diff options
| author | Bill Wendling <isanbard@gmail.com> | 2009-03-26 01:47:50 +0000 |
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2009-03-26 01:47:50 +0000 |
| commit | 94f299f2c53783c57f29afb3c226403f550e5557 (patch) | |
| tree | c2bc123fcb036a1f0a6f5b9e829723f0d089cb01 /llvm | |
| parent | 189d67181c800c46ef03ca45f35cc4acf9da2395 (diff) | |
| download | bcm5719-llvm-94f299f2c53783c57f29afb3c226403f550e5557.tar.gz bcm5719-llvm-94f299f2c53783c57f29afb3c226403f550e5557.zip | |
Match this pattern so that we can generate simpler code:
%a = ...
%b = and i32 %a, 2
%c = srl i32 %b, 1
%d = br i32 %c,
into
%a = ...
%b = and %a, 2
%c = X86ISD::CMP %b, 0
%d = X86ISD::BRCOND %c ...
This applies only when the AND constant value has one bit set and the SRL
constant is equal to the log2 of the AND constant. The back-end is smart enough
to convert the result into a TEST/JMP sequence.
llvm-svn: 67728
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 89228261659..154e8d3fd9c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5870,6 +5870,45 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { CC = DAG.getConstant(CCode, MVT::i8); Cond = Cond.getOperand(0).getOperand(1); addTest = false; + } else if (Cond.hasOneUse() && Cond.getOpcode() == ISD::SRL) { + // Match this pattern so that we can generate simpler code: + // + // %a = ... + // %b = and i32 %a, 2 + // %c = srl i32 %b, 1 + // %d = br i32 %c, + // + // into + // + // %a = ... + // %b = and %a, 2 + // %c = X86ISD::CMP %b, 0 + // %d = X86ISD::BRCOND %c ... + // + // This applies only when the AND constant value has one bit set and the + // SRL constant is equal to the log2 of the AND constant. The back-end is + // smart enough to convert the result into a TEST/JMP sequence. + SDValue Op0 = Cond.getOperand(0); + SDValue Op1 = Cond.getOperand(1); + + if (Op0.getOpcode() == ISD::AND && + Op0.hasOneUse() && + Op1.getOpcode() == ISD::Constant) { + SDValue AndOp0 = Op0.getOperand(0); + SDValue AndOp1 = Op0.getOperand(1); + + if (AndOp1.getOpcode() == ISD::Constant) { + const APInt &AndConst = cast<ConstantSDNode>(AndOp1)->getAPIntValue(); + + if (AndConst.isPowerOf2() && + cast<ConstantSDNode>(Op1)->getAPIntValue()==AndConst.logBase2()) { + CC = DAG.getConstant(X86::COND_NE, MVT::i8); + Cond = EmitTest(Op0, X86::COND_NE, DAG); + return DAG.getNode(X86ISD::BRCOND, dl, Op.getValueType(), + Chain, Dest, CC, Cond); + } + } + } } } |

