[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