[llvm] [SDAG] Specify unsigned compares for loop.dependance.{war|raw} masks (PR #197437)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 13 06:22:59 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Benjamin Maxwell (MacDue)

<details>
<summary>Changes</summary>

Previously, the LangRef was ambiguous about the sign of comparisons used to create the loop dependence masks. This resulted in the expansion not following the intended semantics for extreme inputs.

For example, %ptrA = 0, %ptrB = UINT_MAX, should result in a (RAW) mask with all lanes active. However, previously we'd do ``(%elementSize * lane) < abs(%ptrB - %ptrA)``, which due to incorrectly using signed arithmetic would result in a mask with a single lane active as ``abs(%ptrB - %ptrA)`` resulted in 1, not `UINT_MAX`. In other words, ``abs(%ptrB - %ptrA)`` should be ``unsigned-absolute-difference(%ptrA, %ptrB)``.

Follow up to #<!-- -->188248. 

---

Patch is 20.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/197437.diff


6 Files Affected:

- (modified) llvm/docs/LangRef.rst (+19-15) 
- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (+5-26) 
- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+23-9) 
- (modified) llvm/test/CodeGen/AArch64/alias_mask.ll (+25-30) 
- (modified) llvm/test/CodeGen/AArch64/alias_mask_scalable.ll (+24-29) 
- (modified) llvm/test/CodeGen/AArch64/alias_mask_scalable_nosve2.ll (+15-3) 


``````````diff
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index ed20a25cf06c8..fa695db4193a0 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -25312,15 +25312,17 @@ Semantics:
 
 ``%elementSize`` is the size of the accessed elements in bytes.
 The intrinsic returns ``poison`` if the distance between ``%addrA`` and ``%addrB``
-is smaller than ``VF * %elementsize`` and either ``%addrA + VF * %elementSize``
-or ``%addrB + VF * %elementSize`` wrap.
+is not a multiple of ``%elementsize``.
 
-The element of the result mask is active when loading from %addrA then storing to
-%addrB is safe and doesn't result in a write-after-read hazard, meaning that:
+Each lane of the mask ``%m[i]`` is defined as the ``or`` of:
 
-* (addrB - addrA) <= 0 (guarantees that all lanes are loaded before any stores), or
-* elementSize * lane < (addrB - addrA) (guarantees that this lane is loaded
-  before the store to the same address)
+* ``icmp uge %addrA, %addrB``
+  * (guarantees that all lanes are loaded before any stores)
+* ``icmp ult (%elementSize * i), (%addrB - %addrA)``
+  * (guarantees that this lane is loaded before the store to the same address)
+
+where ``%m`` is the vector mask of active/inactive lanes with its elements
+indexed by ``i``.
 
 Examples:
 """""""""
@@ -25406,16 +25408,18 @@ Semantics:
 
 ``%elementSize`` is the size of the accessed elements in bytes.
 The intrinsic returns ``poison`` if the distance between ``%addrA`` and ``%addrB``
-is smaller than ``VF * %elementsize`` and either ``%addrA + VF * %elementSize``
-or ``%addrB + VF * %elementSize`` wrap.
+is not a multiple of ``%elementsize``.
+
+Each lane of the mask ``%m[i]`` is defined as the ``or`` of:
 
-The element of the result mask is active when storing to %addrA then loading from
-%addrB is safe and doesn't result in aliasing, meaning that:
+* ``icmp eq %addrA, %addrB``
+  * (doesn't introduce any new hazards that weren't in the scalar code)
+* ``icmp ult (%elementSize * i), uabs(%addrA,  %addrB)``
+  * (guarantees that this lane is loaded before the store to the same address)
 
-* elementSize * lane < abs(addrB - addrA) (guarantees that the store of this lane
-  occurs before loading from this address), or
-* addrA == addrB (doesn't introduce any new hazards that weren't in the scalar
-  code)
+where ``%m`` is the vector mask of active/inactive lanes with its elements
+indexed by ``i`` and ``uabs`` is the unsigned absolute difference between
+``%addrA`` and ``%addrB``.
 
 Examples:
 """""""""
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 81e9e301f2572..82fce9a6cf8c4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -442,32 +442,11 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N,
 
 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(SDNode *N) {
   SDLoc DL(N);
-  SDValue SourceValue = N->getOperand(0);
-  SDValue SinkValue = N->getOperand(1);
-  SDValue EltSizeInBytes = N->getOperand(2);
-  SDValue LaneOffset = N->getOperand(3);
-
-  EVT PtrVT = SourceValue->getValueType(0);
-  bool IsReadAfterWrite = N->getOpcode() == ISD::LOOP_DEPENDENCE_RAW_MASK;
-
-  // Take the difference between the pointers and divided by the element size,
-  // to see how many lanes separate them.
-  SDValue Diff = DAG.getNode(ISD::SUB, DL, PtrVT, SinkValue, SourceValue);
-  if (IsReadAfterWrite)
-    Diff = DAG.getNode(ISD::ABS, DL, PtrVT, Diff);
-  Diff = DAG.getNode(ISD::SDIV, DL, PtrVT, Diff, EltSizeInBytes);
-
-  // The pointers do not alias if:
-  //  * Diff <= 0 || LaneOffset < Diff (WAR_MASK)
-  //  * Diff == 0 || LaneOffset < abs(Diff) (RAW_MASK)
-  // Note: If LaneOffset is zero, both cases will fold to "true".
-  EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
-                                     Diff.getValueType());
-  SDValue Zero = DAG.getConstant(0, DL, PtrVT);
-  SDValue Cmp = DAG.getSetCC(DL, CmpVT, Diff, Zero,
-                             IsReadAfterWrite ? ISD::SETEQ : ISD::SETLE);
-  return DAG.getNode(ISD::OR, DL, CmpVT, Cmp,
-                     DAG.getSetCC(DL, CmpVT, LaneOffset, Diff, ISD::SETULT));
+  // Reuse the expansion (which should scalarize).
+  SDValue Mask = TLI.expandLoopDependenceMask(N, DAG);
+  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
+                     N->getValueType(0).getScalarType(), Mask,
+                     DAG.getVectorIdxConstant(0, DL));
 }
 
 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index ce1493200b9b1..bb26409c5d5fb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -10591,30 +10591,44 @@ SDValue TargetLowering::expandLoopDependenceMask(SDNode *N,
   ElementCount LaneOffsetEC =
       ElementCount::get(N->getConstantOperandVal(3), VT.isScalableVT());
 
+  // The first lane is always active, so v1i1 => true.
+  if (LaneOffsetEC.isZero() &&
+      VT.getVectorElementCount() == ElementCount::getFixed(1))
+    return DAG.getBoolConstant(true, DL, VT, VT);
+
   EVT AddrVT = SourceValue->getValueType(0);
   bool IsReadAfterWrite = N->getOpcode() == ISD::LOOP_DEPENDENCE_RAW_MASK;
 
+  EVT CmpVT =
+      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), AddrVT);
+
+  // Unsigned compare: Source >= Sink.
+  SDValue SourceAheadOfOrEqualToSink =
+      DAG.getSetCC(DL, CmpVT, SourceValue, SinkValue, ISD::SETUGE);
+
   // Take the difference between the pointers and divided by the element size,
   // to see how many lanes separate them.
   SDValue Diff = DAG.getNode(ISD::SUB, DL, AddrVT, SinkValue, SourceValue);
+
+  // RAW_MASK: Diff = Source >= Sink ? (Source - Sink) : (Sink - Source)
   if (IsReadAfterWrite)
-    Diff = DAG.getNode(ISD::ABS, DL, AddrVT, Diff);
+    Diff = DAG.getSelect(DL, AddrVT, SourceAheadOfOrEqualToSink,
+                         DAG.getNegative(Diff, DL, AddrVT), Diff);
+
   Diff = DAG.getNode(ISD::SDIV, DL, AddrVT, Diff, EltSizeInBytes);
 
   // The pointers do not alias if:
-  //  * Diff <= 0 (WAR_MASK)
-  //  * Diff == 0 (RAW_MASK)
-  EVT CmpVT =
-      getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), AddrVT);
-  SDValue Zero = DAG.getConstant(0, DL, AddrVT);
-  SDValue Cmp = DAG.getSetCC(DL, CmpVT, Diff, Zero,
-                             IsReadAfterWrite ? ISD::SETEQ : ISD::SETLE);
+  // - Source >= Sink (WAR_MASK)
+  // - Source == Sink (RAW_MASK)
+  SDValue NoAlias = SourceAheadOfOrEqualToSink;
+  if (IsReadAfterWrite)
+    NoAlias = DAG.getSetCC(DL, CmpVT, SourceValue, SinkValue, ISD::SETEQ);
 
   // The pointers do not alias if:
   // Lane + LaneOffset < Diff (WAR/RAW_MASK)
   SDValue LaneOffset = DAG.getElementCount(DL, AddrVT, LaneOffsetEC);
   SDValue MaskN = DAG.getSelect(
-      DL, AddrVT, Cmp,
+      DL, AddrVT, NoAlias,
       DAG.getConstant(APInt::getMaxValue(AddrVT.getScalarSizeInBits()), DL,
                       AddrVT),
       Diff);
diff --git a/llvm/test/CodeGen/AArch64/alias_mask.ll b/llvm/test/CodeGen/AArch64/alias_mask.ll
index d3e6513c83cd6..4b94fe3b70c28 100644
--- a/llvm/test/CodeGen/AArch64/alias_mask.ll
+++ b/llvm/test/CodeGen/AArch64/alias_mask.ll
@@ -100,10 +100,9 @@ entry:
 define <32 x i1> @whilewr_8_split(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_8_split:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    mov w10, #16 // =0x10
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilewr p0.b, x0, x1
 ; CHECK-NEXT:    whilelo p1.b, x10, x9
 ; CHECK-NEXT:    adrp x9, .LCPI8_0
@@ -129,13 +128,12 @@ entry:
 define <64 x i1> @whilewr_8_split2(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_8_split2:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    mov w10, #48 // =0x30
 ; CHECK-NEXT:    mov w11, #16 // =0x10
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    mov w12, #32 // =0x20
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilewr p0.b, x0, x1
+; CHECK-NEXT:    mov w12, #32 // =0x20
 ; CHECK-NEXT:    whilelo p1.b, x10, x9
 ; CHECK-NEXT:    adrp x10, .LCPI9_0
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
@@ -174,11 +172,10 @@ entry:
 define <16 x i1> @whilewr_16_expand(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_16_expand:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x8, x1, x0
+; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x8, x8, x8, lsr #63
 ; CHECK-NEXT:    asr x8, x8, #1
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
@@ -191,12 +188,11 @@ entry:
 define <32 x i1> @whilewr_16_expand2(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_16_expand2:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    mov w10, #16 // =0x10
 ; CHECK-NEXT:    add x9, x9, x9, lsr #63
 ; CHECK-NEXT:    asr x9, x9, #1
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, x10, x9
 ; CHECK-NEXT:    whilelo p1.b, xzr, x9
 ; CHECK-NEXT:    adrp x9, .LCPI11_0
@@ -225,9 +221,9 @@ define <8 x i1> @whilewr_32_expand(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #3
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #2
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
@@ -243,9 +239,9 @@ define <16 x i1> @whilewr_32_expand2(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #3
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #2
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
@@ -261,10 +257,10 @@ define <32 x i1> @whilewr_32_expand3(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    add x10, x9, #3
 ; CHECK-NEXT:    csel x9, x10, x9, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    mov w10, #16 // =0x10
 ; CHECK-NEXT:    asr x9, x9, #2
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, x10, x9
 ; CHECK-NEXT:    whilelo p1.b, xzr, x9
 ; CHECK-NEXT:    adrp x9, .LCPI14_0
@@ -293,9 +289,9 @@ define <4 x i1> @whilewr_64_expand(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.h, xzr, x8
 ; CHECK-NEXT:    mov z0.h, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
@@ -311,9 +307,9 @@ define <8 x i1> @whilewr_64_expand2(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
@@ -329,9 +325,9 @@ define <16 x i1> @whilewr_64_expand3(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
@@ -347,10 +343,10 @@ define <32 x i1> @whilewr_64_expand4(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    add x10, x9, #7
 ; CHECK-NEXT:    csel x9, x10, x9, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    mov w10, #16 // =0x10
 ; CHECK-NEXT:    asr x9, x9, #3
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, x10, x9
 ; CHECK-NEXT:    whilelo p1.b, xzr, x9
 ; CHECK-NEXT:    adrp x9, .LCPI18_0
@@ -443,12 +439,11 @@ define <16 x i1> @whilewr_badimm(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_badimm:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    mov x8, #6148914691236517205 // =0x5555555555555555
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    movk x8, #21846
 ; CHECK-NEXT:    smulh x8, x9, x8
 ; CHECK-NEXT:    add x8, x8, x8, lsr #63
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    mov z0.b, p0/z, #-1 // =0xffffffffffffffff
 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
diff --git a/llvm/test/CodeGen/AArch64/alias_mask_scalable.ll b/llvm/test/CodeGen/AArch64/alias_mask_scalable.ll
index def691db9cd8a..8449e081664cc 100644
--- a/llvm/test/CodeGen/AArch64/alias_mask_scalable.ll
+++ b/llvm/test/CodeGen/AArch64/alias_mask_scalable.ll
@@ -84,10 +84,9 @@ entry:
 define <vscale x 32 x i1> @whilewr_8_split(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_8_split:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    rdvl x8, #1
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilewr p0.b, x0, x1
 ; CHECK-NEXT:    whilelo p1.b, x8, x9
 ; CHECK-NEXT:    ret
@@ -99,11 +98,10 @@ entry:
 define <vscale x 64 x i1> @whilewr_8_split2(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_8_split2:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    rdvl x8, #1
 ; CHECK-NEXT:    rdvl x10, #2
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilewr p0.b, x0, x1
 ; CHECK-NEXT:    whilelo p1.b, x8, x9
 ; CHECK-NEXT:    rdvl x8, #3
@@ -118,11 +116,10 @@ entry:
 define <vscale x 16 x i1> @whilewr_16_expand(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_16_expand:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x8, x1, x0
+; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x8, x8, x8, lsr #63
 ; CHECK-NEXT:    asr x8, x8, #1
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -133,12 +130,11 @@ entry:
 define <vscale x 32 x i1> @whilewr_16_expand2(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_16_expand2:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    rdvl x8, #1
 ; CHECK-NEXT:    add x9, x9, x9, lsr #63
 ; CHECK-NEXT:    asr x9, x9, #1
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x9
 ; CHECK-NEXT:    whilelo p1.b, x8, x9
 ; CHECK-NEXT:    ret
@@ -153,9 +149,9 @@ define <vscale x 8 x i1> @whilewr_32_expand(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #3
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #2
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.h, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -169,9 +165,9 @@ define <vscale x 16 x i1> @whilewr_32_expand2(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #3
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #2
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -186,9 +182,9 @@ define <vscale x 32 x i1> @whilewr_32_expand3(i64 %a, i64 %b) {
 ; CHECK-NEXT:    rdvl x8, #1
 ; CHECK-NEXT:    add x10, x9, #3
 ; CHECK-NEXT:    csel x9, x10, x9, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x9, x9, #2
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x9
 ; CHECK-NEXT:    whilelo p1.b, x8, x9
 ; CHECK-NEXT:    ret
@@ -203,9 +199,9 @@ define <vscale x 4 x i1> @whilewr_64_expand(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.s, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -219,9 +215,9 @@ define <vscale x 8 x i1> @whilewr_64_expand2(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.h, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -235,9 +231,9 @@ define <vscale x 16 x i1> @whilewr_64_expand3(i64 %a, i64 %b) {
 ; CHECK-NEXT:    subs x8, x1, x0
 ; CHECK-NEXT:    add x9, x8, #7
 ; CHECK-NEXT:    csel x8, x9, x8, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x8, x8, #3
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -252,9 +248,9 @@ define <vscale x 32 x i1> @whilewr_64_expand4(i64 %a, i64 %b) {
 ; CHECK-NEXT:    rdvl x8, #1
 ; CHECK-NEXT:    add x10, x9, #7
 ; CHECK-NEXT:    csel x9, x10, x9, mi
+; CHECK-NEXT:    cmp x1, x0
 ; CHECK-NEXT:    asr x9, x9, #3
-; CHECK-NEXT:    cmp x9, #1
-; CHECK-NEXT:    csinv x9, x9, xzr, ge
+; CHECK-NEXT:    csinv x9, x9, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x9
 ; CHECK-NEXT:    whilelo p1.b, x8, x9
 ; CHECK-NEXT:    ret
@@ -297,12 +293,11 @@ define <vscale x 16 x i1> @whilewr_badimm(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_badimm:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    mov x8, #6148914691236517205 // =0x5555555555555555
-; CHECK-NEXT:    sub x9, x1, x0
+; CHECK-NEXT:    subs x9, x1, x0
 ; CHECK-NEXT:    movk x8, #21846
 ; CHECK-NEXT:    smulh x8, x9, x8
 ; CHECK-NEXT:    add x8, x8, x8, lsr #63
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
diff --git a/llvm/test/CodeGen/AArch64/alias_mask_scalable_nosve2.ll b/llvm/test/CodeGen/AArch64/alias_mask_scalable_nosve2.ll
index 80b72152c5dc3..96a88849d8046 100644
--- a/llvm/test/CodeGen/AArch64/alias_mask_scalable_nosve2.ll
+++ b/llvm/test/CodeGen/AArch64/alias_mask_scalable_nosve2.ll
@@ -4,9 +4,8 @@
 define <vscale x 16 x i1> @whilewr_8(i64 %a, i64 %b) {
 ; CHECK-LABEL: whilewr_8:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    sub x8, x1, x0
-; CHECK-NEXT:    cmp x8, #1
-; CHECK-NEXT:    csinv x8, x8, xzr, ge
+; CHECK-NEXT:    subs x8, x1, x0
+; CHECK-NEXT:    csinv x8, x8, xzr, hi
 ; CHECK-NEXT:    whilelo p0.b, xzr, x8
 ; CHECK-NEXT:    ret
 entry:
@@ -29,3 +2...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/197437


More information about the llvm-commits mailing list