Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3416,7 +3416,10 @@ 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; Index: lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSelect.cpp +++ lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -553,8 +553,11 @@ } } + // 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; Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -1742,3 +1742,26 @@ %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 +} + Index: test/Transforms/InstSimplify/select.ll =================================================================== --- test/Transforms/InstSimplify/select.ll +++ test/Transforms/InstSimplify/select.ll @@ -119,6 +119,17 @@ 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