[InstCombine] add one-use check to prevent creating an instruction in shuffle-of...
authorSanjay Patel <spatel@rotateright.com>
Thu, 23 Feb 2023 00:10:12 +0000 (19:10 -0500)
committerSanjay Patel <spatel@rotateright.com>
Thu, 23 Feb 2023 00:20:32 +0000 (19:20 -0500)
This fold was added with https://reviews.llvm.org/D135876 ,
but we missed the one-use check.

This might be the root cause for issue #60632.

llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
llvm/test/Transforms/InstCombine/shuffle-binop.ll

index 3ad6b87..ea9aba4 100644 (file)
@@ -2718,7 +2718,8 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) {
 // splatting the first element of the result of the BinOp
 Instruction *InstCombinerImpl::simplifyBinOpSplats(ShuffleVectorInst &SVI) {
   if (!match(SVI.getOperand(1), m_Undef()) ||
-      !match(SVI.getShuffleMask(), m_ZeroMask()))
+      !match(SVI.getShuffleMask(), m_ZeroMask()) ||
+      !SVI.getOperand(0)->hasOneUse())
     return nullptr;
 
   Value *Op0 = SVI.getOperand(0);
index 74aa70c..b298471 100644 (file)
@@ -201,12 +201,13 @@ define <2 x double> @shuffle_op2_0th_element_mask(ptr %a, ptr %b) {
   ret <2 x double> %shuffle
 }
 
+; This should not create an extra binop.
+
 define <2 x i4> @splat_binop_splat_uses(<2 x i4> %x, <2 x i4> %y) {
 ; CHECK-LABEL: @splat_binop_splat_uses(
 ; CHECK-NEXT:    [[XSPLAT:%.*]] = shufflevector <2 x i4> [[X:%.*]], <2 x i4> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    [[XY:%.*]] = mul <2 x i4> [[XSPLAT]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i4> [[X]], [[Y]]
-; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i4> [[TMP1]], <2 x i4> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i4> [[XY]], <2 x i4> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    [[RES:%.*]] = add <2 x i4> [[XY]], [[MSPLAT]]
 ; CHECK-NEXT:    ret <2 x i4> [[RES]]
 ;