Not all targets have efficient ISel code generation for select instructions.

For example, the ARM target does not have efficient ISel handling for vector
selects with scalar conditions. This patch adds a TLI hook which allows the
different targets to report which selects are supported well and which selects
should be converted to CF duting codegen prepare.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163093 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nadav Rotem 2012-09-02 12:10:19 +00:00
parent 7de7078933
commit 9f40cb32ac
4 changed files with 39 additions and 10 deletions

View File

@ -107,6 +107,14 @@ public:
ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
};
enum SelectSupportKind {
ScalarValSelect, // The target supports scalar selects (ex: cmov).
ScalarCondVectorVal, // The target supports selects with a scalar condition
// and vector values (ex: cmov).
VectorMaskSelect // The target supports vector selects with a vector
// mask (ex: x86 blends).
};
static ISD::NodeType getExtendForContent(BooleanContent Content) {
switch (Content) {
case UndefinedBooleanContent:
@ -140,6 +148,8 @@ public:
/// this target.
bool isSelectExpensive() const { return SelectIsExpensive; }
virtual bool isSelectSupported(SelectSupportKind kind) const { return true; }
/// isIntDivCheap() - Return true if integer divide is usually cheaper than
/// a sequence of several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }

View File

@ -257,6 +257,11 @@ namespace llvm {
virtual const char *getTargetNodeName(unsigned Opcode) const;
virtual bool isSelectSupported(SelectSupportKind Kind) const {
// ARM does not support scalar condition selects on vectors.
return (Kind != ScalarCondVectorVal);
}
/// getSetCCResultType - Return the value type to use for ISD::SETCC.
virtual EVT getSetCCResultType(EVT VT) const;

View File

@ -1174,16 +1174,31 @@ static bool isFormingBranchFromSelectProfitable(SelectInst *SI) {
}
/// If we have a SelectInst that will likely profit from branch prediction,
/// turn it into a branch.
bool CodeGenPrepare::OptimizeSelectInst(SelectInst *SI) {
// If we have a SelectInst that will likely profit from branch prediction,
// turn it into a branch.
if (DisableSelectToBranch || OptSize || !TLI ||
!TLI->isPredictableSelectExpensive())
bool VectorCond = !SI->getCondition()->getType()->isIntegerTy(1);
// Can we convert the 'select' to CF ?
if (DisableSelectToBranch || OptSize || !TLI || VectorCond)
return false;
if (!SI->getCondition()->getType()->isIntegerTy(1) ||
!isFormingBranchFromSelectProfitable(SI))
return false;
TargetLowering::SelectSupportKind SelectKind;
if (VectorCond)
SelectKind = TargetLowering::VectorMaskSelect;
else if (SI->getType()->isVectorTy())
SelectKind = TargetLowering::ScalarCondVectorVal;
else
SelectKind = TargetLowering::ScalarValSelect;
// Do we have efficient codegen support for this kind of 'selects' ?
if (TLI->isSelectSupported(SelectKind)) {
// We have efficient codegen support for the select instruction.
// Check if it is profitable to keep this 'select'.
if (!TLI->isPredictableSelectExpensive() ||
!isFormingBranchFromSelectProfitable(SI))
return false;
}
ModifiedDT = true;

View File

@ -2,9 +2,8 @@
; rdar://12201387
;CHECK: select_s_v_v
;CHECK: it eq
;CHECK-NEXT: moveq.w r2, #-1
;CHECK: vbsl
;CHECK: it ne
;CHECK-NEXT: vmovne.i32
;CHECK: bx
define <16 x i8> @select_s_v_v(i32 %avail, i8* %bar) {
entry: