[GlobalISel] Extend G_SELECT of known condition combine to vectors.

Adds a new utility function: isConstantOrConstantSplatVector().

Differential Revision: https://reviews.llvm.org/D110786
This commit is contained in:
Amara Emerson 2021-09-29 15:38:59 -07:00
parent 8256867508
commit 80f4bb5c61
5 changed files with 74 additions and 11 deletions

View File

@ -214,6 +214,18 @@ public:
}
};
/// Represents a G_SELECT.
class GSelect : public GenericMachineInstr {
public:
Register getCondReg() const { return getReg(1); }
Register getTrueReg() const { return getReg(2); }
Register getFalseReg() const { return getReg(3); }
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_SELECT;
}
};
} // namespace llvm
#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H

View File

@ -397,6 +397,12 @@ bool isBuildVectorAllOnes(const MachineInstr &MI,
Optional<RegOrConstant> getVectorSplat(const MachineInstr &MI,
const MachineRegisterInfo &MRI);
/// Determines if \p MI defines a constant integer or a splat vector of
/// constant integers.
/// \returns the scalar constant or None.
Optional<APInt> isConstantOrConstantSplatVector(MachineInstr &MI,
const MachineRegisterInfo &MRI);
/// Attempt to match a unary predicate against a scalar/splat constant or every
/// element of a constant G_BUILD_VECTOR. If \p ConstVal is null, the source
/// value was undef.

View File

@ -2239,13 +2239,13 @@ bool CombinerHelper::matchUndefSelectCmp(MachineInstr &MI) {
}
bool CombinerHelper::matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) {
assert(MI.getOpcode() == TargetOpcode::G_SELECT);
if (auto MaybeCstCmp =
getIConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI)) {
OpIdx = MaybeCstCmp->Value.isNullValue() ? 3 : 2;
return true;
}
return false;
GSelect &SelMI = cast<GSelect>(MI);
auto Cst =
isConstantOrConstantSplatVector(*MRI.getVRegDef(SelMI.getCondReg()), MRI);
if (!Cst)
return false;
OpIdx = Cst->isZero() ? 3 : 2;
return true;
}
bool CombinerHelper::eraseInst(MachineInstr &MI) {

View File

@ -1016,6 +1016,19 @@ Optional<RegOrConstant> llvm::getVectorSplat(const MachineInstr &MI,
return RegOrConstant(Reg);
}
Optional<APInt>
llvm::isConstantOrConstantSplatVector(MachineInstr &MI,
const MachineRegisterInfo &MRI) {
Register Def = MI.getOperand(0).getReg();
if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
return C->Value;
auto MaybeCst = getBuildVectorConstantSplat(MI, MRI);
if (!MaybeCst)
return None;
const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
return APInt(ScalarSize, *MaybeCst, true);
}
bool llvm::matchUnaryPredicate(
const MachineRegisterInfo &MRI, Register Reg,
std::function<bool(const Constant *ConstVal)> Match, bool AllowUndefs) {

View File

@ -9,7 +9,7 @@ body: |
liveins: $x0, $x1
; CHECK-LABEL: name: test_combine_select_same_res
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK: $x0 = COPY [[COPY]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s1) = G_TRUNC %0
%2:_(s64) = G_SELECT %1, %0, %0
@ -23,7 +23,7 @@ body: |
liveins: $x0, $x1
; CHECK-LABEL: name: test_combine_select_undef_res0_res1
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK: $x0 = COPY [[COPY]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s64) = COPY $x1
%2:_(s1) = G_IMPLICIT_DEF
@ -38,7 +38,7 @@ body: |
liveins: $x0, $x1
; CHECK-LABEL: name: test_combine_select_false_res0_res1
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x1
; CHECK: $x0 = COPY [[COPY]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s64) = COPY $x1
%2:_(s1) = G_CONSTANT i1 false
@ -46,6 +46,22 @@ body: |
$x0 = COPY %3(s64)
...
---
# vector select (false, x, y) -> y
name: test_combine_vector_select_false_res0_res1
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_combine_vector_select_false_res0_res1
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q1
; CHECK-NEXT: $q0 = COPY [[COPY]](<4 x s32>)
%0:_(<4 x s32>) = COPY $q0
%1:_(<4 x s32>) = COPY $q1
%2:_(s1) = G_CONSTANT i1 false
%condvec:_(<4 x s1>) = G_BUILD_VECTOR %2, %2, %2, %2
%3:_(<4 x s32>) = G_SELECT %condvec, %0, %1
$q0 = COPY %3(<4 x s32>)
...
---
# select (true, x, y) -> x
name: test_combine_select_true_res0_res1
body: |
@ -53,10 +69,26 @@ body: |
liveins: $x0, $x1
; CHECK-LABEL: name: test_combine_select_true_res0_res1
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK: $x0 = COPY [[COPY]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY]](s64)
%0:_(s64) = COPY $x0
%1:_(s64) = COPY $x1
%2:_(s1) = G_CONSTANT i1 true
%3:_(s64) = G_SELECT %2, %0, %1
$x0 = COPY %3(s64)
...
---
# vector select (true, x, y) -> x
name: test_combine_vector_select_true_res0_res1
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_combine_vector_select_true_res0_res1
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: $q0 = COPY [[COPY]](<4 x s32>)
%0:_(<4 x s32>) = COPY $q0
%1:_(<4 x s32>) = COPY $q1
%2:_(s1) = G_CONSTANT i1 true
%condvec:_(<4 x s1>) = G_BUILD_VECTOR %2, %2, %2, %2
%3:_(<4 x s32>) = G_SELECT %condvec, %0, %1
$q0 = COPY %3(<4 x s32>)
...