summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-05-20 21:01:12 +0000
committerDan Gohman <gohman@apple.com>2008-05-20 21:01:12 +0000
commit81ab753b1485582b44cca121f02097b719a2195e (patch)
treee707baa119a4094d63e780c52d3f5f6f026ac9ea /llvm/lib/Transforms
parent1e427c3264c25b01630dfc2bf89e4f4f7bc570b8 (diff)
downloadbcm5719-llvm-81ab753b1485582b44cca121f02097b719a2195e.tar.gz
bcm5719-llvm-81ab753b1485582b44cca121f02097b719a2195e.zip
Port SelectionDAG's ComputeNumSignBits-using code to instcombine,
now that instcombine also has ComputeNumSignBits. llvm-svn: 51350
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index b8b64951668..c35bc49e512 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -2085,7 +2085,7 @@ unsigned InstCombiner::ComputeNumSignBits(Value *V, unsigned Depth) const{
case Instruction::AShr:
Tmp = ComputeNumSignBits(U->getOperand(0), Depth+1);
- // SRA X, C -> adds C sign bits.
+ // ashr X, C -> adds C sign bits.
if (ConstantInt *C = dyn_cast<ConstantInt>(U->getOperand(1))) {
Tmp += C->getZExtValue();
if (Tmp > TyBits) Tmp = TyBits;
@@ -8195,6 +8195,33 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
}
}
}
+
+ // See if the value being truncated is already sign extended. If so, just
+ // eliminate the trunc/sext pair.
+ if (getOpcode(Src) == Instruction::Trunc) {
+ Value *Op = cast<User>(Src)->getOperand(0);
+ unsigned OpBits = cast<IntegerType>(Op->getType())->getBitWidth();
+ unsigned MidBits = cast<IntegerType>(Src->getType())->getBitWidth();
+ unsigned DestBits = cast<IntegerType>(CI.getType())->getBitWidth();
+ unsigned NumSignBits = ComputeNumSignBits(Op);
+
+ if (OpBits == DestBits) {
+ // Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
+ // bits, it is already ready.
+ if (NumSignBits > DestBits-MidBits)
+ return ReplaceInstUsesWith(CI, Op);
+ } else if (OpBits < DestBits) {
+ // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
+ // bits, just sext from i32.
+ if (NumSignBits > OpBits-MidBits)
+ return new SExtInst(Op, CI.getType(), "tmp");
+ } else {
+ // Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
+ // bits, just truncate to i32.
+ if (NumSignBits > OpBits-MidBits)
+ return new TruncInst(Op, CI.getType(), "tmp");
+ }
+ }
return 0;
}
OpenPOWER on IntegriCloud