[llvm] [InstCombine] Do not perform binop-of-shuffle when mask is poison (PR #82185)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 18 12:12:43 PST 2024


https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/82185

>From 1238a5a34ba869b9eac06c03f5a69ee09c9f6da6 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sun, 18 Feb 2024 18:10:41 +0100
Subject: [PATCH 1/2] =?UTF-8?q?[InstCombine]=C2=A0Precommit=20tests=20for?=
 =?UTF-8?q?=20PR82185=20(NFC)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../InstCombine/vec_demanded_elts.ll          | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
index 4e5fdbb1eab991..8ca30322bd0338 100644
--- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -1159,3 +1159,52 @@ define i4 @common_binop_demand_via_extelt_op0_mismatch_elt1(<2 x i4> %x, <2 x i4
   call void @use(<2 x i4> %b_xshuf_y)
   ret i4 %b_xy0
 }
+
+define <2 x i8> @common_binop_demand_via_splat_mask_poison(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison(
+; CHECK-NEXT:    [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 0, i32 poison>
+; CHECK-NEXT:    [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
+; CHECK-NEXT:    ret <2 x i8> [[RES]]
+;
+  %ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 0, i32 poison>                       ; <y0, poison>
+  %vv = add <2 x i8> %x, %ysplat                                                                            ; <x0+y0, poison>
+  %m = add <2 x i8> %x, %y                                                                                  ; <x0+y0, x1+y1>
+  %msplat = shufflevector <2 x i8> %m, <2 x i8> poison, <2 x i32> <i32 0, i32 0>      ; LeftDemanded = 1    ; <x0+y0, x0+y0>
+  %res = add <2 x i8> %vv, %msplat                                                                          ; <x0+y0+x0+y0, poison>
+  ret <2 x i8> %res
+}
+
+define <2 x i8> @common_binop_demand_via_splat_mask_poison_2(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_2(
+; CHECK-NEXT:    [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
+; CHECK-NEXT:    [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> [[Y]], <2 x i32> <i32 0, i32 2>
+; CHECK-NEXT:    [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
+; CHECK-NEXT:    ret <2 x i8> [[RES]]
+;
+  %ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
+  %vv = add <2 x i8> %x, %ysplat
+  %m = add <2 x i8> %x, %y
+  %msplat = shufflevector <2 x i8> %m, <2 x i8> %y, <2 x i32> <i32 0, i32 2>           ; LeftDemanded = 1, RightDemanded = 1
+  %res = add <2 x i8> %vv, %msplat
+  ret <2 x i8> %res
+}
+
+; FIXME: This is a miscompilation.
+define <2 x i8> @common_binop_demand_via_splat_mask_poison_3(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_3(
+; CHECK-NEXT:    [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
+; CHECK-NEXT:    [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
+; CHECK-NEXT:    ret <2 x i8> [[RES]]
+;
+  %ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
+  %vv = add <2 x i8> %x, %ysplat
+  %m = add <2 x i8> %x, %y
+  %msplat = shufflevector <2 x i8> %m, <2 x i8> poison, <2 x i32> <i32 0, i32 0>       ; LeftDemanded = 1
+  %res = add <2 x i8> %vv, %msplat
+  ret <2 x i8> %res
+}

>From 38910f09db1c737b4afc64e19023ca876ce86052 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sun, 18 Feb 2024 18:25:12 +0100
Subject: [PATCH 2/2] [InstCombine] Do not perform binop-of-shuffle when mask
 is poison

A miscompilation issue has been addressed with refined checking.
Shuffle masks operand may be turn into `poison` if this does not
lead to observable changes. This however may not guarantee binop
to binop-of-shuffle replacement to be sound anymore.

Fixes: https://github.com/llvm/llvm-project/issues/82052.
---
 .../InstCombine/InstCombineSimplifyDemanded.cpp           | 8 +++++---
 llvm/test/Transforms/InstCombine/vec_demanded_elts.ll     | 7 ++++---
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 5f13454089e515..97ae980a7cba70 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1870,14 +1870,16 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
         Value *ShufOp = MatchShufAsOp0 ? X : Y;
         Value *OtherOp = MatchShufAsOp0 ? Y : X;
         for (User *U : OtherOp->users()) {
-          auto Shuf = m_Shuffle(m_Specific(ShufOp), m_Value(), m_ZeroMask());
+          ArrayRef<int> Mask;
+          auto Shuf = m_Shuffle(m_Specific(ShufOp), m_Value(), m_Mask(Mask));
           if (BO->isCommutative()
                   ? match(U, m_c_BinOp(Opcode, Shuf, m_Specific(OtherOp)))
                   : MatchShufAsOp0
                         ? match(U, m_BinOp(Opcode, Shuf, m_Specific(OtherOp)))
                         : match(U, m_BinOp(Opcode, m_Specific(OtherOp), Shuf)))
-            if (DT.dominates(U, I))
-              return U;
+            if (match(Mask, m_ZeroMask()) && Mask[0] != PoisonMaskElem)
+              if (DT.dominates(U, I))
+                return U;
         }
         return nullptr;
       };
diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
index 8ca30322bd0338..fd55a236e0d751 100644
--- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -1180,7 +1180,8 @@ define <2 x i8> @common_binop_demand_via_splat_mask_poison_2(<2 x i8> %x, <2 x i
 ; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_2(
 ; CHECK-NEXT:    [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
 ; CHECK-NEXT:    [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
-; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> [[Y]], <2 x i32> <i32 0, i32 2>
+; CHECK-NEXT:    [[M:%.*]] = add <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[M]], <2 x i8> [[Y]], <2 x i32> <i32 0, i32 2>
 ; CHECK-NEXT:    [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
 ; CHECK-NEXT:    ret <2 x i8> [[RES]]
 ;
@@ -1192,12 +1193,12 @@ define <2 x i8> @common_binop_demand_via_splat_mask_poison_2(<2 x i8> %x, <2 x i
   ret <2 x i8> %res
 }
 
-; FIXME: This is a miscompilation.
 define <2 x i8> @common_binop_demand_via_splat_mask_poison_3(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_3(
 ; CHECK-NEXT:    [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
 ; CHECK-NEXT:    [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
-; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[M:%.*]] = add <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[MSPLAT:%.*]] = shufflevector <2 x i8> [[M]], <2 x i8> poison, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
 ; CHECK-NEXT:    ret <2 x i8> [[RES]]
 ;



More information about the llvm-commits mailing list