From ef258e180673f4ac91e90d0bea45a8a3f201333a Mon Sep 17 00:00:00 2001 From: AZero13 Date: Sat, 15 Nov 2025 14:06:38 -0500 Subject: [PATCH 1/2] Pre-commit test (NFC) --- .../AArch64/loop-dependence-mask-ccmp.ll | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll diff --git a/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll b/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll new file mode 100644 index 0000000000000..4c5619c57fa17 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=aarch64 -mattr=+sve2 -verify-machineinstrs -stop-after=finalize-isel %s -o - | FileCheck %s + +; Regression test for a bug where getTargetConstant(0) was used instead of +; getConstant(0) in ScalarizeVecRes_LOOP_DEPENDENCE_MASK, causing instruction +; selection to incorrectly generate CCMPXr (register form) with an immediate +; operand instead of CCMPXi (immediate form). +; + +define <1 x i1> @test_war_mask_ccmp(ptr %a, ptr %b) { + ; CHECK-LABEL: name: test_war_mask_ccmp + ; CHECK: bb.0.entry: + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr [[COPY]], [[COPY1]], implicit-def dead $nzcv + ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBSXrr]], 0, 0, implicit-def $nzcv + ; CHECK-NEXT: CCMPXr [[SUBSXrr]], 0, 4, 13, implicit-def $nzcv, implicit $nzcv + ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] + ; CHECK-NEXT: RET_ReallyLR implicit $w0 +entry: + %0 = call <1 x i1> @llvm.loop.dependence.war.mask.v1i1(ptr %a, ptr %b, i64 1) + ret <1 x i1> %0 +} + +define <1 x i1> @test_raw_mask_ccmp(ptr %a, ptr %b) { + ; CHECK-LABEL: name: test_raw_mask_ccmp + ; CHECK: bb.0.entry: + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr [[COPY]], [[COPY1]], implicit-def dead $nzcv + ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBSXrr]], 0, 0, implicit-def $nzcv + ; CHECK-NEXT: CCMPXr [[SUBSXrr]], 0, 4, 13, implicit-def $nzcv, implicit $nzcv + ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] + ; CHECK-NEXT: RET_ReallyLR implicit $w0 +entry: + %0 = call <1 x i1> @llvm.loop.dependence.raw.mask.v1i1(ptr %a, ptr %b, i64 1) + ret <1 x i1> %0 +} + +declare <1 x i1> @llvm.loop.dependence.war.mask.v1i1(ptr, ptr, i64) +declare <1 x i1> @llvm.loop.dependence.raw.mask.v1i1(ptr, ptr, i64) From bf6ae88e66447c2758bc8ade438128143d149c2e Mon Sep 17 00:00:00 2001 From: AZero13 Date: Sat, 15 Nov 2025 15:20:38 -0500 Subject: [PATCH 2/2] [SelectionDAG] Fix AArch64 machine verifier bug when expanding LOOP_DEPENDENCE_MASK Fixes: #168227 TargetConstant nodes don't match TableGen ImmLeaf patterns during instruction selection. When this zero constant flows into the AArch64 CCMP formation code, the machine verifier hits an assertion in expensive checks. --- llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 2 +- llvm/test/CodeGen/AArch64/alias_mask.ll | 10 ++++------ llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll | 10 ++++------ 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 7d979caa8bf82..e8d9bce43f6ea 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -1829,7 +1829,7 @@ SDValue VectorLegalizer::ExpandLOOP_DEPENDENCE_MASK(SDNode *N) { // If the difference is positive then some elements may alias EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), Diff.getValueType()); - SDValue Zero = DAG.getTargetConstant(0, DL, PtrVT); + SDValue Zero = DAG.getConstant(0, DL, PtrVT); SDValue Cmp = DAG.getSetCC(DL, CmpVT, Diff, Zero, IsReadAfterWrite ? ISD::SETEQ : ISD::SETLE); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 417122d467054..71eeee78bd868 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -413,7 +413,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(SDNode *N) { SDValue Diff = DAG.getNode(ISD::SUB, DL, PtrVT, SinkValue, SourceValue); EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), Diff.getValueType()); - SDValue Zero = DAG.getTargetConstant(0, DL, PtrVT); + SDValue Zero = DAG.getConstant(0, DL, PtrVT); return DAG.getNode(ISD::OR, DL, CmpVT, DAG.getSetCC(DL, CmpVT, Diff, EltSize, ISD::SETGE), DAG.getSetCC(DL, CmpVT, Diff, Zero, ISD::SETEQ)); diff --git a/llvm/test/CodeGen/AArch64/alias_mask.ll b/llvm/test/CodeGen/AArch64/alias_mask.ll index c5d3677366480..fdd0a6a4709da 100644 --- a/llvm/test/CodeGen/AArch64/alias_mask.ll +++ b/llvm/test/CodeGen/AArch64/alias_mask.ll @@ -793,9 +793,8 @@ define <1 x i1> @whilewr_8_scalarize(ptr %a, ptr %b) { ; CHECK-LABEL: whilewr_8_scalarize: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: sub x8, x1, x0 -; CHECK-NEXT: cmp x8, #0 -; CHECK-NEXT: ccmp x8, #0, #4, le -; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: cmn x8, #1 +; CHECK-NEXT: cset w0, gt ; CHECK-NEXT: ret entry: %0 = call <1 x i1> @llvm.loop.dependence.war.mask.v1i1(ptr %a, ptr %b, i64 1) @@ -845,9 +844,8 @@ define <1 x i1> @whilerw_8_scalarize(ptr %a, ptr %b) { ; CHECK-LABEL: whilerw_8_scalarize: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: sub x8, x1, x0 -; CHECK-NEXT: cmp x8, #0 -; CHECK-NEXT: ccmp x8, #0, #4, le -; CHECK-NEXT: cset w0, eq +; CHECK-NEXT: cmn x8, #1 +; CHECK-NEXT: cset w0, gt ; CHECK-NEXT: ret entry: %0 = call <1 x i1> @llvm.loop.dependence.raw.mask.v1i1(ptr %a, ptr %b, i64 1) diff --git a/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll b/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll index 4c5619c57fa17..2c5e351ee9ba7 100644 --- a/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll +++ b/llvm/test/CodeGen/AArch64/loop-dependence-mask-ccmp.ll @@ -15,9 +15,8 @@ define <1 x i1> @test_war_mask_ccmp(ptr %a, ptr %b) { ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr [[COPY]], [[COPY1]], implicit-def dead $nzcv - ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBSXrr]], 0, 0, implicit-def $nzcv - ; CHECK-NEXT: CCMPXr [[SUBSXrr]], 0, 4, 13, implicit-def $nzcv, implicit $nzcv - ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK-NEXT: [[ADDSXri:%[0-9]+]]:gpr64 = ADDSXri killed [[SUBSXrr]], 1, 0, implicit-def $nzcv + ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 entry: @@ -33,9 +32,8 @@ define <1 x i1> @test_raw_mask_ccmp(ptr %a, ptr %b) { ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr [[COPY]], [[COPY1]], implicit-def dead $nzcv - ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBSXrr]], 0, 0, implicit-def $nzcv - ; CHECK-NEXT: CCMPXr [[SUBSXrr]], 0, 4, 13, implicit-def $nzcv, implicit $nzcv - ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv + ; CHECK-NEXT: [[ADDSXri:%[0-9]+]]:gpr64 = ADDSXri killed [[SUBSXrr]], 1, 0, implicit-def $nzcv + ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 entry: