Skip to content

Commit d2a26a7

Browse files
[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 turned 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: #82052.
1 parent a45df47 commit d2a26a7

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,14 +1870,16 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
18701870
Value *ShufOp = MatchShufAsOp0 ? X : Y;
18711871
Value *OtherOp = MatchShufAsOp0 ? Y : X;
18721872
for (User *U : OtherOp->users()) {
1873-
auto Shuf = m_Shuffle(m_Specific(ShufOp), m_Value(), m_ZeroMask());
1873+
ArrayRef<int> Mask;
1874+
auto Shuf = m_Shuffle(m_Specific(ShufOp), m_Value(), m_Mask(Mask));
18741875
if (BO->isCommutative()
18751876
? match(U, m_c_BinOp(Opcode, Shuf, m_Specific(OtherOp)))
18761877
: MatchShufAsOp0
18771878
? match(U, m_BinOp(Opcode, Shuf, m_Specific(OtherOp)))
18781879
: match(U, m_BinOp(Opcode, m_Specific(OtherOp), Shuf)))
1879-
if (DT.dominates(U, I))
1880-
return U;
1880+
if (match(Mask, m_ZeroMask()) && Mask[0] != PoisonMaskElem)
1881+
if (DT.dominates(U, I))
1882+
return U;
18811883
}
18821884
return nullptr;
18831885
};

llvm/test/Transforms/InstCombine/vec_demanded_elts.ll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,3 +1159,53 @@ define i4 @common_binop_demand_via_extelt_op0_mismatch_elt1(<2 x i4> %x, <2 x i4
11591159
call void @use(<2 x i4> %b_xshuf_y)
11601160
ret i4 %b_xy0
11611161
}
1162+
1163+
define <2 x i8> @common_binop_demand_via_splat_mask_poison(<2 x i8> %x, <2 x i8> %y) {
1164+
; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison(
1165+
; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 0, i32 poison>
1166+
; CHECK-NEXT: [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
1167+
; CHECK-NEXT: [[MSPLAT:%.*]] = shufflevector <2 x i8> [[VV]], <2 x i8> poison, <2 x i32> zeroinitializer
1168+
; CHECK-NEXT: [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
1169+
; CHECK-NEXT: ret <2 x i8> [[RES]]
1170+
;
1171+
%ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 0, i32 poison> ; <y0, poison>
1172+
%vv = add <2 x i8> %x, %ysplat ; <x0+y0, poison>
1173+
%m = add <2 x i8> %x, %y ; <x0+y0, x1+y1>
1174+
%msplat = shufflevector <2 x i8> %m, <2 x i8> poison, <2 x i32> <i32 0, i32 0> ; LeftDemanded = 1 ; <x0+y0, x0+y0>
1175+
%res = add <2 x i8> %vv, %msplat ; <x0+y0+x0+y0, poison>
1176+
ret <2 x i8> %res
1177+
}
1178+
1179+
define <2 x i8> @common_binop_demand_via_splat_mask_poison_2(<2 x i8> %x, <2 x i8> %y) {
1180+
; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_2(
1181+
; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
1182+
; CHECK-NEXT: [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
1183+
; CHECK-NEXT: [[M:%.*]] = add <2 x i8> [[X]], [[Y]]
1184+
; CHECK-NEXT: [[MSPLAT:%.*]] = shufflevector <2 x i8> [[M]], <2 x i8> [[Y]], <2 x i32> <i32 0, i32 2>
1185+
; CHECK-NEXT: [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
1186+
; CHECK-NEXT: ret <2 x i8> [[RES]]
1187+
;
1188+
%ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
1189+
%vv = add <2 x i8> %x, %ysplat
1190+
%m = add <2 x i8> %x, %y
1191+
%msplat = shufflevector <2 x i8> %m, <2 x i8> %y, <2 x i32> <i32 0, i32 2> ; LeftDemanded = 1, RightDemanded = 1
1192+
%res = add <2 x i8> %vv, %msplat
1193+
ret <2 x i8> %res
1194+
}
1195+
1196+
define <2 x i8> @common_binop_demand_via_splat_mask_poison_3(<2 x i8> %x, <2 x i8> %y) {
1197+
; CHECK-LABEL: @common_binop_demand_via_splat_mask_poison_3(
1198+
; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <2 x i8> [[Y:%.*]], <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
1199+
; CHECK-NEXT: [[VV:%.*]] = add <2 x i8> [[YSPLAT]], [[X:%.*]]
1200+
; CHECK-NEXT: [[M:%.*]] = add <2 x i8> [[X]], [[Y]]
1201+
; CHECK-NEXT: [[MSPLAT:%.*]] = shufflevector <2 x i8> [[M]], <2 x i8> poison, <2 x i32> zeroinitializer
1202+
; CHECK-NEXT: [[RES:%.*]] = add <2 x i8> [[VV]], [[MSPLAT]]
1203+
; CHECK-NEXT: ret <2 x i8> [[RES]]
1204+
;
1205+
%ysplat = shufflevector <2 x i8> %y, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
1206+
%vv = add <2 x i8> %x, %ysplat
1207+
%m = add <2 x i8> %x, %y
1208+
%msplat = shufflevector <2 x i8> %m, <2 x i8> poison, <2 x i32> <i32 0, i32 0> ; LeftDemanded = 1
1209+
%res = add <2 x i8> %vv, %msplat
1210+
ret <2 x i8> %res
1211+
}

0 commit comments

Comments
 (0)