[llvm-commits] [llvm] r61426 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/bt.ll
Chris Lattner
sabre at nondot.org
Wed Dec 24 21:34:38 PST 2008
Author: lattner
Date: Wed Dec 24 23:34:37 2008
New Revision: 61426
URL: http://llvm.org/viewvc/llvm-project?rev=61426&view=rev
Log:
Add a simple pattern for matching 'bt'.
Added:
llvm/trunk/test/CodeGen/X86/bt.ll
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=61426&r1=61425&r2=61426&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 24 23:34:37 2008
@@ -5017,16 +5017,48 @@
SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
- SDValue Cond;
SDValue Op0 = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1);
- SDValue CC = Op.getOperand(2);
- bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
+ ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+
+ // Lower (X & (1 << N)) == 0 to BT.
+ // Lower ((X >>u N) & 1) != 0 to BT.
+ // Lower ((X >>s N) & 1) != 0 to BT.
+ // FIXME: Is i386 or later or available only on some chips?
+ if (Op0.getOpcode() == ISD::AND && Op1.getOpcode() == ISD::Constant &&
+ Op0.getOperand(1).getOpcode() == ISD::Constant &&
+ (CC == ISD::SETEQ || CC == ISD::SETNE)) {
+ ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
+ ConstantSDNode *CmpRHS = cast<ConstantSDNode>(Op1);
+ SDValue AndLHS = Op0.getOperand(0);
+ if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
+ AndLHS.getOpcode() == ISD::SRL) {
+ SDValue LHS = AndLHS.getOperand(0);
+ SDValue RHS = AndLHS.getOperand(1);
+
+ // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
+ // instruction. Since the shift amount is in-range-or-undefined, we know
+ // that doing a bittest on the i16 value is ok. We extend to i32 because
+ // the encoding for the i16 version is larger than the i32 version.
+ if (LHS.getValueType() == MVT::i8)
+ LHS = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, LHS);
+
+ // If the operand types disagree, extend the shift amount to match. Since
+ // BT ignores high bits (like shifts) we can use anyextend.
+ if (LHS.getValueType() != RHS.getValueType())
+ RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
+
+ SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
+ unsigned Cond = CC == ISD::SETEQ ? X86::COND_NC : X86::COND_C;
+ return DAG.getNode(X86ISD::SETCC, MVT::i8,
+ DAG.getConstant(Cond, MVT::i8), BT);
+ }
+ }
- unsigned X86CC = TranslateX86CC(cast<CondCodeSDNode>(CC)->get(), isFP,
- Op0, Op1, DAG);
+ bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
+ unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
- Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
+ SDValue Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
return DAG.getNode(X86ISD::SETCC, MVT::i8,
DAG.getConstant(X86CC, MVT::i8), Cond);
}
@@ -5219,12 +5251,15 @@
if (Cond.getOpcode() == ISD::SETCC)
Cond = LowerSETCC(Cond, DAG);
+#if 0
+ // FIXME: LowerXALUO doesn't handle these!!
else if (Cond.getOpcode() == X86ISD::ADD ||
Cond.getOpcode() == X86ISD::SUB ||
Cond.getOpcode() == X86ISD::SMUL ||
Cond.getOpcode() == X86ISD::UMUL)
Cond = LowerXALUO(Cond, DAG);
-
+#endif
+
// If condition flag is set by a X86ISD::CMP, then use it as the condition
// setting operand in place of the X86ISD::SETCC.
if (Cond.getOpcode() == X86ISD::SETCC) {
@@ -5232,7 +5267,8 @@
SDValue Cmp = Cond.getOperand(1);
unsigned Opc = Cmp.getOpcode();
- if (isX86LogicalCmp(Opc)) {
+ // FIXME: WHY THE SPECIAL CASING OF LogicalCmp??
+ if (isX86LogicalCmp(Opc) || Opc == X86ISD::BT) {
Cond = Cmp;
addTest = false;
} else {
@@ -5240,8 +5276,8 @@
default: break;
case X86::COND_O:
case X86::COND_C:
- // These can only come from an arithmetic instruction with overflow, e.g.
- // SADDO, UADDO.
+ // These can only come from an arithmetic instruction with overflow,
+ // e.g. SADDO, UADDO.
Cond = Cond.getNode()->getOperand(1);
addTest = false;
break;
Added: llvm/trunk/test/CodeGen/X86/bt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bt.ll?rev=61426&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bt.ll (added)
+++ llvm/trunk/test/CodeGen/X86/bt.ll Wed Dec 24 23:34:37 2008
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc | grep btl
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin8"
+
+define void @test2(i32 %x, i32 %n) nounwind {
+entry:
+ %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1]
+ %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1]
+ %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb: ; preds = %entry
+ call void @foo()
+ ret void
+
+UnifiedReturnBlock: ; preds = %entry
+ ret void
+}
+
+declare void @foo()
More information about the llvm-commits
mailing list