From: Dan Gohman Date: Fri, 1 Jul 2011 01:03:43 +0000 (+0000) Subject: Improve constant folding of undef for cmp and select operators. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=68c0dbc14fb7599987fb3e27be4e12c1ac36535e;p=oota-llvm.git Improve constant folding of undef for cmp and select operators. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134223 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 9d78f8bf404..8709f6bf9d2 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -2204,15 +2204,15 @@ Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, if (TrueVal == FalseVal) return TrueVal; - if (isa(TrueVal)) // select C, undef, X -> X - return FalseVal; - if (isa(FalseVal)) // select C, X, undef -> X - return TrueVal; if (isa(CondVal)) { // select undef, X, Y -> X or Y if (isa(TrueVal)) return TrueVal; return FalseVal; } + if (isa(TrueVal)) // select C, undef, X -> X + return FalseVal; + if (isa(FalseVal)) // select C, X, undef -> X + return TrueVal; return 0; } diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 8cca06fdda0..b7a1350ff5a 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -730,9 +730,12 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, } + if (isa(Cond)) { + if (isa(V1)) return V1; + return V2; + } if (isa(V1)) return V2; if (isa(V2)) return V1; - if (isa(Cond)) return V1; if (V1 == V2) return V1; if (ConstantExpr *TrueVal = dyn_cast(V1)) { @@ -1851,7 +1854,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, if (isa(C1) || isa(C2)) { // For EQ and NE, we can always pick a value for the undef to make the // predicate pass or fail, so we can return undef. - if (ICmpInst::isEquality(ICmpInst::Predicate(pred))) + // Also, if both operands are undef, we can return undef. + if (ICmpInst::isEquality(ICmpInst::Predicate(pred)) || + (isa(C1) && isa(C2))) return UndefValue::get(ResultTy); // Otherwise, pick the same value as the non-undef operand, and fold // it to true or false. diff --git a/test/Transforms/InstSimplify/binop.ll b/test/Transforms/InstSimplify/binop.ll deleted file mode 100644 index f4bc55753a5..00000000000 --- a/test/Transforms/InstSimplify/binop.ll +++ /dev/null @@ -1,99 +0,0 @@ -; RUN: opt -instsimplify -S < %s | FileCheck %s - -; @test0 -; CHECK: ret i64 undef -define i64 @test0() { - %r = mul i64 undef, undef - ret i64 %r -} - -; @test1 -; CHECK: ret i64 undef -define i64 @test1() { - %r = mul i64 3, undef - ret i64 %r -} - -; @test2 -; CHECK: ret i64 undef -define i64 @test2() { - %r = mul i64 undef, 3 - ret i64 %r -} - -; @test3 -; CHECK: ret i64 0 -define i64 @test3() { - %r = mul i64 undef, 6 - ret i64 %r -} - -; @test4 -; CHECK: ret i64 0 -define i64 @test4() { - %r = mul i64 6, undef - ret i64 %r -} - -; @test5 -; CHECK: ret i64 undef -define i64 @test5() { - %r = and i64 undef, undef - ret i64 %r -} - -; @test6 -; CHECK: ret i64 undef -define i64 @test6() { - %r = or i64 undef, undef - ret i64 %r -} - -; @test7 -; CHECK: ret i64 undef -define i64 @test7() { - %r = udiv i64 undef, 1 - ret i64 %r -} - -; @test8 -; CHECK: ret i64 undef -define i64 @test8() { - %r = sdiv i64 undef, 1 - ret i64 %r -} - -; @test9 -; CHECK: ret i64 0 -define i64 @test9() { - %r = urem i64 undef, 1 - ret i64 %r -} - -; @test10 -; CHECK: ret i64 0 -define i64 @test10() { - %r = srem i64 undef, 1 - ret i64 %r -} - -; @test11 -; CHECK: ret i64 undef -define i64 @test11() { - %r = shl i64 undef, undef - ret i64 %r -} - -; @test12 -; CHECK: ret i64 undef -define i64 @test12() { - %r = ashr i64 undef, undef - ret i64 %r -} - -; @test13 -; CHECK: ret i64 undef -define i64 @test13() { - %r = lshr i64 undef, undef - ret i64 %r -} diff --git a/test/Transforms/InstSimplify/undef.ll b/test/Transforms/InstSimplify/undef.ll new file mode 100644 index 00000000000..8134cc84874 --- /dev/null +++ b/test/Transforms/InstSimplify/undef.ll @@ -0,0 +1,127 @@ +; RUN: opt -instsimplify -S < %s | FileCheck %s + +; @test0 +; CHECK: ret i64 undef +define i64 @test0() { + %r = mul i64 undef, undef + ret i64 %r +} + +; @test1 +; CHECK: ret i64 undef +define i64 @test1() { + %r = mul i64 3, undef + ret i64 %r +} + +; @test2 +; CHECK: ret i64 undef +define i64 @test2() { + %r = mul i64 undef, 3 + ret i64 %r +} + +; @test3 +; CHECK: ret i64 0 +define i64 @test3() { + %r = mul i64 undef, 6 + ret i64 %r +} + +; @test4 +; CHECK: ret i64 0 +define i64 @test4() { + %r = mul i64 6, undef + ret i64 %r +} + +; @test5 +; CHECK: ret i64 undef +define i64 @test5() { + %r = and i64 undef, undef + ret i64 %r +} + +; @test6 +; CHECK: ret i64 undef +define i64 @test6() { + %r = or i64 undef, undef + ret i64 %r +} + +; @test7 +; CHECK: ret i64 undef +define i64 @test7() { + %r = udiv i64 undef, 1 + ret i64 %r +} + +; @test8 +; CHECK: ret i64 undef +define i64 @test8() { + %r = sdiv i64 undef, 1 + ret i64 %r +} + +; @test9 +; CHECK: ret i64 0 +define i64 @test9() { + %r = urem i64 undef, 1 + ret i64 %r +} + +; @test10 +; CHECK: ret i64 0 +define i64 @test10() { + %r = srem i64 undef, 1 + ret i64 %r +} + +; @test11 +; CHECK: ret i64 undef +define i64 @test11() { + %r = shl i64 undef, undef + ret i64 %r +} + +; @test12 +; CHECK: ret i64 undef +define i64 @test12() { + %r = ashr i64 undef, undef + ret i64 %r +} + +; @test13 +; CHECK: ret i64 undef +define i64 @test13() { + %r = lshr i64 undef, undef + ret i64 %r +} + +; @test14 +; CHECK: ret i1 undef +define i1 @test14() { + %r = icmp slt i64 undef, undef + ret i1 %r +} + +; @test15 +; CHECK: ret i1 undef +define i1 @test15() { + %r = icmp ult i64 undef, undef + ret i1 %r +} + +; @test16 +; CHECK: ret i64 undef +define i64 @test16(i64 %a) { + %r = select i1 undef, i64 %a, i64 undef + ret i64 %r +} + +; @test17 +; CHECK: ret i64 undef +define i64 @test17(i64 %a) { + %r = select i1 undef, i64 undef, i64 %a + ret i64 %r +}