llvm.org GIT mirror llvm / 8999dd3
implement InstCombine/shift-trunc-shift.ll. This allows us to compile: #include <math.h> int t1(double d) { return signbit(d); } into: _t1: movd %xmm0, %rax shrq $63, %rax ret instead of: _t1: movd %xmm0, %rax shrq $32, %rax shrl $31, %eax ret on x86-64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45311 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
2 changed file(s) with 54 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
60036003 if (Instruction *NV = FoldOpIntoPhi(I))
60046004 return NV;
60056005
6006 // Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
6007 if (TruncInst *TI = dyn_cast(Op0)) {
6008 Instruction *TrOp = dyn_cast(TI->getOperand(0));
6009 // If 'shift2' is an ashr, we would have to get the sign bit into a funny
6010 // place. Don't try to do this transformation in this case. Also, we
6011 // require that the input operand is a shift-by-constant so that we have
6012 // confidence that the shifts will get folded together. We could do this
6013 // xform in more cases, but it is unlikely to be profitable.
6014 if (TrOp && I.isLogicalShift() && TrOp->isShift() &&
6015 isa(TrOp->getOperand(1))) {
6016 // Okay, we'll do this xform. Make the shift of shift.
6017 Constant *ShAmt = ConstantExpr::getZExt(Op1, TrOp->getType());
6018 Instruction *NSh = BinaryOperator::create(I.getOpcode(), TrOp, ShAmt,
6019 I.getName());
6020 InsertNewInstBefore(NSh, I); // (shift2 (shift1 & 0x00FF), c2)
6021
6022 // For logical shifts, the truncation has the effect of making the high
6023 // part of the register be zeros. Emulate this by inserting an AND to
6024 // clear the top bits as needed. This 'and' will usually be zapped by
6025 // other xforms later if dead.
6026 unsigned SrcSize = TrOp->getType()->getPrimitiveSizeInBits();
6027 unsigned DstSize = TI->getType()->getPrimitiveSizeInBits();
6028 APInt MaskV(APInt::getLowBitsSet(SrcSize, DstSize));
6029
6030 // The mask we constructed says what the trunc would do if occurring
6031 // between the shifts. We want to know the effect *after* the second
6032 // shift. We know that it is a logical shift by a constant, so adjust the
6033 // mask as appropriate.
6034 if (I.getOpcode() == Instruction::Shl)
6035 MaskV <<= Op1->getZExtValue();
6036 else {
6037 assert(I.getOpcode() == Instruction::LShr && "Unknown logical shift");
6038 MaskV = MaskV.lshr(Op1->getZExtValue());
6039 }
6040
6041 Instruction *And = BinaryOperator::createAnd(NSh, ConstantInt::get(MaskV),
6042 TI->getName());
6043 InsertNewInstBefore(And, I); // shift1 & 0x00FF
6044
6045 // Return the value truncated to the interesting size.
6046 return new TruncInst(And, I.getType());
6047 }
6048 }
6049
60066050 if (Op0->hasOneUse()) {
60076051 if (BinaryOperator *Op0BO = dyn_cast(Op0)) {
60086052 // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep lshr.*63
1
2 define i32 @t1(i64 %d18) {
3 entry:
4 %tmp916 = lshr i64 %d18, 32 ; [#uses=1]
5 %tmp917 = trunc i64 %tmp916 to i32 ; [#uses=1]
6 %tmp10 = lshr i32 %tmp917, 31 ; [#uses=1]
7 ret i32 %tmp10
8 }
9