diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/vec_shuffle.ll | 6 |
2 files changed, 8 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index c28c5138dab..5f0aeb5cc5a 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1418,14 +1418,11 @@ Instruction *InstCombiner::foldShuffledBinop(BinaryOperator &Inst) { } if (MayChange) { Constant *NewC = ConstantVector::get(NewVecC); - // With integer div/rem instructions, it is not safe to use a vector with - // undef elements because the entire instruction can be folded to undef. - // All other binop opcodes are always safe to speculate, and therefore, it - // is fine to include undef elements for unused lanes (and using undefs - // may help optimization). - // FIXME: This transform is also not poison-safe. Eg, shift-by-undef would - // create poison that may not exist in the original code. - if (Inst.isIntDivRem()) + // It may not be safe to execute a binop on a vector with undef elements + // because the entire instruction can be folded to undef or create poison + // that did not exist in the original code. + if (Inst.isIntDivRem() || + (Inst.isShift() && isa<Constant>(Inst.getOperand(1)))) NewC = getSafeVectorConstantForBinop(Inst.getOpcode(), NewC); // Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask) diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index 7e863fd2813..d1a42882eaa 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -654,7 +654,7 @@ define <2 x i32> @shl_splat_constant0(<2 x i32> %x) { define <2 x i32> @shl_splat_constant1(<2 x i32> %x) { ; CHECK-LABEL: @shl_splat_constant1( -; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 undef> +; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 0> ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x i32> [[R]] ; @@ -676,7 +676,7 @@ define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) { define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) { ; CHECK-LABEL: @ashr_splat_constant1( -; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 undef> +; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 0> ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x i32> [[R]] ; @@ -698,7 +698,7 @@ define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) { define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) { ; CHECK-LABEL: @lshr_splat_constant1( -; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 undef> +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 0> ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x i32> [[R]] ; |

