Skip to content

Commit 80f4bb5

Browse files
committed
[GlobalISel] Extend G_SELECT of known condition combine to vectors.
Adds a new utility function: isConstantOrConstantSplatVector(). Differential Revision: https://reviews.llvm.org/D110786
1 parent 8256867 commit 80f4bb5

File tree

5 files changed

+74
-11
lines changed

5 files changed

+74
-11
lines changed

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,18 @@ class GImplicitDef : public GenericMachineInstr {
214214
}
215215
};
216216

217+
/// Represents a G_SELECT.
218+
class GSelect : public GenericMachineInstr {
219+
public:
220+
Register getCondReg() const { return getReg(1); }
221+
Register getTrueReg() const { return getReg(2); }
222+
Register getFalseReg() const { return getReg(3); }
223+
224+
static bool classof(const MachineInstr *MI) {
225+
return MI->getOpcode() == TargetOpcode::G_SELECT;
226+
}
227+
};
228+
217229
} // namespace llvm
218230

219231
#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H

llvm/include/llvm/CodeGen/GlobalISel/Utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ bool isBuildVectorAllOnes(const MachineInstr &MI,
397397
Optional<RegOrConstant> getVectorSplat(const MachineInstr &MI,
398398
const MachineRegisterInfo &MRI);
399399

400+
/// Determines if \p MI defines a constant integer or a splat vector of
401+
/// constant integers.
402+
/// \returns the scalar constant or None.
403+
Optional<APInt> isConstantOrConstantSplatVector(MachineInstr &MI,
404+
const MachineRegisterInfo &MRI);
405+
400406
/// Attempt to match a unary predicate against a scalar/splat constant or every
401407
/// element of a constant G_BUILD_VECTOR. If \p ConstVal is null, the source
402408
/// value was undef.

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,13 +2239,13 @@ bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
22392239
}
22402240

22412241
bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
2242-
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
2243-
if (auto MaybeCstCmp =
2244-
getIConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
2245-
OpIdx = MaybeCstCmp->Value.isNullValue() ? 3 : 2;
2246-
return true;
2247-
}
2248-
return false;
2242+
GSelect &SelMI = cast<GSelect>(MI);
2243+
auto Cst =
2244+
isConstantOrConstantSplatVector(*MRI.getVRegDef(SelMI.getCondReg()), MRI);
2245+
if (!Cst)
2246+
return false;
2247+
OpIdx = Cst->isZero() ? 3 : 2;
2248+
return true;
22492249
}
22502250

22512251
bool CombinerHelper::eraseInst(MachineInstr &MI) {

llvm/lib/CodeGen/GlobalISel/Utils.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,19 @@ Optional<RegOrConstant> llvm::getVectorSplat(const MachineInstr &MI,
10161016
return RegOrConstant(Reg);
10171017
}
10181018

1019+
Optional<APInt>
1020+
llvm::isConstantOrConstantSplatVector(MachineInstr &MI,
1021+
const MachineRegisterInfo &MRI) {
1022+
Register Def = MI.getOperand(0).getReg();
1023+
if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1024+
return C->Value;
1025+
auto MaybeCst = getBuildVectorConstantSplat(MI, MRI);
1026+
if (!MaybeCst)
1027+
return None;
1028+
const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
1029+
return APInt(ScalarSize, *MaybeCst, true);
1030+
}
1031+
10191032
bool llvm::matchUnaryPredicate(
10201033
const MachineRegisterInfo &MRI, Register Reg,
10211034
std::function<bool(const Constant *ConstVal)> Match, bool AllowUndefs) {

llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ body: |
99
liveins: $x0, $x1
1010
; CHECK-LABEL: name: test_combine_select_same_res
1111
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
12-
; CHECK: $x0 = COPY [[COPY]](s64)
12+
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
1313
%0:_(s64) = COPY $x0
1414
%1:_(s1) = G_TRUNC %0
1515
%2:_(s64) = G_SELECT %1, %0, %0
@@ -23,7 +23,7 @@ body: |
2323
liveins: $x0, $x1
2424
; CHECK-LABEL: name: test_combine_select_undef_res0_res1
2525
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
26-
; CHECK: $x0 = COPY [[COPY]](s64)
26+
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
2727
%0:_(s64) = COPY $x0
2828
%1:_(s64) = COPY $x1
2929
%2:_(s1) = G_IMPLICIT_DEF
@@ -38,25 +38,57 @@ body: |
3838
liveins: $x0, $x1
3939
; CHECK-LABEL: name: test_combine_select_false_res0_res1
4040
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
41-
; CHECK: $x0 = COPY [[COPY]](s64)
41+
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
4242
%0:_(s64) = COPY $x0
4343
%1:_(s64) = COPY $x1
4444
%2:_(s1) = G_CONSTANT i1 false
4545
%3:_(s64) = G_SELECT %2, %0, %1
4646
$x0 = COPY %3(s64)
4747
...
4848
---
49+
# vector select (false, x, y) -> y
50+
name: test_combine_vector_select_false_res0_res1
51+
body: |
52+
bb.1:
53+
liveins: $q0, $q1
54+
; CHECK-LABEL: name: test_combine_vector_select_false_res0_res1
55+
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q1
56+
; CHECK-NEXT: $q0 = COPY [[COPY]](<4 x s32>)
57+
%0:_(<4 x s32>) = COPY $q0
58+
%1:_(<4 x s32>) = COPY $q1
59+
%2:_(s1) = G_CONSTANT i1 false
60+
%condvec:_(<4 x s1>) = G_BUILD_VECTOR %2, %2, %2, %2
61+
%3:_(<4 x s32>) = G_SELECT %condvec, %0, %1
62+
$q0 = COPY %3(<4 x s32>)
63+
...
64+
---
4965
# select (true, x, y) -> x
5066
name: test_combine_select_true_res0_res1
5167
body: |
5268
bb.1:
5369
liveins: $x0, $x1
5470
; CHECK-LABEL: name: test_combine_select_true_res0_res1
5571
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
56-
; CHECK: $x0 = COPY [[COPY]](s64)
72+
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
5773
%0:_(s64) = COPY $x0
5874
%1:_(s64) = COPY $x1
5975
%2:_(s1) = G_CONSTANT i1 true
6076
%3:_(s64) = G_SELECT %2, %0, %1
6177
$x0 = COPY %3(s64)
6278
...
79+
---
80+
# vector select (true, x, y) -> x
81+
name: test_combine_vector_select_true_res0_res1
82+
body: |
83+
bb.1:
84+
liveins: $q0, $q1
85+
; CHECK-LABEL: name: test_combine_vector_select_true_res0_res1
86+
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
87+
; CHECK-NEXT: $q0 = COPY [[COPY]](<4 x s32>)
88+
%0:_(<4 x s32>) = COPY $q0
89+
%1:_(<4 x s32>) = COPY $q1
90+
%2:_(s1) = G_CONSTANT i1 true
91+
%condvec:_(<4 x s1>) = G_BUILD_VECTOR %2, %2, %2, %2
92+
%3:_(<4 x s32>) = G_SELECT %condvec, %0, %1
93+
$q0 = COPY %3(<4 x s32>)
94+
...

0 commit comments

Comments
 (0)