llvm.org GIT mirror llvm / e55484e
Add a simple pattern for matching 'bt'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61426 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
2 changed file(s) with 66 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
50165016
50175017 SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
50185018 assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
5019 SDValue Cond;
50205019 SDValue Op0 = Op.getOperand(0);
50215020 SDValue Op1 = Op.getOperand(1);
5022 SDValue CC = Op.getOperand(2);
5021 ISD::CondCode CC = cast(Op.getOperand(2))->get();
5022
5023 // Lower (X & (1 << N)) == 0 to BT.
5024 // Lower ((X >>u N) & 1) != 0 to BT.
5025 // Lower ((X >>s N) & 1) != 0 to BT.
5026 // FIXME: Is i386 or later or available only on some chips?
5027 if (Op0.getOpcode() == ISD::AND && Op1.getOpcode() == ISD::Constant &&
5028 Op0.getOperand(1).getOpcode() == ISD::Constant &&
5029 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
5030 ConstantSDNode *AndRHS = cast(Op0.getOperand(1));
5031 ConstantSDNode *CmpRHS = cast(Op1);
5032 SDValue AndLHS = Op0.getOperand(0);
5033 if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
5034 AndLHS.getOpcode() == ISD::SRL) {
5035 SDValue LHS = AndLHS.getOperand(0);
5036 SDValue RHS = AndLHS.getOperand(1);
5037
5038 // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
5039 // instruction. Since the shift amount is in-range-or-undefined, we know
5040 // that doing a bittest on the i16 value is ok. We extend to i32 because
5041 // the encoding for the i16 version is larger than the i32 version.
5042 if (LHS.getValueType() == MVT::i8)
5043 LHS = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, LHS);
5044
5045 // If the operand types disagree, extend the shift amount to match. Since
5046 // BT ignores high bits (like shifts) we can use anyextend.
5047 if (LHS.getValueType() != RHS.getValueType())
5048 RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
5049
5050 SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
5051 unsigned Cond = CC == ISD::SETEQ ? X86::COND_NC : X86::COND_C;
5052 return DAG.getNode(X86ISD::SETCC, MVT::i8,
5053 DAG.getConstant(Cond, MVT::i8), BT);
5054 }
5055 }
5056
50235057 bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
5024
5025 unsigned X86CC = TranslateX86CC(cast(CC)->get(), isFP,
5026 Op0, Op1, DAG);
5058 unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
50275059
5028 Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
5060 SDValue Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
50295061 return DAG.getNode(X86ISD::SETCC, MVT::i8,
50305062 DAG.getConstant(X86CC, MVT::i8), Cond);
50315063 }
52185250
52195251 if (Cond.getOpcode() == ISD::SETCC)
52205252 Cond = LowerSETCC(Cond, DAG);
5253 #if 0
5254 // FIXME: LowerXALUO doesn't handle these!!
52215255 else if (Cond.getOpcode() == X86ISD::ADD ||
52225256 Cond.getOpcode() == X86ISD::SUB ||
52235257 Cond.getOpcode() == X86ISD::SMUL ||
52245258 Cond.getOpcode() == X86ISD::UMUL)
52255259 Cond = LowerXALUO(Cond, DAG);
5226
5260 #endif
5261
52275262 // If condition flag is set by a X86ISD::CMP, then use it as the condition
52285263 // setting operand in place of the X86ISD::SETCC.
52295264 if (Cond.getOpcode() == X86ISD::SETCC) {
52315266
52325267 SDValue Cmp = Cond.getOperand(1);
52335268 unsigned Opc = Cmp.getOpcode();
5234 if (isX86LogicalCmp(Opc)) {
5269 // FIXME: WHY THE SPECIAL CASING OF LogicalCmp??
5270 if (isX86LogicalCmp(Opc) || Opc == X86ISD::BT) {
52355271 Cond = Cmp;
52365272 addTest = false;
52375273 } else {
52395275 default: break;
52405276 case X86::COND_O:
52415277 case X86::COND_C:
5242 // These can only come from an arithmetic instruction with overflow, e.g.
5243 // SADDO, UADDO.
5278 // These can only come from an arithmetic instruction with overflow,
5279 // e.g. SADDO, UADDO.
52445280 Cond = Cond.getNode()->getOperand(1);
52455281 addTest = false;
52465282 break;
0 ; RUN: llvm-as < %s | llc | grep btl
1 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"
2 target triple = "i386-apple-darwin8"
3
4 define void @test2(i32 %x, i32 %n) nounwind {
5 entry:
6 %tmp29 = lshr i32 %x, %n ; [#uses=1]
7 %tmp3 = and i32 %tmp29, 1 ; [#uses=1]
8 %tmp4 = icmp eq i32 %tmp3, 0 ; [#uses=1]
9 br i1 %tmp4, label %bb, label %UnifiedReturnBlock
10
11 bb: ; preds = %entry
12 call void @foo()
13 ret void
14
15 UnifiedReturnBlock: ; preds = %entry
16 ret void
17 }
18
19 declare void @foo()