From 0514fd36e4e63690cb5d41ce139567eae1ef681a Mon Sep 17 00:00:00 2001 From: NeverSightAI Date: Sun, 2 Aug 2026 15:37:40 +0800 Subject: [PATCH 1/3] Fix X86 selectAddr crash on non-MemSDNode parents for 32-bit Linux Only read pointer address space when the parent SDNode is a MemSDNode. The addr complex pattern is also used from X86ISD::CALL (e.g. i686 ELF PIC calls), and casting those nodes to MemSDNode caused ISel to crash. Closes #176 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 14 ++------------ llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index fb0c778e4190..f7af1f365a6f 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2990,18 +2990,8 @@ bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Disp, SDValue &Segment) { X86ISelAddressMode AM; - if (Parent && - // This list of opcodes are all the nodes that have an "addr:$ptr" operand - // that are not a MemSDNode, and thus don't have proper addrspace info. - Parent->getOpcode() != ISD::INTRINSIC_W_CHAIN && // unaligned loads, fixme - Parent->getOpcode() != ISD::INTRINSIC_VOID && // nontemporal stores - Parent->getOpcode() != X86ISD::TLSCALL && // Fixme - Parent->getOpcode() != X86ISD::ENQCMD && // Fixme - Parent->getOpcode() != X86ISD::ENQCMDS && // Fixme - Parent->getOpcode() != X86ISD::EH_SJLJ_SETJMP && // setjmp - Parent->getOpcode() != X86ISD::EH_SJLJ_LONGJMP) { // longjmp - unsigned AddrSpace = - cast(Parent)->getPointerInfo().getAddrSpace(); + if (auto *MemParent = dyn_cast(Parent)) { + unsigned AddrSpace = MemParent->getPointerInfo().getAddrSpace(); if (AddrSpace == X86AS::GS) AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16); if (AddrSpace == X86AS::FS) diff --git a/llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll b/llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll new file mode 100644 index 000000000000..431692cf191a --- /dev/null +++ b/llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s +; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -relocation-model=pic | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic | FileCheck %s + +declare void @abort() nounwind + +define void @f() local_unnamed_addr { +entry: + tail call void @abort() nounwind + unreachable +} + +; CHECK-LABEL: f: +; CHECK: calll From 95c3e7090f06bfe96e0906d71344d9a3e8708537 Mon Sep 17 00:00:00 2001 From: NeverSightAI Date: Sun, 2 Aug 2026 23:15:04 +0800 Subject: [PATCH 2/3] Use dyn_cast_if_present in selectAddr for null Parent Parent may be null for inline asm addr matching; dyn_cast asserts on null in debug builds. dyn_cast_if_present matches the API contract. --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index f7af1f365a6f..f9680ff8b3a7 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2990,7 +2990,7 @@ bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Disp, SDValue &Segment) { X86ISelAddressMode AM; - if (auto *MemParent = dyn_cast(Parent)) { + if (auto *MemParent = dyn_cast_if_present(Parent)) { unsigned AddrSpace = MemParent->getPointerInfo().getAddrSpace(); if (AddrSpace == X86AS::GS) AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16); From 26f9673bac3940c90b6ca5d072c27f842c1ba99f Mon Sep 17 00:00:00 2001 From: NeverSightAI Date: Sun, 2 Aug 2026 23:17:06 +0800 Subject: [PATCH 3/3] Add issue #176 regression CI using PR build artifacts Run clang++/llc checks on Windows and Linux install prefixes downloaded from the windows-llvm-msvc-build and android-llvm-msvc-build artifacts. --- .github/workflows/issue176-regression.yml | 232 ++++++++++++++++++ .github/workflows/scripts/verify-issue176.ps1 | 66 +++++ .github/workflows/scripts/verify-issue176.sh | 56 +++++ 3 files changed, 354 insertions(+) create mode 100644 .github/workflows/issue176-regression.yml create mode 100644 .github/workflows/scripts/verify-issue176.ps1 create mode 100755 .github/workflows/scripts/verify-issue176.sh diff --git a/.github/workflows/issue176-regression.yml b/.github/workflows/issue176-regression.yml new file mode 100644 index 000000000000..5852f5cdfd77 --- /dev/null +++ b/.github/workflows/issue176-regression.yml @@ -0,0 +1,232 @@ +name: issue176-regression + +permissions: + actions: read + contents: read + +on: + workflow_run: + workflows: + - windows-llvm-msvc-build + - android-llvm-msvc-build + types: [completed] + workflow_dispatch: + inputs: + commit: + description: 'Commit SHA to test (defaults to the triggering ref)' + required: false + platform: + description: 'Which platform artifacts to test' + type: choice + options: + - all + - windows + - linux + default: all + +concurrency: + group: issue176-regression-${{ github.event.workflow_run.head_sha || github.sha }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + plan: + if: > + github.event_name == 'workflow_dispatch' || + (github.event_name == 'workflow_run' && + github.event.workflow_run.conclusion == 'success') + runs-on: ubuntu-latest + outputs: + commit: ${{ steps.plan.outputs.commit }} + run_windows: ${{ steps.plan.outputs.run_windows }} + run_linux: ${{ steps.plan.outputs.run_linux }} + windows_run_id: ${{ steps.plan.outputs.windows_run_id }} + linux_run_id: ${{ steps.plan.outputs.linux_run_id }} + steps: + - name: Plan verification jobs + id: plan + env: + EVENT_NAME: ${{ github.event_name }} + WORKFLOW_NAME: ${{ github.event.workflow_run.name || '' }} + WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id || '' }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha || github.sha }} + INPUT_COMMIT: ${{ github.event.inputs.commit || '' }} + INPUT_PLATFORM: ${{ github.event.inputs.platform || 'all' }} + run: | + set -euo pipefail + + commit="$HEAD_SHA" + if [ "$EVENT_NAME" = "workflow_dispatch" ] && [ -n "$INPUT_COMMIT" ]; then + commit="$INPUT_COMMIT" + fi + + run_windows=false + run_linux=false + windows_run_id= + linux_run_id= + + if [ "$EVENT_NAME" = "workflow_run" ]; then + case "$WORKFLOW_NAME" in + windows-llvm-msvc-build) + run_windows=true + windows_run_id="$WORKFLOW_RUN_ID" + ;; + android-llvm-msvc-build) + run_linux=true + linux_run_id="$WORKFLOW_RUN_ID" + ;; + esac + else + case "$INPUT_PLATFORM" in + all) + run_windows=true + run_linux=true + ;; + windows) run_windows=true ;; + linux) run_linux=true ;; + esac + fi + + { + echo "commit=$commit" + echo "run_windows=$run_windows" + echo "run_linux=$run_linux" + echo "windows_run_id=$windows_run_id" + echo "linux_run_id=$linux_run_id" + } >> "$GITHUB_OUTPUT" + + find-windows-run: + needs: plan + if: needs.plan.outputs.run_windows == 'true' + runs-on: ubuntu-latest + outputs: + run_id: ${{ steps.find.outputs.run_id }} + steps: + - name: Resolve Windows build run id + id: find + uses: actions/github-script@v7 + env: + COMMIT: ${{ needs.plan.outputs.commit }} + RUN_ID: ${{ needs.plan.outputs.windows_run_id }} + with: + script: | + if (process.env.RUN_ID) { + core.setOutput('run_id', process.env.RUN_ID); + return; + } + const commit = process.env.COMMIT; + const { data } = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'windows-llvm-msvc-build.yml', + head_sha: commit, + status: 'success', + per_page: 5, + }); + const run = data.workflow_runs.find(r => r.conclusion === 'success'); + if (!run) { + core.setFailed(`No successful windows-llvm-msvc-build run for ${commit}`); + return; + } + core.setOutput('run_id', String(run.id)); + + find-linux-run: + needs: plan + if: needs.plan.outputs.run_linux == 'true' + runs-on: ubuntu-latest + outputs: + run_id: ${{ steps.find.outputs.run_id }} + steps: + - name: Resolve Linux build run id + id: find + uses: actions/github-script@v7 + env: + COMMIT: ${{ needs.plan.outputs.commit }} + RUN_ID: ${{ needs.plan.outputs.linux_run_id }} + with: + script: | + if (process.env.RUN_ID) { + core.setOutput('run_id', process.env.RUN_ID); + return; + } + const commit = process.env.COMMIT; + const { data } = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'android-llvm-msvc-build.yml', + head_sha: commit, + status: 'success', + per_page: 5, + }); + const run = data.workflow_runs.find(r => r.conclusion === 'success'); + if (!run) { + core.setFailed(`No successful android-llvm-msvc-build run for ${commit}`); + return; + } + core.setOutput('run_id', String(run.id)); + + test-windows: + needs: [plan, find-windows-run] + if: needs.plan.outputs.run_windows == 'true' + runs-on: windows-2022 + steps: + - name: Checkout test inputs + uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.commit }} + + - name: Download Windows PR build artifact + uses: actions/download-artifact@v4 + with: + name: windows-llvm-msvc + run-id: ${{ needs.find-windows-run.outputs.run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + path: artifacts/windows + + - name: Extract install prefix + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + Set-Location artifacts/windows + $first = Get-ChildItem -Filter 'windows-llvm-msvc.zip.*' | Sort-Object Name | Select-Object -First 1 + if (-not $first) { throw 'windows-llvm-msvc zip parts not found' } + 7z x $first.Name + + - name: Verify issue #176 on Windows binary + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + & .github/workflows/scripts/verify-issue176.ps1 ` + -InstallPrefix "$PWD/artifacts/windows/install" ` + -RepoRoot "$PWD" + + test-linux: + needs: [plan, find-linux-run] + if: needs.plan.outputs.run_linux == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout test inputs + uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.commit }} + + - name: Install 7z + run: sudo apt-get update && sudo apt-get install -y p7zip-full + + - name: Download Linux PR build artifact + uses: actions/download-artifact@v4 + with: + name: android-llvm-msvc + run-id: ${{ needs.find-linux-run.outputs.run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + path: artifacts/linux + + - name: Extract install prefix + run: | + set -euo pipefail + cd artifacts/linux + 7z x android-llvm-msvc.zip + + - name: Verify issue #176 on Linux binary + run: | + chmod +x .github/workflows/scripts/verify-issue176.sh + .github/workflows/scripts/verify-issue176.sh "$PWD/artifacts/linux/install" "$PWD" diff --git a/.github/workflows/scripts/verify-issue176.ps1 b/.github/workflows/scripts/verify-issue176.ps1 new file mode 100644 index 000000000000..99d839471bdc --- /dev/null +++ b/.github/workflows/scripts/verify-issue176.ps1 @@ -0,0 +1,66 @@ +# Regression checks for llvm-msvc issue #176 (32-bit Linux ISel crash). +param( + [Parameter(Mandatory = $true)][string]$InstallPrefix, + [Parameter(Mandatory = $true)][string]$RepoRoot +) + +$ErrorActionPreference = 'Stop' + +$Bin = Join-Path $InstallPrefix 'bin' +$Clang = Join-Path $Bin 'clang++.exe' +$Llc = Join-Path $Bin 'llc.exe' +$TestLl = Join-Path $RepoRoot 'llvm\test\CodeGen\X86\issue176-abort-i686-linux.ll' + +foreach ($tool in @($Clang, $Llc)) { + if (-not (Test-Path $tool)) { + throw "Missing tool: $tool" + } +} + +if (-not (Test-Path $TestLl)) { + throw "Missing test IR: $TestLl" +} + +$Tmp = Join-Path $env:RUNNER_TEMP "issue176-$PID" +New-Item -ItemType Directory -Path $Tmp -Force | Out-Null + +function Run([scriptblock]$Block, [string]$Label) { + Write-Host ">>> $Label" + & $Block + if ($LASTEXITCODE -ne 0) { + throw "Command failed: $Label (exit $LASTEXITCODE)" + } +} + +Run { & $Clang --version } 'clang++ --version' +Run { & $Llc --version } 'llc --version' + +$Cpp = Join-Path $Tmp 'issue176.cpp' +$Obj = Join-Path $Tmp 'issue176.o' +Set-Content -Path $Cpp -Value 'void f() { __builtin_abort(); }' -NoNewline + +Run { + & $Clang --target=i686-pc-linux-gnu -O1 -c $Cpp -o $Obj +} 'clang++ i686-linux __builtin_abort @ -O1' + +if (-not (Test-Path $Obj) -or (Get-Item $Obj).Length -eq 0) { + throw "Object file was not produced: $Obj" +} + +$Triples = @( + 'i686-pc-linux-gnu', + 'i686-unknown-linux-gnu', + 'i686-linux-android' +) + +foreach ($Triple in $Triples) { + $Asm = Join-Path $Tmp ("issue176-" + ($Triple -replace '[^a-zA-Z0-9]', '_') + '.s') + Run { + Get-Content -Raw $TestLl | & $Llc -mtriple=$Triple -relocation-model=pic -o $Asm + "llc $Triple" + if (-not (Select-String -Path $Asm -Pattern 'calll' -Quiet)) { + throw "Expected calll in assembly for $Triple" + } +} + +Write-Host 'issue #176 regression checks passed' diff --git a/.github/workflows/scripts/verify-issue176.sh b/.github/workflows/scripts/verify-issue176.sh new file mode 100755 index 000000000000..a58a2ca1b7d1 --- /dev/null +++ b/.github/workflows/scripts/verify-issue176.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Regression checks for llvm-msvc issue #176 (32-bit Linux ISel crash). +set -euo pipefail + +INSTALL="${1:?usage: $0 /path/to/install/prefix}" +REPO="${2:-.}" + +BIN="$INSTALL/bin" +export PATH="$BIN:$PATH" + +CLANG="$BIN/clang++" +LLC="$BIN/llc" + +if [[ ! -x "$CLANG" ]]; then + echo "clang++ not found under $BIN" >&2 + exit 1 +fi +if [[ ! -x "$LLC" ]]; then + echo "llc not found under $BIN" >&2 + exit 1 +fi + +TEST_LL="$REPO/llvm/test/CodeGen/X86/issue176-abort-i686-linux.ll" +if [[ ! -f "$TEST_LL" ]]; then + echo "missing test IR: $TEST_LL" >&2 + exit 1 +fi + +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT + +run() { + echo ">>> $*" + "$@" +} + +echo "=== toolchain ===" +run "$CLANG" --version +run "$LLC" --version + +echo "=== clang: i686-linux __builtin_abort @ -O1 ===" +cat >"$TMP/issue176.cpp" <<'EOF' +void f() { __builtin_abort(); } +EOF +run "$CLANG" --target=i686-pc-linux-gnu -O1 -c "$TMP/issue176.cpp" -o "$TMP/issue176.o" +test -s "$TMP/issue176.o" + +echo "=== llc: issue176-abort-i686-linux.ll (3 triples) ===" +for triple in i686-pc-linux-gnu i686-unknown-linux-gnu i686-linux-android; do + echo "--- $triple ---" + OUT="$TMP/issue176-${triple//[^a-zA-Z0-9]/_}.s" + run "$LLC" <"$TEST_LL" -mtriple="$triple" -relocation-model=pic -o "$OUT" + grep -q calll "$OUT" +done + +echo "issue #176 regression checks passed"