From 7dd540ee2469c7c931360ca0aa196d71b54b3e72 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 10 Jan 2010 20:30:41 +0000 Subject: [PATCH] teach sext optimization to handle truncs from types that are not the dest of the sext. llvm-svn: 93128 --- .../InstCombine/InstCombineCasts.cpp | 7 ++--- llvm/test/Transforms/InstCombine/cast.ll | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index e2e74c1e5d54..49b2e22a6815 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -799,6 +799,10 @@ static bool CanEvaluateSExtd(Value *V, const Type *Ty, TargetData *TD) { if (!I->hasOneUse()) return false; switch (I->getOpcode()) { + case Instruction::SExt: // sext(sext(x)) -> sext(x) + case Instruction::ZExt: // sext(zext(x)) -> zext(x) + case Instruction::Trunc: // sext(trunc(x)) -> trunc(x) or sext(x) + return true; case Instruction::And: case Instruction::Or: case Instruction::Xor: @@ -813,9 +817,6 @@ static bool CanEvaluateSExtd(Value *V, const Type *Ty, TargetData *TD) { //case Instruction::LShr: TODO //case Instruction::Trunc: TODO - case Instruction::SExt: // sext(sext(x)) -> sext(x) - case Instruction::ZExt: // sext(zext(x)) -> zext(x) - return true; case Instruction::Select: return CanEvaluateSExtd(I->getOperand(1), Ty, TD) && CanEvaluateSExtd(I->getOperand(2), Ty, TD); diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll index 8424967e11ab..d624f342b9be 100644 --- a/llvm/test/Transforms/InstCombine/cast.ll +++ b/llvm/test/Transforms/InstCombine/cast.ll @@ -523,3 +523,29 @@ define i64 @test53(i32 %A) { ; CHECK-NEXT: %D = and i64 %C, 40186 ; CHECK-NEXT: ret i64 %D } + +define i32 @test54(i64 %A) { + %B = trunc i64 %A to i16 + %C = or i16 %B, -32574 + %D = and i16 %C, -25350 + %E = sext i16 %D to i32 + ret i32 %E +; CHECK: @test54 +; CHECK-NEXT: %B = trunc i64 %A to i32 +; CHECK-NEXT: %C = or i32 %B, -32574 +; CHECK-NEXT: %D = and i32 %C, -25350 +; CHECK-NEXT: ret i32 %D +} + +define i64 @test55(i32 %A) { + %B = trunc i32 %A to i16 + %C = or i16 %B, -32574 + %D = and i16 %C, -25350 + %E = sext i16 %D to i64 + ret i64 %E +; CHECK: @test55 +; CHECK-NEXT: %B = zext i32 %A to i64 +; CHECK-NEXT: %C = or i64 %B, -32574 +; CHECK-NEXT: %D = and i64 %C, -25350 +; CHECK-NEXT: ret i64 %D +} \ No newline at end of file