[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