From 468f6700218afd39c932e71a83786215930d5a77 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 6 Jun 2015 02:30:43 +0000 Subject: [PATCH] [InstCombine] Don't miscompile select to poison If we have (select a, b, c), it is sometimes valid to simplify this to a single select operand. However, doing so is only valid if the computation doesn't inject poison into the computation. It might be helpful to consider the following example: (select (icmp ne %i, INT_MAX), (add nsw %i, 1), INT_MIN) The select is equivalent to (add %i, 1) but not (add nsw %i, 1). Self hosting on x86_64 revealed that this occurs very, very rarely so bailing out is hopefully pretty reasonable. llvm-svn: 239215 --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 13 +++++++++++++ llvm/test/Transforms/InstCombine/select.ll | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index d2fbcdd..9a50e74 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -292,6 +292,19 @@ static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, // If this is a binary operator, try to simplify it with the replaced op. if (BinaryOperator *B = dyn_cast(I)) { + // Consider: + // %cmp = icmp eq i32 %x, 2147483647 + // %add = add nsw i32 %x, 1 + // %sel = select i1 %cmp, i32 -2147483648, i32 %add + // + // We can't replace %sel with %add unless we strip away the flags. + if (isa(B)) + if (B->hasNoSignedWrap() || B->hasNoUnsignedWrap()) + return nullptr; + if (isa(B)) + if (B->isExact()) + return nullptr; + if (B->getOperand(0) == Op) return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), DL, TLI); if (B->getOperand(1) == Op) diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index e4bc96c..27e487b 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -1532,3 +1532,16 @@ define i32 @test_max_of_min(i32 %a) { %s1 = select i1 %c1, i32 %s0, i32 -1 ret i32 %s1 } + + +define i32 @PR23757(i32 %x) { +; CHECK-LABEL: @PR23757 +; CHECK: %[[cmp:.*]] = icmp eq i32 %x, 2147483647 +; CHECK-NEXT: %[[add:.*]] = add nsw i32 %x, 1 +; CHECK-NEXT: %[[sel:.*]] = select i1 %[[cmp]], i32 -2147483648, i32 %[[add]] +; CHECK-NEXT: ret i32 %[[sel]] + %cmp = icmp eq i32 %x, 2147483647 + %add = add nsw i32 %x, 1 + %sel = select i1 %cmp, i32 -2147483648, i32 %add + ret i32 %sel +} -- 2.7.4