summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2012-09-02 12:10:19 +0000
committerNadav Rotem <nrotem@apple.com>2012-09-02 12:10:19 +0000
commit9d832026206d89fe70ecabec281db8f6699dbebc (patch)
treeae5f852032987dbdfd3787dea719c05513ba76d6
parent49dd68ae7cfa1ad3e95c9552c6cabc85fe927bb3 (diff)
downloadbcm5719-llvm-9d832026206d89fe70ecabec281db8f6699dbebc.tar.gz
bcm5719-llvm-9d832026206d89fe70ecabec281db8f6699dbebc.zip
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. llvm-svn: 163093
-rw-r--r--llvm/include/llvm/Target/TargetLowering.h10
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.h5
-rw-r--r--llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp29
-rw-r--r--llvm/test/CodeGen/ARM/2012-08-30-select.ll5
4 files changed, 39 insertions, 10 deletions
diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h
index acf0419510e..b8c070bce75 100644
--- a/llvm/include/llvm/Target/TargetLowering.h
+++ b/llvm/include/llvm/Target/TargetLowering.h
@@ -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; }
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 13b83de85d3..757c68ee370 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -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;
diff --git a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
index cfca726f269..57a648f7b97 100644
--- a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -1174,17 +1174,32 @@ 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())
- return false;
+ bool VectorCond = !SI->getCondition()->getType()->isIntegerTy(1);
- if (!SI->getCondition()->getType()->isIntegerTy(1) ||
- !isFormingBranchFromSelectProfitable(SI))
+ // Can we convert the 'select' to CF ?
+ if (DisableSelectToBranch || OptSize || !TLI || VectorCond)
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;
// First, we split the block containing the select into 2 blocks.
diff --git a/llvm/test/CodeGen/ARM/2012-08-30-select.ll b/llvm/test/CodeGen/ARM/2012-08-30-select.ll
index 4c94ac9dbf0..8471be5330b 100644
--- a/llvm/test/CodeGen/ARM/2012-08-30-select.ll
+++ b/llvm/test/CodeGen/ARM/2012-08-30-select.ll
@@ -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:
OpenPOWER on IntegriCloud