[llvm] [GlobalIsel][AArch64] MVP for vectorized selects. (PR #76104)

Thorsten Schütt via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 20 15:51:54 PST 2023


https://github.com/tschuett updated https://github.com/llvm/llvm-project/pull/76104

>From 360acc9a0b540012e559dc94bb2177ef86f48d1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Wed, 20 Dec 2023 22:22:23 +0100
Subject: [PATCH 1/4] [GlobalIsel][AArch64] MVP for vectorized selects.

Try to select Selects where the condition is a vector.

Inspired by arm64-vselect.ll and extensions to it.

Note that there are not tests for all legal types.
---
 .../GISel/AArch64InstructionSelector.cpp      | 34 +++++++++
 .../AArch64/GISel/AArch64LegalizerInfo.cpp    |  8 ++-
 .../AArch64/GlobalISel/select-select.mir      | 71 +++++++++++++------
 3 files changed, 91 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index a4ace6cce46342..6fbd850395fda6 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -507,6 +507,9 @@ class AArch64InstructionSelector : public InstructionSelector {
   /// zero extended.
   bool isDef32(const MachineInstr &MI) const;
 
+  /// Select selects where the condition is a vector.
+  bool selectVectorSelect(GSelect &Sel, MachineIRBuilder &MIB) const;
+
   const AArch64TargetMachine &TM;
   const AArch64Subtarget &STI;
   const AArch64InstrInfo &TII;
@@ -1154,6 +1157,34 @@ static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) {
   return GenericOpc;
 }
 
+bool AArch64InstructionSelector::selectVectorSelect(
+    GSelect &Sel, MachineIRBuilder &MIB) const {
+  MachineRegisterInfo *MRI = MIB.getMRI();
+  Register Dst = Sel.getReg(0);
+  Register Cond = Sel.getCondReg();
+  Register True = Sel.getTrueReg();
+  Register False = Sel.getFalseReg();
+  LLT DestTy = MRI->getType(Dst);
+  LLT CondTy = MRI->getType(Cond);
+
+  // There are no scalable vectors yet.
+  if (CondTy.isScalable())
+    return false;
+
+  // We would need to sext the Cond to the Dest, i.e., sshll.
+  // It will fail for v2s64, v4s32, and v8s16.
+  if (CondTy != DestTy)
+    return false;
+
+  unsigned Opcode =
+      CondTy.getSizeInBits() == 128 ? AArch64::BSLv16i8 : AArch64::BSLv8i8;
+  auto SelMI = MIB.buildInstr(Opcode, {Dst}, {Cond, True, False});
+  constrainSelectedInstRegOperands(*SelMI, TII, TRI, RBI);
+
+  Sel.eraseFromParent();
+  return true;
+}
+
 MachineInstr *
 AArch64InstructionSelector::emitSelect(Register Dst, Register True,
                                        Register False, AArch64CC::CondCode CC,
@@ -3442,6 +3473,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
     const Register TReg = Sel.getTrueReg();
     const Register FReg = Sel.getFalseReg();
 
+    if (MRI.getType(CondReg).isVector())
+      return selectVectorSelect(Sel, MIB);
+
     if (tryOptSelect(Sel))
       return true;
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 8b909f53c84460..0af18108c6710f 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -708,7 +708,13 @@ 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},
+                 {v2s32, v2s32},
+                 {v4s16, v4s16},
+                 {v8s8, v8s8},
+                 {v16s8, v16s8}})
       .widenScalarToNextPow2(0)
       .clampScalar(0, s32, s64)
       .clampScalar(1, s32, s32)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
index e26c1431350979..8d125a81df49a5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
@@ -95,7 +95,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
 
     ; CHECK-LABEL: name: csinc_t_0_f_1
     ; CHECK: liveins: $w0, $w1
@@ -123,7 +122,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
 
     ; CHECK-LABEL: name: csinv_t_0_f_neg_1
     ; CHECK: liveins: $w0, $w1
@@ -151,7 +149,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 
     ; CHECK-LABEL: name: csinc_t_1
     ; CHECK: liveins: $w0, $w1, $w2
@@ -180,7 +177,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, -1, f -> CSINV f, zreg, inv_cc
 
     ; CHECK-LABEL: name: csinv_t_neg_1
     ; CHECK: liveins: $w0, $w1, $w2
@@ -209,7 +205,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, t, 1 -> CSINC t, zreg, cc
 
     ; CHECK-LABEL: name: csinc_f_1
     ; CHECK: liveins: $w0, $w1, $w2
@@ -238,7 +233,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, t, -1 -> CSINC t, zreg, cc
 
     ; CHECK-LABEL: name: csinc_f_neg_1
     ; CHECK: liveins: $w0, $w1, $w2
@@ -267,7 +261,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 
     ; CHECK-LABEL: name: csinc_t_1_no_cmp
     ; CHECK: liveins: $w0, $w1
@@ -294,7 +287,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1
-    ; G_SELECT cc, t, 1 -> CSINC t, zreg, cc
 
     ; CHECK-LABEL: name: csinc_f_1_no_cmp
     ; CHECK: liveins: $w0, $w1
@@ -321,7 +313,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $x0, $x1
-    ; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 
     ; CHECK-LABEL: name: csinc_t_1_no_cmp_s64
     ; CHECK: liveins: $x0, $x1
@@ -350,7 +341,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
 
     ; CHECK-LABEL: name: csneg_s32
     ; CHECK: liveins: $w0, $w1, $w2
@@ -380,7 +370,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, (G_SUB 0, %x), %false -> CSNEG %x, %false, inv_cc
 
     ; CHECK-LABEL: name: csneg_inverted_cc
     ; CHECK: liveins: $w0, $w1, $w2
@@ -410,7 +399,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
-    ; G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
 
     ; CHECK-LABEL: name: csneg_s64
     ; CHECK: liveins: $x0, $x1, $x2
@@ -441,8 +429,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; We should prefer eliminating the G_SUB over eliminating the constant true
-    ; value.
 
     ; CHECK-LABEL: name: csneg_with_true_cst
     ; CHECK: liveins: $w0, $w1, $w2
@@ -472,7 +458,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
 
     ; CHECK-LABEL: name: csinv_s32
     ; CHECK: liveins: $w0, $w1, $w2
@@ -502,7 +487,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, (G_XOR x, -1), %false -> CSINV %x, %false, inv_cc
 
     ; CHECK-LABEL: name: csinv_inverted_cc
     ; CHECK: liveins: $w0, $w1, $w2
@@ -532,7 +516,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
-    ; G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
 
     ; CHECK-LABEL: name: csinv_s64
     ; CHECK: liveins: $x0, $x1, $x2
@@ -564,7 +547,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
-    ; zext(s32 -1) != s64 -1, so we can't fold it away.
 
     ; CHECK-LABEL: name: xor_not_negative_one
     ; CHECK: liveins: $x0, $x1, $x2
@@ -601,7 +583,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, %true, (G_ADD %x, 1) -> CSINC %true, %x, cc
     ; CHECK-LABEL: name: csinc_s32
     ; CHECK: liveins: $w0, $w1, $w2
     ; CHECK-NEXT: {{  $}}
@@ -630,7 +611,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; G_SELECT cc, (G_ADD %x, 1), %false -> CSINC %x, %false, inv_cc
     ; CHECK-LABEL: name: csinc_s32_inverted_cc
     ; CHECK: liveins: $w0, $w1, $w2
     ; CHECK-NEXT: {{  $}}
@@ -659,7 +639,6 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $x0, $x1, $x2
-    ; G_SELECT cc, %true, (G_PTR_ADD %x, 1) -> CSINC %true, %x, cc
 
     ; CHECK-LABEL: name: csinc_ptr_add
     ; CHECK: liveins: $x0, $x1, $x2
@@ -713,3 +692,53 @@ body:             |
     %select:gpr(s32) = G_SELECT %reg0, %xor, %sub
     $w0 = COPY %select(s32)
     RET_ReallyLR implicit $w0
+...
+---
+name:            select_vectorized_conditon_v2s32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $w0, $w1, $w2
+    ; CHECK-LABEL: name: select_vectorized_conditon_v2s32
+    ; CHECK: liveins: $w0, $w1, $w2
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %reg0:gpr32all = COPY $w0
+    ; CHECK-NEXT: %reg1:gpr32 = COPY $w1
+    ; CHECK-NEXT: %reg2:gpr32all = COPY $w2
+    ; CHECK-NEXT: %reg3:gpr32 = COPY $w0
+    ; CHECK-NEXT: %reg4:gpr32all = COPY $w1
+    ; CHECK-NEXT: %reg5:gpr32 = COPY $w2
+    ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], %reg0, %subreg.ssub
+    ; CHECK-NEXT: [[INSvi32gpr:%[0-9]+]]:fpr128 = INSvi32gpr [[INSERT_SUBREG]], 1, %reg1
+    ; CHECK-NEXT: %true:fpr64 = COPY [[INSvi32gpr]].dsub
+    ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF1]], %reg2, %subreg.ssub
+    ; CHECK-NEXT: [[INSvi32gpr1:%[0-9]+]]:fpr128 = INSvi32gpr [[INSERT_SUBREG1]], 1, %reg3
+    ; CHECK-NEXT: %false:fpr64 = COPY [[INSvi32gpr1]].dsub
+    ; CHECK-NEXT: [[DEF2:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF2]], %reg4, %subreg.ssub
+    ; CHECK-NEXT: [[INSvi32gpr2:%[0-9]+]]:fpr128 = INSvi32gpr [[INSERT_SUBREG2]], 1, %reg5
+    ; CHECK-NEXT: %cond:fpr64 = COPY [[INSvi32gpr2]].dsub
+    ; CHECK-NEXT: %select:fpr64 = BSLv8i8 %cond, %true, %false
+    ; CHECK-NEXT: [[DEF3:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF3]], %select, %subreg.dsub
+    ; CHECK-NEXT: %extract:fpr32 = DUPi32 [[INSERT_SUBREG3]], 1
+    ; CHECK-NEXT: $w0 = COPY %extract
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %idx:gpr(s64) = G_CONSTANT i64 1
+    %reg0:gpr(s32) = COPY $w0
+    %reg1:gpr(s32) = COPY $w1
+    %reg2:gpr(s32) = COPY $w2
+    %reg3:gpr(s32) = COPY $w0
+    %reg4:gpr(s32) = COPY $w1
+    %reg5:gpr(s32) = COPY $w2
+    %true:fpr(<2 x s32>) = G_BUILD_VECTOR %reg0(s32), %reg1(s32)
+    %false:fpr(<2 x s32>) = G_BUILD_VECTOR %reg2(s32), %reg3(s32)
+    %cond:fpr(<2 x s32>) = G_BUILD_VECTOR %reg4(s32), %reg5(s32)
+    %select:fpr(<2 x s32>) = G_SELECT %cond, %true, %false
+    %extract:fpr(s32) = G_EXTRACT_VECTOR_ELT %select:fpr(<2 x s32>), %idx:gpr(s64)
+    $w0 = COPY %extract(s32)
+    RET_ReallyLR implicit $w0

>From b6a7d7418ad75eb52d7ef1c614821364d6398067 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Wed, 20 Dec 2023 22:45:34 +0100
Subject: [PATCH 2/4] preserve comments

---
 .../AArch64/GlobalISel/select-select.mir      | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
index 8d125a81df49a5..9602dd7ef0a7fd 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
@@ -88,6 +88,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
 name:            csinc_t_0_f_1
 legalized:       true
 regBankSelected: true
@@ -115,6 +116,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
 name:            csinv_t_0_f_neg_1
 legalized:       true
 regBankSelected: true
@@ -142,6 +144,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 name:            csinc_t_1
 legalized:       true
 regBankSelected: true
@@ -198,6 +201,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, t, 1 -> CSINC t, zreg, cc
 name:            csinc_f_1
 legalized:       true
 regBankSelected: true
@@ -226,6 +230,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, t, -1 -> CSINC t, zreg, cc
 name:            csinc_f_neg_1
 legalized:       true
 regBankSelected: true
@@ -254,6 +259,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 name:            csinc_t_1_no_cmp
 legalized:       true
 regBankSelected: true
@@ -280,6 +286,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, t, 1 -> CSINC t, zreg, cc
 name:            csinc_f_1_no_cmp
 legalized:       true
 regBankSelected: true
@@ -306,6 +313,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
 name:            csinc_t_1_no_cmp_s64
 legalized:       true
 regBankSelected: true
@@ -334,6 +342,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
 name:            csneg_s32
 legalized:       true
 regBankSelected: true
@@ -363,6 +372,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, (G_SUB 0, %x), %false -> CSNEG %x, %false, inv_cc
 name:            csneg_inverted_cc
 legalized:       true
 regBankSelected: true
@@ -392,6 +402,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
 name:            csneg_s64
 legalized:       true
 regBankSelected: true
@@ -422,6 +433,8 @@ body:             |
     RET_ReallyLR implicit $x0
 ...
 ---
+# We should prefer eliminating the G_SUB over eliminating the constant true
+#  value.
 name:            csneg_with_true_cst
 legalized:       true
 regBankSelected: true
@@ -451,6 +464,7 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
+# G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
 name:            csinv_s32
 legalized:       true
 regBankSelected: true
@@ -480,6 +494,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, (G_XOR x, -1), %false -> CSINV %x, %false, inv_cc
 name:            csinv_inverted_cc
 legalized:       true
 regBankSelected: true
@@ -509,6 +524,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
 name:            csinv_s64
 legalized:       true
 regBankSelected: true
@@ -540,6 +556,7 @@ body:             |
 
 ...
 ---
+# zext(s32 -1) != s64 -1, so we can't fold it away.
 name:            xor_not_negative_one
 legalized:       true
 regBankSelected: true
@@ -576,6 +593,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, %true, (G_ADD %x, 1) -> CSINC %true, %x, cc
 name:            csinc_s32
 legalized:       true
 regBankSelected: true
@@ -604,6 +622,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, (G_ADD %x, 1), %false -> CSINC %x, %false, inv_cc
 name:            csinc_s32_inverted_cc
 legalized:       true
 regBankSelected: true
@@ -632,6 +651,7 @@ body:             |
 
 ...
 ---
+# G_SELECT cc, %true, (G_PTR_ADD %x, 1) -> CSINC %true, %x, cc
 name:            csinc_ptr_add
 legalized:       true
 regBankSelected: true

>From 4b4f5a41d246f63b80cb753327bc04a434429495 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Wed, 20 Dec 2023 23:13:11 +0100
Subject: [PATCH 3/4] add missing legalizer test

---
 .../AArch64/GlobalISel/legalize-select.mir    | 148 ++++++++++++++++--
 1 file changed, 134 insertions(+), 14 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-select.mir
index 4879ffd28784c1..f5ee0ad7601046 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-select.mir
@@ -53,13 +53,8 @@ body:             |
     ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s32>) = G_ICMP intpred(sgt), [[COPY]](<2 x s32>), [[BUILD_VECTOR]]
     ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(<2 x s32>) = G_SEXT_INREG [[ICMP]], 1
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C1]](s32)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s32>) = G_XOR [[SEXT_INREG]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s32>) = G_AND [[COPY1]], [[SEXT_INREG]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[COPY]], [[XOR]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s32>) = G_OR [[AND]], [[AND1]]
-    ; CHECK-NEXT: $d0 = COPY [[OR]](<2 x s32>)
+    ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[SEXT_INREG]](<2 x s32>), [[COPY1]], [[COPY]]
+    ; CHECK-NEXT: $d0 = COPY [[SELECT]](<2 x s32>)
     ; CHECK-NEXT: RET_ReallyLR implicit $d0
     %0:_(<2 x s32>) = COPY $d0
     %1:_(<2 x s32>) = COPY $d1
@@ -88,13 +83,8 @@ body:             |
     ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<16 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
     ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<16 x s8>) = G_ICMP intpred(sgt), [[COPY]](<16 x s8>), [[BUILD_VECTOR]]
     ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(<16 x s8>) = G_SEXT_INREG [[ICMP]], 1
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<16 x s8>) = G_BUILD_VECTOR [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8), [[C1]](s8)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<16 x s8>) = G_XOR [[SEXT_INREG]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<16 x s8>) = G_AND [[COPY1]], [[SEXT_INREG]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<16 x s8>) = G_AND [[COPY]], [[XOR]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<16 x s8>) = G_OR [[AND]], [[AND1]]
-    ; CHECK-NEXT: $q0 = COPY [[OR]](<16 x s8>)
+    ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(<16 x s8>) = G_SELECT [[SEXT_INREG]](<16 x s8>), [[COPY1]], [[COPY]]
+    ; CHECK-NEXT: $q0 = COPY [[SELECT]](<16 x s8>)
     ; CHECK-NEXT: RET_ReallyLR implicit $q0
     %0:_(<16 x s8>) = COPY $q0
     %1:_(<16 x s8>) = COPY $q1
@@ -382,3 +372,133 @@ body:             |
     RET_ReallyLR implicit $q0
 
 ...
+---
+name:            select_with_vector_condition_v2s32
+liveins:
+  - { reg: '$x0' }
+  - { reg: '$q0' }
+body:             |
+  bb.1:
+    liveins: $q0, $x0
+    ; CHECK-LABEL: name: select_with_vector_condition_v2s32
+    ; CHECK: liveins: $q0, $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %idx:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+    ; CHECK-NEXT: %cond:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+    ; CHECK-NEXT: %true:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+    ; CHECK-NEXT: %false:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+    ; CHECK-NEXT: %select:_(<2 x s32>) = G_SELECT %cond(<2 x s32>), %true, %false
+    ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %select(<2 x s32>), %idx(s64)
+    ; CHECK-NEXT: $w0 = COPY %extract(s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %idx:_(s64) = G_CONSTANT i64 0
+    %2:_(s32) = G_CONSTANT i32 0
+    %cond:_(<2 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32)
+    %true:_(<2 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32)
+    %false:_(<2 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32)
+    %select:_(<2 x s32>) = G_SELECT %cond(<2 x s32>), %true, %false
+    %extract:_(s32) = G_EXTRACT_VECTOR_ELT %select:_(<2 x s32>), %idx:_(s64)
+    $w0 = COPY %extract
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            select_with_vector_condition_v4s16
+liveins:
+  - { reg: '$x0' }
+  - { reg: '$q0' }
+body:             |
+  bb.1:
+    liveins: $q0, $x0
+    ; CHECK-LABEL: name: select_with_vector_condition_v4s16
+    ; CHECK: liveins: $q0, $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %idx:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
+    ; CHECK-NEXT: %cond:_(<4 x s16>) = G_BUILD_VECTOR [[C]](s16), [[C]](s16), [[C]](s16), [[C]](s16)
+    ; CHECK-NEXT: %true:_(<4 x s16>) = G_BUILD_VECTOR [[C]](s16), [[C]](s16), [[C]](s16), [[C]](s16)
+    ; CHECK-NEXT: %false:_(<4 x s16>) = G_BUILD_VECTOR [[C]](s16), [[C]](s16), [[C]](s16), [[C]](s16)
+    ; CHECK-NEXT: %select:_(<4 x s16>) = G_SELECT %cond(<4 x s16>), %true, %false
+    ; CHECK-NEXT: %extract:_(s16) = G_EXTRACT_VECTOR_ELT %select(<4 x s16>), %idx(s64)
+    ; CHECK-NEXT: %zext:_(s32) = G_ZEXT %extract(s16)
+    ; CHECK-NEXT: $w0 = COPY %zext(s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %idx:_(s64) = G_CONSTANT i64 0
+    %2:_(s16) = G_CONSTANT i16 0
+    %cond:_(<4 x s16>) = G_BUILD_VECTOR %2(s16), %2(s16), %2(s16), %2(s16)
+    %true:_(<4 x s16>) = G_BUILD_VECTOR %2(s16), %2(s16), %2(s16), %2(s16)
+    %false:_(<4 x s16>) = G_BUILD_VECTOR %2(s16), %2(s16), %2(s16), %2(s16)
+    %select:_(<4 x s16>) = G_SELECT %cond(<4 x s16>), %true, %false
+    %extract:_(s16) = G_EXTRACT_VECTOR_ELT %select:_(<4 x s16>), %idx:_(s64)
+    %zext:_(s32) = G_ZEXT %extract:_(s16)
+    $w0 = COPY %zext
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:            select_with_vector_condition_v8s8
+liveins:
+  - { reg: '$x0' }
+  - { reg: '$q0' }
+body:             |
+  bb.1:
+    liveins: $q0, $x0
+    ; CHECK-LABEL: name: select_with_vector_condition_v8s8
+    ; CHECK: liveins: $q0, $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %idx:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
+    ; CHECK-NEXT: %cond:_(<8 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %true:_(<8 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %false:_(<8 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %select:_(<8 x s8>) = G_SELECT %cond(<8 x s8>), %true, %false
+    ; CHECK-NEXT: %extract:_(s8) = G_EXTRACT_VECTOR_ELT %select(<8 x s8>), %idx(s64)
+    ; CHECK-NEXT: %zext:_(s32) = G_ZEXT %extract(s8)
+    ; CHECK-NEXT: $w0 = COPY %zext(s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %idx:_(s64) = G_CONSTANT i64 0
+    %2:_(s8) = G_CONSTANT i8 0
+    %cond:_(<8 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %true:_(<8 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %false:_(<8 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %select:_(<8 x s8>) = G_SELECT %cond(<8 x s8>), %true, %false
+    %extract:_(s8) = G_EXTRACT_VECTOR_ELT %select:_(<8 x s8>), %idx:_(s64)
+    %zext:_(s32) = G_ZEXT %extract:_(s8)
+    $w0 = COPY %zext
+    RET_ReallyLR implicit $x0
+
+...
+---
+name:            select_with_vector_condition_v16s8
+liveins:
+  - { reg: '$x0' }
+  - { reg: '$q0' }
+body:             |
+  bb.1:
+    liveins: $q0, $x0
+    ; CHECK-LABEL: name: select_with_vector_condition_v16s8
+    ; CHECK: liveins: $q0, $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %idx:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
+    ; CHECK-NEXT: %cond:_(<16 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %true:_(<16 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %false:_(<16 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8), [[C]](s8)
+    ; CHECK-NEXT: %select:_(<16 x s8>) = G_SELECT %cond(<16 x s8>), %true, %false
+    ; CHECK-NEXT: %extract:_(s8) = G_EXTRACT_VECTOR_ELT %select(<16 x s8>), %idx(s64)
+    ; CHECK-NEXT: %zext:_(s32) = G_ZEXT %extract(s8)
+    ; CHECK-NEXT: $w0 = COPY %zext(s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $x0
+    %idx:_(s64) = G_CONSTANT i64 0
+    %2:_(s8) = G_CONSTANT i8 0
+    %cond:_(<16 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %true:_(<16 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %false:_(<16 x s8>) = G_BUILD_VECTOR %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8), %2(s8)
+    %select:_(<16 x s8>) = G_SELECT %cond(<16 x s8>), %true, %false
+    %extract:_(s8) = G_EXTRACT_VECTOR_ELT %select:_(<16 x s8>), %idx:_(s64)
+    %zext:_(s32) = G_ZEXT %extract:_(s8)
+    $w0 = COPY %zext
+    RET_ReallyLR implicit $x0
+
+...

>From 4705d9934e4165dd28da58a9a3777138e0f91bcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Thu, 21 Dec 2023 00:51:13 +0100
Subject: [PATCH 4/4] more select tests

---
 .../AArch64/GlobalISel/select-select.mir      | 88 ++++++++++++++++++-
 1 file changed, 86 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
index 9602dd7ef0a7fd..1bf1251b7956bb 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-select.mir
@@ -714,14 +714,14 @@ body:             |
     RET_ReallyLR implicit $w0
 ...
 ---
-name:            select_vectorized_conditon_v2s32
+name:            select_vectorized_condition_v2s32
 legalized:       true
 regBankSelected: true
 tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $w0, $w1, $w2
-    ; CHECK-LABEL: name: select_vectorized_conditon_v2s32
+    ; CHECK-LABEL: name: select_vectorized_condition_v2s32
     ; CHECK: liveins: $w0, $w1, $w2
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %reg0:gpr32all = COPY $w0
@@ -762,3 +762,87 @@ body:             |
     %extract:fpr(s32) = G_EXTRACT_VECTOR_ELT %select:fpr(<2 x s32>), %idx:gpr(s64)
     $w0 = COPY %extract(s32)
     RET_ReallyLR implicit $w0
+
+...
+---
+name:            select_vectorized_condition_v4s16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $w0, $w1, $w2
+    ; CHECK-LABEL: name: select_vectorized_condition_v4s16
+    ; CHECK: liveins: $w0, $w1, $w2
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool)
+    ; CHECK-NEXT: [[ADRP1:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRDui1:%[0-9]+]]:fpr64 = LDRDui [[ADRP1]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool)
+    ; CHECK-NEXT: [[ADRP2:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRDui2:%[0-9]+]]:fpr64 = LDRDui [[ADRP2]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool)
+    ; CHECK-NEXT: %select:fpr64 = BSLv8i8 [[LDRDui2]], [[LDRDui]], [[LDRDui1]]
+    ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+    ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], %select, %subreg.dsub
+    ; CHECK-NEXT: %zext:gpr32 = UMOVvi16 [[INSERT_SUBREG]], 1
+    ; CHECK-NEXT: $w0 = COPY %zext
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %idx:gpr(s64) = G_CONSTANT i64 1
+    %reg0:gpr(s32) = COPY $w0
+    %reg1:gpr(s32) = COPY $w1
+    %reg2:gpr(s32) = COPY $w2
+    %reg3:gpr(s32) = COPY $w0
+    %reg4:gpr(s32) = COPY $w1
+    %reg5:gpr(s32) = COPY $w2
+    %const0:gpr(s16) = G_CONSTANT i16 9
+    %const1:gpr(s16) = G_CONSTANT i16 11
+    %true:fpr(<4 x s16>) = G_BUILD_VECTOR %const0(s16), %const1(s16), %const0(s16), %const1(s16)
+    %false:fpr(<4 x s16>) = G_BUILD_VECTOR %const0(s16), %const1(s16), %const0(s16), %const1(s16)
+    %cond:fpr(<4 x s16>) = G_BUILD_VECTOR %const0(s16), %const1(s16), %const0(s16), %const1(s16)
+    %select:fpr(<4 x s16>) = G_SELECT %cond, %true, %false
+    %extract:fpr(s16) = G_EXTRACT_VECTOR_ELT %select:fpr(<4 x s16>), %idx:gpr(s64)
+    %extra:gpr(s16) = COPY %extract:fpr(s16)
+    %zext:gpr(s32) = G_ZEXT %extra:gpr(s16)
+    $w0 = COPY %zext(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            select_vectorized_condition_v16s8
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $w0, $w1, $w2
+    ; CHECK-LABEL: name: select_vectorized_condition_v16s8
+    ; CHECK: liveins: $w0, $w1, $w2
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+    ; CHECK-NEXT: [[ADRP1:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRQui1:%[0-9]+]]:fpr128 = LDRQui [[ADRP1]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+    ; CHECK-NEXT: [[ADRP2:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+    ; CHECK-NEXT: [[LDRQui2:%[0-9]+]]:fpr128 = LDRQui [[ADRP2]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+    ; CHECK-NEXT: %select:fpr128 = BSLv16i8 [[LDRQui2]], [[LDRQui]], [[LDRQui1]]
+    ; CHECK-NEXT: %zext:gpr32 = UMOVvi8 %select, 1
+    ; CHECK-NEXT: $w0 = COPY %zext
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %idx:gpr(s64) = G_CONSTANT i64 1
+    %reg0:gpr(s32) = COPY $w0
+    %reg1:gpr(s32) = COPY $w1
+    %reg2:gpr(s32) = COPY $w2
+    %reg3:gpr(s32) = COPY $w0
+    %reg4:gpr(s32) = COPY $w1
+    %reg5:gpr(s32) = COPY $w2
+    %const0:gpr(s8) = G_CONSTANT i8 9
+    %const1:gpr(s8) = G_CONSTANT i8 11
+    %true:fpr(<16 x s8>) = G_BUILD_VECTOR %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8)
+    %false:fpr(<16 x s8>) = G_BUILD_VECTOR %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8)
+    %cond:fpr(<16 x s8>) = G_BUILD_VECTOR %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8), %const0(s8), %const1(s8)
+    %select:fpr(<16 x s8>) = G_SELECT %cond, %true, %false
+    %extract:fpr(s8) = G_EXTRACT_VECTOR_ELT %select:fpr(<16 x s8>), %idx:gpr(s64)
+    %extra:gpr(s8) = COPY %extract:fpr(s8)
+    %zext:gpr(s32) = G_ZEXT %extra:gpr(s8)
+    $w0 = COPY %zext(s32)
+    RET_ReallyLR implicit $w0



More information about the llvm-commits mailing list