From 54664ed71444698e3f24ee372c3d9da42a1133c2 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 1 Jul 2011 01:03:43 +0000 Subject: [PATCH] Improve constant folding of undef for cmp and select operators. llvm-svn: 134223 --- llvm/lib/Analysis/InstructionSimplify.cpp | 8 +++--- llvm/lib/VMCore/ConstantFold.cpp | 9 ++++-- .../InstSimplify/{binop.ll => undef.ll} | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) rename llvm/test/Transforms/InstSimplify/{binop.ll => undef.ll} (75%) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 9d78f8bf4044..8709f6bf9d26 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/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/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp index 8cca06fdda04..b7a1350ff5ad 100644 --- a/llvm/lib/VMCore/ConstantFold.cpp +++ b/llvm/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/llvm/test/Transforms/InstSimplify/binop.ll b/llvm/test/Transforms/InstSimplify/undef.ll similarity index 75% rename from llvm/test/Transforms/InstSimplify/binop.ll rename to llvm/test/Transforms/InstSimplify/undef.ll index f4bc55753a58..8134cc848749 100644 --- a/llvm/test/Transforms/InstSimplify/binop.ll +++ b/llvm/test/Transforms/InstSimplify/undef.ll @@ -97,3 +97,31 @@ 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 +}