From 5f3c70307d7e195b802048a04e8c33c8b2ff6a50 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 20 Jul 2016 23:40:01 +0000 Subject: [PATCH] [InstSimplify][InstCombine] don't crash when folding vector selects of icmp Differential Revision: https://reviews.llvm.org/D22602 llvm-svn: 276209 --- llvm/lib/Analysis/InstructionSimplify.cpp | 5 ++++- .../Transforms/InstCombine/InstCombineSelect.cpp | 5 ++++- llvm/test/Transforms/InstCombine/select.ll | 23 ++++++++++++++++++++++ llvm/test/Transforms/InstSimplify/select.ll | 11 +++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 9eefc99..45d4f14 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3416,7 +3416,10 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)))) return nullptr; - unsigned BitWidth = Q.DL.getTypeSizeInBits(TrueVal->getType()); + // FIXME: This code is nearly duplicated in InstCombine. Using/refactoring + // decomposeBitTestICmp() might help. + unsigned BitWidth = + Q.DL.getTypeSizeInBits(TrueVal->getType()->getScalarType()); APInt MinSignedValue = APInt::getSignBit(BitWidth); if (ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero())) { Value *X; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index d7eed79..8f1ff8a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -553,8 +553,11 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI, } } + // FIXME: This code is nearly duplicated in InstSimplify. Using/refactoring + // decomposeBitTestICmp() might help. { - unsigned BitWidth = DL.getTypeSizeInBits(TrueVal->getType()); + unsigned BitWidth = + DL.getTypeSizeInBits(TrueVal->getType()->getScalarType()); APInt MinSignedValue = APInt::getSignBit(BitWidth); Value *X; const APInt *Y, *C; diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index 079e5fb..4b9f690 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -1742,3 +1742,26 @@ define i32 @PR27137(i32 %a) { %s1 = select i1 %c1, i32 %s0, i32 -1 ret i32 %s1 } + +define i32 @select_icmp_slt0_xor(i32 %x) { +; CHECK-LABEL: @select_icmp_slt0_xor( +; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, -2147483648 +; CHECK-NEXT: ret i32 [[TMP1]] +; + %cmp = icmp slt i32 %x, zeroinitializer + %xor = xor i32 %x, 2147483648 + %x.xor = select i1 %cmp, i32 %x, i32 %xor + ret i32 %x.xor +} + +define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) { +; CHECK-LABEL: @select_icmp_slt0_xor_vec( +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> %x, +; CHECK-NEXT: ret <2 x i32> [[TMP1]] +; + %cmp = icmp slt <2 x i32> %x, zeroinitializer + %xor = xor <2 x i32> %x, + %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor + ret <2 x i32> %x.xor +} + diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll index adc9392..4500662 100644 --- a/llvm/test/Transforms/InstSimplify/select.ll +++ b/llvm/test/Transforms/InstSimplify/select.ll @@ -119,6 +119,17 @@ define i32 @test11(i32 %X) { ret i32 %cond } +define <2 x i8> @test11vec(<2 x i8> %X) { +; CHECK-LABEL: @test11vec( +; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> %X, +; CHECK-NEXT: ret <2 x i8> [[AND]] +; + %cmp = icmp sgt <2 x i8> %X, + %and = and <2 x i8> %X, + %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and + ret <2 x i8> %sel +} + define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { ; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8 -- 2.7.4