diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-11-15 19:12:01 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-11-15 19:12:01 +0000 |
| commit | 03d0cd6a81db286369eb55b31e9279dc9d3d7f56 (patch) | |
| tree | 180663b70ea881600a630c61c7202f7c6fad1a86 | |
| parent | a17fca06ee312baac84c39204982327f6f75ac83 (diff) | |
| download | bcm5719-llvm-03d0cd6a81db286369eb55b31e9279dc9d3d7f56.tar.gz bcm5719-llvm-03d0cd6a81db286369eb55b31e9279dc9d3d7f56.zip | |
[InstCombine] trunc (binop X, C) --> binop (trunc X, C')
Note that one-use and shouldChangeType() are checked ahead of the switch.
Without the narrowing folds, we can produce inferior vector code as shown in PR35299:
https://bugs.llvm.org/show_bug.cgi?id=35299
llvm-svn: 318323
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 21 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/pr33765.ll | 5 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/trunc-binop-ext.ll | 102 |
3 files changed, 60 insertions, 68 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 5e4fd8c2656..c2fe661c467 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -545,6 +545,8 @@ Instruction *InstCombiner::narrowBinOp(TruncInst &Trunc) { if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(BinOp)))) return nullptr; + Value *BinOp0 = BinOp->getOperand(0); + Value *BinOp1 = BinOp->getOperand(1); switch (BinOp->getOpcode()) { case Instruction::And: case Instruction::Or: @@ -552,20 +554,31 @@ Instruction *InstCombiner::narrowBinOp(TruncInst &Trunc) { case Instruction::Add: case Instruction::Mul: { Constant *C; - if (match(BinOp->getOperand(1), m_Constant(C))) { + if (match(BinOp1, m_Constant(C))) { // trunc (binop X, C) --> binop (trunc X, C') Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(0), DestTy); + Value *TruncX = Builder.CreateTrunc(BinOp0, DestTy); return BinaryOperator::Create(BinOp->getOpcode(), TruncX, NarrowC); } + Value *X; + if (match(BinOp0, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) { + // trunc (binop (ext X), Y) --> binop X, (trunc Y) + Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy); + return BinaryOperator::Create(BinOp->getOpcode(), X, NarrowOp1); + } + if (match(BinOp1, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) { + // trunc (binop Y, (ext X)) --> binop (trunc Y), X + Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy); + return BinaryOperator::Create(BinOp->getOpcode(), NarrowOp0, X); + } break; } case Instruction::Sub: { Constant *C; - if (match(BinOp->getOperand(0), m_Constant(C))) { + if (match(BinOp0, m_Constant(C))) { // trunc (binop C, X) --> binop (trunc C', X) Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(1), DestTy); + Value *TruncX = Builder.CreateTrunc(BinOp1, DestTy); return BinaryOperator::Create(BinOp->getOpcode(), NarrowC, TruncX); } break; diff --git a/llvm/test/Transforms/InstCombine/pr33765.ll b/llvm/test/Transforms/InstCombine/pr33765.ll index 5aa99bbf7cb..0b29d67d056 100644 --- a/llvm/test/Transforms/InstCombine/pr33765.ll +++ b/llvm/test/Transforms/InstCombine/pr33765.ll @@ -10,9 +10,8 @@ define void @patatino(i8 %beth) { ; CHECK: if.then9: ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[CONV]], [[CONV]] ; CHECK-NEXT: [[TINKY:%.*]] = load i16, i16* @glob, align 2 -; CHECK-NEXT: [[CONV131:%.*]] = zext i16 [[TINKY]] to i32 -; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], [[CONV131]] -; CHECK-NEXT: [[CONV14:%.*]] = trunc i32 [[AND]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[MUL]] to i16 +; CHECK-NEXT: [[CONV14:%.*]] = and i16 [[TINKY]], [[TMP1]] ; CHECK-NEXT: store i16 [[CONV14]], i16* @glob, align 2 ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/InstCombine/trunc-binop-ext.ll b/llvm/test/Transforms/InstCombine/trunc-binop-ext.ll index bbd2357f1a7..59336425d5f 100644 --- a/llvm/test/Transforms/InstCombine/trunc-binop-ext.ll +++ b/llvm/test/Transforms/InstCombine/trunc-binop-ext.ll @@ -2,9 +2,8 @@ define i16 @narrow_sext_and(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_sext_and( -; CHECK-NEXT: [[X321:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = and i32 [[X321]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = and i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = sext i16 %x16 to i32 @@ -15,9 +14,8 @@ define i16 @narrow_sext_and(i16 %x16, i32 %y32) { define i16 @narrow_zext_and(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_zext_and( -; CHECK-NEXT: [[X32:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = and i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = and i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = zext i16 %x16 to i32 @@ -28,9 +26,8 @@ define i16 @narrow_zext_and(i16 %x16, i32 %y32) { define i16 @narrow_sext_or(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_sext_or( -; CHECK-NEXT: [[X321:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = or i32 [[X321]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = or i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = sext i16 %x16 to i32 @@ -41,9 +38,8 @@ define i16 @narrow_sext_or(i16 %x16, i32 %y32) { define i16 @narrow_zext_or(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_zext_or( -; CHECK-NEXT: [[X32:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = or i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = or i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = zext i16 %x16 to i32 @@ -54,9 +50,8 @@ define i16 @narrow_zext_or(i16 %x16, i32 %y32) { define i16 @narrow_sext_xor(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_sext_xor( -; CHECK-NEXT: [[X321:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = xor i32 [[X321]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = xor i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = sext i16 %x16 to i32 @@ -67,9 +62,8 @@ define i16 @narrow_sext_xor(i16 %x16, i32 %y32) { define i16 @narrow_zext_xor(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_zext_xor( -; CHECK-NEXT: [[X32:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = xor i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = xor i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = zext i16 %x16 to i32 @@ -80,9 +74,8 @@ define i16 @narrow_zext_xor(i16 %x16, i32 %y32) { define i16 @narrow_sext_add(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_sext_add( -; CHECK-NEXT: [[X321:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = add i32 [[X321]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = add i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = sext i16 %x16 to i32 @@ -93,9 +86,8 @@ define i16 @narrow_sext_add(i16 %x16, i32 %y32) { define i16 @narrow_zext_add(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_zext_add( -; CHECK-NEXT: [[X32:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = add i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = add i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = zext i16 %x16 to i32 @@ -106,9 +98,8 @@ define i16 @narrow_zext_add(i16 %x16, i32 %y32) { define i16 @narrow_sext_mul(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_sext_mul( -; CHECK-NEXT: [[X32:%.*]] = sext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = mul i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = mul i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = sext i16 %x16 to i32 @@ -119,9 +110,8 @@ define i16 @narrow_sext_mul(i16 %x16, i32 %y32) { define i16 @narrow_zext_mul(i16 %x16, i32 %y32) { ; CHECK-LABEL: @narrow_zext_mul( -; CHECK-NEXT: [[X32:%.*]] = zext i16 %x16 to i32 -; CHECK-NEXT: [[B:%.*]] = mul i32 [[X32]], %y32 -; CHECK-NEXT: [[R:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 %y32 to i16 +; CHECK-NEXT: [[R:%.*]] = mul i16 [[TMP1]], %x16 ; CHECK-NEXT: ret i16 [[R]] ; %x32 = zext i16 %x16 to i32 @@ -130,15 +120,14 @@ define i16 @narrow_zext_mul(i16 %x16, i32 %y32) { ret i16 %r } -; Verify that the commuted patterns work. The div is to ensure that complexity-based +; Verify that the commuted patterns work. The div is to ensure that complexity-based ; canonicalization doesn't swap the binop operands. Use vector types to show those work too. define <2 x i16> @narrow_sext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_and_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[Y32OP0]], [[X321]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -151,9 +140,8 @@ define <2 x i16> @narrow_sext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_zext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_and_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -166,9 +154,8 @@ define <2 x i16> @narrow_zext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_sext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_or_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[Y32OP0]], [[X321]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -181,9 +168,8 @@ define <2 x i16> @narrow_sext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_zext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_or_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -196,9 +182,8 @@ define <2 x i16> @narrow_zext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_sext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_xor_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i32> [[Y32OP0]], [[X321]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -211,9 +196,8 @@ define <2 x i16> @narrow_sext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_zext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_xor_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -226,9 +210,8 @@ define <2 x i16> @narrow_zext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_sext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_add_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = add <2 x i32> [[Y32OP0]], [[X321]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = add <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -241,9 +224,8 @@ define <2 x i16> @narrow_sext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_zext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_add_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = add <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = add <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -256,9 +238,8 @@ define <2 x i16> @narrow_zext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_sext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_mul_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = sext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = mul <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> @@ -271,9 +252,8 @@ define <2 x i16> @narrow_sext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) { define <2 x i16> @narrow_zext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_mul_commute( ; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17> -; CHECK-NEXT: [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32> -; CHECK-NEXT: [[B:%.*]] = mul <2 x i32> [[Y32OP0]], [[X32]] -; CHECK-NEXT: [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> +; CHECK-NEXT: [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17> |

