[llvm] [AArch64][GlobalISel] Treat vector select as legal (PR #197111)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 00:57:10 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: David Green (davemgreen)

<details>
<summary>Changes</summary>

AArch64 has a BSP psuedo that lowers to BIF/BIT/BSL and acts like a `or(and(m, x), and(not(m), y))`, to selects between x and y depending on the mask. For whatever reason vector selects have always been expanded to and/or in AArch64, being recombined into a BSP later during selection. This can be a little unreliable, with many places where we do not manage to turn them back. Plus it makes adding selection patterns for selects more difficult.

This change that to treat selects as legal, adding some combines that optime the places where and / or is more beneficial.

Currently includes #<!-- -->200131

---

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


23 Files Affected:

- (modified) llvm/include/llvm/Target/GenericOpcodes.td (+1) 
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+30-1) 
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+28-4) 
- (modified) llvm/lib/Target/AArch64/AArch64Combine.td (+3-1) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+18) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+30-4) 
- (added) llvm/test/CodeGen/AArch64/GlobalISel/combine-select-zero.mir (+73) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max.mir (+28-80) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/legalize-select.mir (+47-111) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll (+12-20) 
- (modified) llvm/test/CodeGen/AArch64/arm64-zip.ll (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/fcmp.ll (+157-170) 
- (modified) llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll (+1-1) 
- (modified) llvm/test/CodeGen/AArch64/icmp.ll (+11-17) 
- (modified) llvm/test/CodeGen/AArch64/neon-anyof-splat.ll (+5-10) 
- (modified) llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll (+13-26) 
- (modified) llvm/test/CodeGen/AArch64/qmovn.ll (+1-1) 
- (modified) llvm/test/CodeGen/AArch64/selectcc-to-shiftand.ll (+18-38) 
- (modified) llvm/test/CodeGen/AArch64/setcc-redundant-cmlt.ll (+2-2) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-phis-no-lane-mask-merging.ll (+10-9) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-divergent-i1-used-outside-loop.ll (+16-14) 
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/divergence-temporal-divergent-i1.ll (+3-3) 
- (modified) llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td (+4-4) 


``````````diff
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 37a185a226b63..2e763f969f10d 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -528,6 +528,7 @@ def G_SELECT : GenericInstruction {
   let OutOperandList = (outs type0:$dst);
   let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
   let hasSideEffects = false;
+  let GISelMatchGenericTypes = 1;
 }
 
 // Generic pointer offset.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 5f8213d9c7ec3..5f43c73f07494 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -533,6 +533,35 @@ def select_constant_cmp: GICombineRule<
   (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
 >;
 
+// select c, 0, x -> and (not c), x
+def select_zero_true: GICombineRule<
+  (defs root:$root),
+  (match (G_SELECT $dst, $c, 0, $x):$root,
+    [{ return MRI.getType(${c}.getReg()) == MRI.getType(${dst}.getReg()) &&
+              VT->computeNumSignBits(${c}.getReg()) == MRI.getType(${dst}.getReg()).getScalarSizeInBits(); }]),
+  (apply (G_XOR $xor, $c, -1),
+         (G_FREEZE $f, $x),
+         (G_AND $dst, $xor, $f))
+>;
+
+// select c, x, 0 -> and c, x
+def select_zero_false: GICombineRule<
+  (defs root:$root),
+  (match (G_SELECT $dst, $c, $x, 0):$root,
+    [{ return MRI.getType(${c}.getReg()) == MRI.getType(${dst}.getReg()) &&
+              VT->computeNumSignBits(${c}.getReg()) == MRI.getType(${dst}.getReg()).getScalarSizeInBits(); }]),
+  (apply (G_FREEZE $f, $x),
+         (G_AND $dst, $c, $f))
+>;
+
+// select (not c), x, y -> select c, y, x
+def select_not: GICombineRule<
+  (defs root:$root),
+  (match (G_XOR $c, $src, -1),
+         (G_SELECT $dst, $c, $x, $y):$root),
+  (apply (G_SELECT $dst, $src, $y, $x))
+>;
+
 // Fold (C op x) -> (x op C)
 // TODO: handle more isCommutable opcodes
 // TODO: handle compares (currently not marked as isCommutable)
@@ -2452,7 +2481,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
     simplify_add_to_sub, hoist_logic_op_with_same_opcode_hands, shifts_too_big,
     reassocs, ptr_add_immed_chain, cmp_combines,
     shl_ashr_to_sext_inreg, neg_and_one_to_sext_inreg, sext_inreg_of_load,
-    width_reduction_combines, select_combines,
+    width_reduction_combines, select_combines, select_zero_false, select_not,
     known_bits_simplifications, trunc_shift,
     not_cmp_fold, opt_brcond_by_inverting_cond,
     const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index a200aa29f95ca..b7c6ddd117e29 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -4522,7 +4522,10 @@ LegalizerHelper::bitcast(MachineInstr &MI, unsigned TypeIdx, LLT CastTy) {
     if (TypeIdx != 0)
       return UnableToLegalize;
 
-    if (MRI.getType(MI.getOperand(1).getReg()).isVector()) {
+    if (MRI.getType(MI.getOperand(1).getReg()).isVector() &&
+        (!CastTy.isVector() ||
+         MRI.getType(MI.getOperand(1).getReg()).getElementCount() !=
+             CastTy.getElementCount())) {
       LLVM_DEBUG(
           dbgs() << "bitcast action not implemented for vector select\n");
       return UnableToLegalize;
@@ -6847,6 +6850,25 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
           DstTy.getElementCount() != MoreTy.getElementCount())
         return UnableToLegalize;
 
+      if (CondTy.getSizeInBits() != 1) {
+        unsigned ScalarExt = MIRBuilder.getBoolExtOp(/*IsVec=*/false, false);
+        unsigned VectorExt = MIRBuilder.getBoolExtOp(/*IsVec=*/true, false);
+        if (ScalarExt != VectorExt) {
+          switch (VectorExt) {
+          case TargetOpcode::G_SEXT:
+            CondReg = MIRBuilder.buildSExtInReg(CondTy, CondReg, 1).getReg(0);
+            break;
+          case TargetOpcode::G_ZEXT:
+            CondReg = MIRBuilder.buildZExtInReg(CondTy, CondReg, 1).getReg(0);
+            break;
+          case TargetOpcode::G_ANYEXT:
+            break;
+          default:
+            llvm_unreachable("Unexpected BooleanContent type");
+          }
+        }
+      }
+
       // This is turning a scalar select of vectors into a vector
       // select. Broadcast the select condition.
       auto ShufSplat = MIRBuilder.buildShuffleSplat(MoreTy, CondReg);
@@ -6856,10 +6878,12 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
       return Legalized;
     }
 
-    if (CondTy.isVector())
-      return UnableToLegalize;
-
     Observer.changingInstr(MI);
+    if (CondTy.isVector()) {
+      assert(DstTy.getElementCount() == CondTy.getElementCount());
+      LLT MoreCondTy = MoreTy.changeElementType(CondTy.getScalarType());
+      moreElementsVectorSrc(MI, MoreCondTy, 1);
+    }
     moreElementsVectorSrc(MI, MoreTy, 2);
     moreElementsVectorSrc(MI, MoreTy, 3);
     moreElementsVectorDst(MI, MoreTy, 0);
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 44b86dac27df2..a9c447336cd5e 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -70,6 +70,7 @@ def simplify_uaddo : GICombineRule<
 
 def AArch64PreLegalizerCombiner: GICombiner<
   "AArch64PreLegalizerCombinerImpl", [all_combines,
+                                      select_zero_true,
                                       combine_shuffle_vector,
                                       icmp_redundant_trunc,
                                       fold_global_offset,
@@ -384,7 +385,8 @@ def AArch64PostLegalizerCombiner
                         mul_const, redundant_sext_inreg,
                         form_bitfield_extract, rotate_out_of_range,
                         icmp_to_true_false_known_bits, overflow_combines,
-                        select_combines, fold_merge_to_zext, merge_combines,
+                        select_combines, select_zero_true, select_zero_false, select_not,
+                        fold_merge_to_zext, merge_combines,
                         constant_fold_binops, identity_combines,
                         ptr_add_immed_chain, overlapping_and,
                         split_store_zero_128, undef_combines,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 9db82fa86348e..c8b6944a4f53c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6260,6 +6260,24 @@ def : Pat<(AArch64bsp (v4i32 V128:$Rd), V128:$Rn, V128:$Rm),
 def : Pat<(AArch64bsp (v2i64 V128:$Rd), V128:$Rn, V128:$Rm),
           (BSPv16i8 V128:$Rd, V128:$Rn, V128:$Rm)>;
 
+def : Pat<(v8i8 (select (v8i8 V64:$Rd), V64:$Rn, V64:$Rm)),
+          (BSPv8i8 V64:$Rd, V64:$Rn, V64:$Rm)>;
+def : Pat<(v4i16 (select (v4i16 V64:$Rd), V64:$Rn, V64:$Rm)),
+          (BSPv8i8 V64:$Rd, V64:$Rn, V64:$Rm)>;
+def : Pat<(v2i32 (select (v2i32 V64:$Rd), V64:$Rn, V64:$Rm)),
+          (BSPv8i8 V64:$Rd, V64:$Rn, V64:$Rm)>;
+def : Pat<(v1i64 (select (v1i64 V64:$Rd), V64:$Rn, V64:$Rm)),
+          (BSPv8i8 V64:$Rd, V64:$Rn, V64:$Rm)>;
+
+def : Pat<(v16i8 (select (v16i8 V128:$Rd), V128:$Rn, V128:$Rm)),
+          (BSPv16i8 V128:$Rd, V128:$Rn, V128:$Rm)>;
+def : Pat<(v8i16 (select (v8i16 V128:$Rd), V128:$Rn, V128:$Rm)),
+          (BSPv16i8 V128:$Rd, V128:$Rn, V128:$Rm)>;
+def : Pat<(v4i32 (select (v4i32 V128:$Rd), V128:$Rn, V128:$Rm)),
+          (BSPv16i8 V128:$Rd, V128:$Rn, V128:$Rm)>;
+def : Pat<(v2i64 (select (v2i64 V128:$Rd), V128:$Rn, V128:$Rm)),
+          (BSPv16i8 V128:$Rd, V128:$Rn, V128:$Rm)>;
+
 // The following SetCC patterns are used for GlobalISel only
 multiclass SelectSetCC<PatFrags InFrag, string INST> {
   def : Pat<(v8i8 (InFrag (v8i8 V64:$Rn), (v8i8 V64:$Rm))),
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index e92c49c2599df..9185d9dc15867 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1067,13 +1067,39 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
   getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
 
   getActionDefinitionsBuilder(G_SELECT)
-      .legalFor({{s32, s32}, {s64, s32}, {p0, s32}})
+      .legalFor({{s32, s32},
+                 {s64, s32},
+                 {p0, s32},
+                 {v8s8, v8s8},
+                 {v4s16, v4s16},
+                 {v2s32, v2s32},
+                 {v16s8, v16s8},
+                 {v8s16, v8s16},
+                 {v4s32, v4s32},
+                 {v2s64, v2s64}})
       .widenScalarToNextPow2(0)
       .clampScalar(0, s32, s64)
-      .clampScalar(1, s32, s32)
       .scalarizeIf(scalarOrEltWiderThan(0, 64), 0)
-      .minScalarEltSameAsIf(all(isVector(0), isVector(1)), 1, 0)
-      .lowerIf(isVector(0));
+      .moreElementsToNextPow2(0)
+      .minScalarEltSameAsIf(all(isVector(0), isScalar(1)), 1, 0)
+      .moreElementsIf(all(isVector(0), isScalar(1)),
+                      [=](const LegalityQuery &Query) {
+                        return std::pair(1, Query.Types[0].changeElementType(
+                                                Query.Types[1]));
+                      })
+      .clampScalar(1, s32, s32)
+      .minScalarEltSameAsIf(isVector(0), 1, 0)
+      .maxScalarEltSameAsIf(isVector(0), 1, 0)
+      .clampNumElements(0, v8s8, v16s8)
+      .clampNumElements(0, v4s16, v8s16)
+      .clampNumElements(0, v2s32, v4s32)
+      .clampMaxNumElements(0, s64, 2)
+      .clampMaxNumElements(0, p0, 2)
+      .bitcastIf(isPointerVector(0), [=](const LegalityQuery &Query) {
+        // Bitcast pointers vector to i64.
+        const LLT DstTy = Query.Types[0];
+        return std::pair(0, DstTy.changeElementType(LLT::integer(64)));
+      });
 
   // Pointer-handling
   getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select-zero.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select-zero.mir
new file mode 100644
index 0000000000000..5a51136041a33
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select-zero.mir
@@ -0,0 +1,73 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            combine_select_zero_false
+body:             |
+  bb.1:
+    liveins: $d0, $d1
+    ; CHECK-LABEL: name: combine_select_zero_false
+    ; CHECK: liveins: $d0, $d1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(<2 x i32>) = COPY $d0
+    ; CHECK-NEXT: %y:_(<2 x i32>) = COPY $d1
+    ; CHECK-NEXT: %c:_(<2 x i32>) = G_ICMP intpred(eq), %x(<2 x i32>), %y
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<2 x i32>) = G_FREEZE %x
+    ; CHECK-NEXT: %s:_(<2 x i32>) = G_AND %c, [[FREEZE]]
+    ; CHECK-NEXT: $d0 = COPY %s(<2 x i32>)
+    %x:_(<2 x i32>) = COPY $d0
+    %y:_(<2 x i32>) = COPY $d1
+    %c:_(<2 x i32>) = G_ICMP intpred(eq), %x:_(<2 x i32>), %y
+    %zero_scalar:_(i32) = G_CONSTANT i32 0
+    %zero:_(<2 x i32>) = G_BUILD_VECTOR %zero_scalar(i32), %zero_scalar(i32)
+    %s:_(<2 x i32>) = G_SELECT %c, %x, %zero
+    $d0 = COPY %s(<2 x i32>)
+...
+---
+name:            combine_select_zero_true
+body:             |
+  bb.1:
+    liveins: $d0, $d1
+    ; CHECK-LABEL: name: combine_select_zero_true
+    ; CHECK: liveins: $d0, $d1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(<2 x i32>) = COPY $d0
+    ; CHECK-NEXT: %y:_(<2 x i32>) = COPY $d1
+    ; CHECK-NEXT: %c:_(<2 x i32>) = G_ICMP intpred(ne), %x(<2 x i32>), %y
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<2 x i32>) = G_FREEZE %x
+    ; CHECK-NEXT: %s:_(<2 x i32>) = G_AND %c, [[FREEZE]]
+    ; CHECK-NEXT: $d0 = COPY %s(<2 x i32>)
+    %x:_(<2 x i32>) = COPY $d0
+    %y:_(<2 x i32>) = COPY $d1
+    %c:_(<2 x i32>) = G_ICMP intpred(eq), %x:_(<2 x i32>), %y
+    %zero_scalar:_(i32) = G_CONSTANT i32 0
+    %zero:_(<2 x i32>) = G_BUILD_VECTOR %zero_scalar(i32), %zero_scalar(i32)
+    %s:_(<2 x i32>) = G_SELECT %c, %zero, %x
+    $d0 = COPY %s(<2 x i32>)
+...
+---
+name:            combine_select_not
+body:             |
+  bb.1:
+    liveins: $d0, $d1
+    ; CHECK-LABEL: name: combine_select_not
+    ; CHECK: liveins: $d0, $d1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:_(<2 x i32>) = COPY $d0
+    ; CHECK-NEXT: %y:_(<2 x i32>) = COPY $d1
+    ; CHECK-NEXT: %s31:_(i32) = G_CONSTANT i32 31
+    ; CHECK-NEXT: %bv31:_(<2 x i32>) = G_BUILD_VECTOR %s31(i32), %s31(i32)
+    ; CHECK-NEXT: %c:_(<2 x i32>) = G_ASHR %x, %bv31(<2 x i32>)
+    ; CHECK-NEXT: %s:_(<2 x i32>) = G_SELECT %c(<2 x i32>), %y, %x
+    ; CHECK-NEXT: $d0 = COPY %s(<2 x i32>)
+    %x:_(<2 x i32>) = COPY $d0
+    %y:_(<2 x i32>) = COPY $d1
+    %s31:_(i32) = G_CONSTANT i32 31
+    %bv31:_(<2 x i32>) = G_BUILD_VECTOR %s31(i32), %s31(i32)
+    %c:_(<2 x i32>) = G_ASHR %x, %bv31
+    %m1s:_(i32) = G_CONSTANT i32 -1
+    %m1:_(<2 x i32>) = G_BUILD_VECTOR %m1s(i32), %m1s(i32)
+    %n:_(<2 x i32>) = G_XOR %c, %m1
+    %s:_(<2 x i32>) = G_SELECT %n, %x, %y
+    $d0 = COPY %s(<2 x i32>)
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max.mir
index b03163ee63f77..f7da42a4d850b 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max.mir
@@ -221,12 +221,7 @@ body: |
     ; CHECK-NEXT: %vec:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: %vec1:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(slt), %vec(<2 x s64>), %vec1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x i64>) = G_AND %vec, [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x i64>) = G_AND %vec1, [[XOR]]
-    ; CHECK-NEXT: %smin:_(<2 x s64>) = G_OR [[AND]], [[AND1]]
+    ; CHECK-NEXT: %smin:_(<2 x s64>) = G_SELECT [[ICMP]](<2 x i64>), %vec, %vec1
     ; CHECK-NEXT: $q0 = COPY %smin(<2 x s64>)
     ; CHECK-NEXT: RET_ReallyLR implicit $q0
     %vec:_(<2 x s64>) = G_IMPLICIT_DEF
@@ -249,21 +244,13 @@ body: |
     ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(slt), [[DEF]](<2 x s64>), [[DEF]]
     ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(slt), [[DEF]](<2 x s64>), [[DEF]]
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[ICMP1]]
-    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[XOR]]
-    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[XOR1]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
-    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+    ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(<2 x s64>) = G_SELECT [[ICMP]](<2 x i64>), [[DEF]], [[DEF]]
+    ; CHECK-NEXT: [[SELECT1:%[0-9]+]]:_(<2 x s64>) = G_SELECT [[ICMP1]](<2 x i64>), [[DEF]], [[DEF]]
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
-    ; CHECK-NEXT: G_STORE [[OR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>), align 32)
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 16
-    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C1]](i64)
-    ; CHECK-NEXT: G_STORE [[OR1]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into unknown-address + 16)
+    ; CHECK-NEXT: G_STORE [[SELECT]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>), align 32)
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C]](i64)
+    ; CHECK-NEXT: G_STORE [[SELECT1]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into unknown-address + 16)
     %vec:_(<4 x s64>) = G_IMPLICIT_DEF
     %vec1:_(<4 x s64>) = G_IMPLICIT_DEF
     %smin:_(<4 x s64>) = G_SMIN %vec, %vec1
@@ -491,12 +478,7 @@ body: |
     ; CHECK-NEXT: %vec:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: %vec1:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(ult), %vec(<2 x s64>), %vec1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x i64>) = G_AND %vec, [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x i64>) = G_AND %vec1, [[XOR]]
-    ; CHECK-NEXT: %umin:_(<2 x s64>) = G_OR [[AND]], [[AND1]]
+    ; CHECK-NEXT: %umin:_(<2 x s64>) = G_SELECT [[ICMP]](<2 x i64>), %vec, %vec1
     ; CHECK-NEXT: $q0 = COPY %umin(<2 x s64>)
     ; CHECK-NEXT: RET_ReallyLR implicit $q0
     %vec:_(<2 x s64>) = G_IMPLICIT_DEF
@@ -519,21 +501,13 @@ body: |
     ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(ult), [[DEF]](<2 x s64>), [[DEF]]
     ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(ult), [[DEF]](<2 x s64>), [[DEF]]
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[ICMP1]]
-    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[XOR]]
-    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x i64>) = G_AND [[DEF]], [[XOR1]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
-    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+    ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(<2 x s64>) = G_SELECT [[ICMP]](<2 x i64>), [[DEF]], [[DEF]]
+    ; CHECK-NEXT: [[SELECT1:%[0-9]+]]:_(<2 x s64>) = G_SELECT [[ICMP1]](<2 x i64>), [[DEF]], [[DEF]]
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
-    ; CHECK-NEXT: G_STORE [[OR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>), align 32)
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 16
-    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C1]](i64)
-    ; CHECK-NEXT: G_STORE [[OR1]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into unknown-address + 16)
+    ; CHECK-NEXT: G_STORE [[SELECT]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>), align 32)
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16
+    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD [[COPY]], [[C]](i64)
+    ; CHECK-NEXT: G_STORE [[SELECT1]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into unknown-address + 16)
     %vec:_(<4 x s64>) = G_IMPLICIT_DEF
     %vec1:_(<4 x s64>) = G_IMPLICIT_DEF
     %umin:_(<4 x s64>) = G_UMIN %vec, %vec1
@@ -761,12 +735,7 @@ body: |
     ; CHECK-NEXT: %vec:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: %vec1:_(<2 x s64>) = G_IMPLICIT_DEF
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x i64>) = G_ICMP intpred(sgt), %vec(<2 x s64>), %vec1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x i64>) = G_XOR [[ICMP]], [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x i64>) = G_AND %vec, [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list