[llvm] [InstCombine] Don't reuse a sibling binop with extra flags via demanded elts (#199782) (PR #201545)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 23:54:34 PDT 2026
https://github.com/lijinpei-amd updated https://github.com/llvm/llvm-project/pull/201545
>From 0539799141e4bec05eaf601d12e46cabaa30236f Mon Sep 17 00:00:00 2001
From: Li Jinpei <jinpli at amd.com>
Date: Thu, 4 Jun 2026 14:27:59 +0800
Subject: [PATCH] [InstCombine] Drop a sibling binop's extra flags when reusing
it via demanded elts (#199782)
SimplifyDemandedVectorElts can replace a vector binop with a sibling
binop. But if the sibling carries a flag the original lacked, it could
produce a result the original never would.
https://alive2.llvm.org/ce/z/9yEaG7
Fix by dropping (via andIRFlags) any flag the sibling has that the
replaced binop lacks.
Fixes #199782.
---
.../InstCombineSimplifyDemanded.cpp | 11 +++-
.../InstCombine/vec_demanded_elts.ll | 58 +++++++++++++++++--
2 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 83ea2d2932ac9..cca297a5b8dc2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1999,10 +1999,15 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
return nullptr;
};
- if (User *ShufBO = findShufBO(/* MatchShufAsOp0 */ true))
- return ShufBO;
- if (User *ShufBO = findShufBO(/* MatchShufAsOp0 */ false))
+ User *ShufBO = findShufBO(/* MatchShufAsOp0 */ true);
+ if (!ShufBO)
+ ShufBO = findShufBO(/* MatchShufAsOp0 */ false);
+ if (ShufBO) {
+ auto *ShufBOI = cast<Instruction>(ShufBO);
+ ShufBOI->andIRFlags(BO);
+ Worklist.add(ShufBOI);
return ShufBO;
+ }
}
simplifyAndSetOp(I, 0, DemandedElts, PoisonElts);
diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
index 7e24ddfac5b1b..55755735a97cc 100644
--- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
+++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -1021,12 +1021,12 @@ define float @common_binop_demand_via_extelt_op1(<2 x float> %p, <2 x float> %y)
define float @common_binop_demand_via_extelt_op0_commute(<2 x float> %p, <2 x float> %q) {
; CHECK-LABEL: @common_binop_demand_via_extelt_op0_commute(
-; CHECK-NEXT: [[X:%.*]] = fsub nnan <2 x float> <float 0.000000e+00, float poison>, [[P:%.*]]
-; CHECK-NEXT: [[Y:%.*]] = fsub nnan <2 x float> <float 3.000000e+00, float 2.000000e+00>, [[Q:%.*]]
+; CHECK-NEXT: [[X:%.*]] = fsub <2 x float> <float 0.000000e+00, float poison>, [[P:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = fsub <2 x float> <float 3.000000e+00, float 2.000000e+00>, [[Q:%.*]]
; CHECK-NEXT: [[XSHUF:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <2 x i32> zeroinitializer
-; CHECK-NEXT: [[B_Y_XSHUF:%.*]] = fmul nnan <2 x float> [[Y]], [[XSHUF]]
-; CHECK-NEXT: [[B_XY0:%.*]] = extractelement <2 x float> [[B_Y_XSHUF]], i64 0
-; CHECK-NEXT: call void @use_fp(<2 x float> [[B_Y_XSHUF]])
+; CHECK-NEXT: [[B_XY:%.*]] = fmul <2 x float> [[Y]], [[XSHUF]]
+; CHECK-NEXT: [[B_XY0:%.*]] = extractelement <2 x float> [[B_XY]], i64 0
+; CHECK-NEXT: call void @use_fp(<2 x float> [[B_XY]])
; CHECK-NEXT: ret float [[B_XY0]]
;
%x = fsub <2 x float> <float 0.0, float 1.0>, %p ; thwart complexity-based canonicalization
@@ -1059,6 +1059,54 @@ define i4 @common_binop_demand_via_extelt_op1_commute(<2 x i4> %p, <2 x i4> %q)
ret i4 %b_xy0
}
+define i4 @common_binop_demand_via_extelt_nuw_nsw_sibling_nsw_extracted(<2 x i4> %x, <2 x i4> %y) {
+; CHECK-LABEL: @common_binop_demand_via_extelt_nuw_nsw_sibling_nsw_extracted(
+; CHECK-NEXT: [[XSHUF:%.*]] = shufflevector <2 x i4> [[X:%.*]], <2 x i4> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[SIB:%.*]] = sub nsw <2 x i4> [[XSHUF]], [[Y:%.*]]
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i4> [[SIB]], i64 0
+; CHECK-NEXT: call void @use(<2 x i4> [[SIB]])
+; CHECK-NEXT: ret i4 [[E]]
+;
+ %xshuf = shufflevector <2 x i4> %x, <2 x i4> poison, <2 x i32> zeroinitializer
+ %sib = sub nuw nsw <2 x i4> %xshuf, %y
+ %bo = sub nsw <2 x i4> %x, %y
+ %e = extractelement <2 x i4> %bo, i32 0
+ call void @use(<2 x i4> %sib)
+ ret i4 %e
+}
+
+define float @common_binop_demand_via_extelt_nsz_extracted(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: @common_binop_demand_via_extelt_nsz_extracted(
+; CHECK-NEXT: [[XSHUF:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[SIB:%.*]] = fadd <2 x float> [[XSHUF]], [[Y:%.*]]
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x float> [[SIB]], i64 0
+; CHECK-NEXT: call void @use_fp(<2 x float> [[SIB]])
+; CHECK-NEXT: ret float [[E]]
+;
+ %xshuf = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
+ %sib = fadd <2 x float> %xshuf, %y
+ %bo = fadd nsz <2 x float> %x, %y
+ %e = extractelement <2 x float> %bo, i32 0
+ call void @use_fp(<2 x float> %sib)
+ ret float %e
+}
+
+define float @common_binop_demand_via_extelt_contract_reassoc_sibling_reassoc_extracted(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: @common_binop_demand_via_extelt_contract_reassoc_sibling_reassoc_extracted(
+; CHECK-NEXT: [[XSHUF:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[SIB:%.*]] = fmul reassoc <2 x float> [[XSHUF]], [[Y:%.*]]
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x float> [[SIB]], i64 0
+; CHECK-NEXT: call void @use_fp(<2 x float> [[SIB]])
+; CHECK-NEXT: ret float [[E]]
+;
+ %xshuf = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> zeroinitializer
+ %sib = fmul contract reassoc <2 x float> %xshuf, %y
+ %bo = fmul reassoc <2 x float> %x, %y
+ %e = extractelement <2 x float> %bo, i32 0
+ call void @use_fp(<2 x float> %sib)
+ ret float %e
+}
+
; negative test - wrong operands for sub
define i4 @common_binop_demand_via_extelt_op0_wrong_commute(<2 x i4> %x, <2 x i4> %y) {
More information about the llvm-commits
mailing list