diff options
author | Dan Gohman <gohman@apple.com> | 2008-05-20 21:01:12 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-05-20 21:01:12 +0000 |
commit | f0f1202b803a92f6caae3eb18ae55f783b1241f8 (patch) | |
tree | fbecf936ca0903b12546e3a54686f96610ba5e32 /lib | |
parent | e47edf956c7dd39240b182f479126c65d2bf2f54 (diff) | |
download | external_llvm-f0f1202b803a92f6caae3eb18ae55f783b1241f8.zip external_llvm-f0f1202b803a92f6caae3eb18ae55f783b1241f8.tar.gz external_llvm-f0f1202b803a92f6caae3eb18ae55f783b1241f8.tar.bz2 |
Port SelectionDAG's ComputeNumSignBits-using code to instcombine,
now that instcombine also has ComputeNumSignBits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51350 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index b8b6495..c35bc49 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/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; } |