diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3569,10 +3569,10 @@ if (Instruction *Xor = visitMaskedMerge(I, Builder)) return Xor; - // Use DeMorgan and reassociation to eliminate a 'not' op. Value *X, *Y; Constant *C1; if (match(Op1, m_Constant(C1))) { + // Use DeMorgan and reassociation to eliminate a 'not' op. Constant *C2; if (match(Op0, m_OneUse(m_Or(m_Not(m_Value(X)), m_Constant(C2))))) { // (~X | C2) ^ C1 --> ((X & ~C2) ^ -1) ^ C1 --> (X & ~C2) ^ ~C1 @@ -3584,6 +3584,21 @@ Value *Or = Builder.CreateOr(X, ConstantExpr::getNot(C2)); return BinaryOperator::CreateXor(Or, ConstantExpr::getNot(C1)); } + + // Convert xor ([trunc] (ashr X, BW-1)), C => + // select(X >s -1, C, ~C) + // The ashr creates "AllZeroOrAllOne's", which then optionally inverses the + // constant depending on whether this input is less than 0. + const APInt *CA; + if (match(Op0, m_OneUse(m_TruncOrSelf( + m_AShr(m_Value(X), m_APIntAllowUndef(CA))))) && + *CA == X->getType()->getScalarSizeInBits() - 1 && + !C1->isAllOnesValue()) { + assert(!C1->isZeroValue() && "Unexpected xor with 0"); + Value *ICmp = + Builder.CreateICmpSGT(X, Constant::getAllOnesValue(X->getType())); + return SelectInst::Create(ICmp, Op1, Builder.CreateNot(Op1)); + } } Type *Ty = I.getType(); diff --git a/llvm/test/Transforms/InstCombine/truncating-saturate.ll b/llvm/test/Transforms/InstCombine/truncating-saturate.ll --- a/llvm/test/Transforms/InstCombine/truncating-saturate.ll +++ b/llvm/test/Transforms/InstCombine/truncating-saturate.ll @@ -13,9 +13,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -38,9 +37,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: ret i32 [[COND_I]] ; @@ -155,9 +153,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: ret i32 [[COND_I]] ; @@ -183,9 +180,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc <4 x i16> [[ADD]] to <4 x i8> ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr <4 x i8> [[CONV1_I]], ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq <4 x i8> [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr <4 x i16> [[ADD]], -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc <4 x i16> [[SHR4_I]] to <4 x i8> -; CHECK-NEXT: [[XOR_I:%.*]] = xor <4 x i8> [[CONV5_I]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD]], +; CHECK-NEXT: [[XOR_I:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> , <4 x i8> ; CHECK-NEXT: [[COND_I:%.*]] = select <4 x i1> [[CMP_NOT_I]], <4 x i8> [[CONV1_I]], <4 x i8> [[XOR_I]] ; CHECK-NEXT: ret <4 x i8> [[COND_I]] ; @@ -211,9 +207,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc <4 x i16> [[ADD]] to <4 x i8> ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr <4 x i8> [[CONV1_I]], ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq <4 x i8> [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr <4 x i16> [[ADD]], -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc <4 x i16> [[SHR4_I]] to <4 x i8> -; CHECK-NEXT: [[XOR_I:%.*]] = xor <4 x i8> [[CONV5_I]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD]], +; CHECK-NEXT: [[XOR_I:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> , <4 x i8> ; CHECK-NEXT: [[COND_I:%.*]] = select <4 x i1> [[CMP_NOT_I]], <4 x i8> [[CONV1_I]], <4 x i8> [[XOR_I]] ; CHECK-NEXT: ret <4 x i8> [[COND_I]] ; @@ -239,9 +234,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -264,9 +258,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7 ; CHECK-NEXT: [[CMP_NOT_I_NOT:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I_NOT]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -332,9 +325,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -357,9 +349,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 6 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -407,9 +398,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i16 [[ADD]], 15 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 126 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i8 126, i8 -127 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]] ; CHECK-NEXT: ret i8 [[COND_I]] ; @@ -434,9 +424,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: call void @use(i32 [[XOR_I]]) ; CHECK-NEXT: ret i32 [[COND_I]] @@ -461,9 +450,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: call void @use(i32 [[CONV1_I]]) ; CHECK-NEXT: ret i32 [[COND_I]] @@ -488,9 +476,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: call void @use1(i1 [[CMP_NOT_I]]) ; CHECK-NEXT: ret i32 [[COND_I]] @@ -515,9 +502,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: call void @use(i32 [[XOR_I]]) ; CHECK-NEXT: call void @use(i32 [[CONV1_I]]) @@ -544,9 +530,8 @@ ; CHECK-NEXT: [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32 ; CHECK-NEXT: [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]] -; CHECK-NEXT: [[SHR4_I:%.*]] = ashr i64 [[ADD]], 63 -; CHECK-NEXT: [[CONV5_I:%.*]] = trunc i64 [[SHR4_I]] to i32 -; CHECK-NEXT: [[XOR_I:%.*]] = xor i32 [[CONV5_I]], 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1 +; CHECK-NEXT: [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]] ; CHECK-NEXT: call void @use(i32 [[XOR_I]]) ; CHECK-NEXT: call void @use(i32 [[CONV1_I]]) diff --git a/llvm/test/Transforms/InstCombine/xor-ashr.ll b/llvm/test/Transforms/InstCombine/xor-ashr.ll --- a/llvm/test/Transforms/InstCombine/xor-ashr.ll +++ b/llvm/test/Transforms/InstCombine/xor-ashr.ll @@ -7,8 +7,8 @@ define i8 @testi8i8(i8 %add) { ; CHECK-LABEL: @testi8i8( -; CHECK-NEXT: [[SH:%.*]] = ashr i8 [[ADD:%.*]], 7 -; CHECK-NEXT: [[X:%.*]] = xor i8 [[SH]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[ADD:%.*]], -1 +; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], i8 127, i8 -128 ; CHECK-NEXT: ret i8 [[X]] ; %sh = ashr i8 %add, 7 @@ -18,9 +18,8 @@ define i8 @testi16i8(i16 %add) { ; CHECK-LABEL: @testi16i8( -; CHECK-NEXT: [[SH:%.*]] = ashr i16 [[ADD:%.*]], 15 -; CHECK-NEXT: [[T:%.*]] = trunc i16 [[SH]] to i8 -; CHECK-NEXT: [[X:%.*]] = xor i8 [[T]], 27 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[ADD:%.*]], -1 +; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], i8 27, i8 -28 ; CHECK-NEXT: ret i8 [[X]] ; %sh = ashr i16 %add, 15 @@ -31,9 +30,8 @@ define i32 @testi64i32(i64 %add) { ; CHECK-LABEL: @testi64i32( -; CHECK-NEXT: [[SH:%.*]] = ashr i64 [[ADD:%.*]], 63 -; CHECK-NEXT: [[T:%.*]] = trunc i64 [[SH]] to i32 -; CHECK-NEXT: [[X:%.*]] = xor i32 [[T]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[ADD:%.*]], -1 +; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], i32 127, i32 -128 ; CHECK-NEXT: ret i32 [[X]] ; %sh = ashr i64 %add, 63 @@ -44,8 +42,8 @@ define i128 @testi128i128(i128 %add) { ; CHECK-LABEL: @testi128i128( -; CHECK-NEXT: [[SH:%.*]] = ashr i128 [[ADD:%.*]], 127 -; CHECK-NEXT: [[X:%.*]] = xor i128 [[SH]], 27 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i128 [[ADD:%.*]], -1 +; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], i128 27, i128 -28 ; CHECK-NEXT: ret i128 [[X]] ; %sh = ashr i128 %add, 127 @@ -55,9 +53,8 @@ define <4 x i8> @testv4i16i8(<4 x i16> %add) { ; CHECK-LABEL: @testv4i16i8( -; CHECK-NEXT: [[SH:%.*]] = ashr <4 x i16> [[ADD:%.*]], -; CHECK-NEXT: [[T:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8> -; CHECK-NEXT: [[X:%.*]] = xor <4 x i8> [[T]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD:%.*]], +; CHECK-NEXT: [[X:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> , <4 x i8> ; CHECK-NEXT: ret <4 x i8> [[X]] ; %sh = ashr <4 x i16> %add, @@ -68,9 +65,8 @@ define <4 x i8> @testv4i16i8_undef(<4 x i16> %add) { ; CHECK-LABEL: @testv4i16i8_undef( -; CHECK-NEXT: [[SH:%.*]] = ashr <4 x i16> [[ADD:%.*]], -; CHECK-NEXT: [[T:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8> -; CHECK-NEXT: [[X:%.*]] = xor <4 x i8> [[T]], +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD:%.*]], +; CHECK-NEXT: [[X:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> , <4 x i8> ; CHECK-NEXT: ret <4 x i8> [[X]] ; %sh = ashr <4 x i16> %add, @@ -112,9 +108,9 @@ define i16 @extrause_trunc1(i32 %add) { ; CHECK-LABEL: @extrause_trunc1( ; CHECK-NEXT: [[SH:%.*]] = ashr i32 [[ADD:%.*]], 31 -; CHECK-NEXT: [[T:%.*]] = trunc i32 [[SH]] to i16 ; CHECK-NEXT: call void @use32(i32 [[SH]]) -; CHECK-NEXT: [[X:%.*]] = xor i16 [[T]], 127 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[ADD]], -1 +; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], i16 127, i16 -128 ; CHECK-NEXT: ret i16 [[X]] ; %sh = ashr i32 %add, 31