[llvm] [InstCombine] Avoid propagating invalid metadata in FoldOpIntoSelect (PR #199155)

Muhammed Shiyas N via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 4 03:24:35 PDT 2026


https://github.com/Shiyas-N updated https://github.com/llvm/llvm-project/pull/199155

>From e2e3f4f58046263e0e6cde381260bbb7659a4848 Mon Sep 17 00:00:00 2001
From: Shiyas-N <muhammedshiyasn811 at gmail.com>
Date: Sun, 17 May 2026 15:18:20 +0000
Subject: [PATCH 1/2] [InstCombine] Avoid propagating invalid metadata in
 FoldOpIntoSelect

FoldOpIntoSelect may create a select with a different result type from
the original instruction. Preserve only metadata valid for the
transformed select and avoid propagating !fpmath to non-FP selects.
---
 .../InstCombine/InstructionCombining.cpp      | 19 ++++++++++++++++++-
 .../Transforms/InstCombine/select_meta.ll     | 17 ++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 348dd162501a0..b21164e5df7e6 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1820,7 +1820,24 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
     NewTV = foldOperationIntoSelectOperand(Op, SI, TV, *this);
   if (!NewFV)
     NewFV = foldOperationIntoSelectOperand(Op, SI, FV, *this);
-  return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
+
+  SelectInst *NewSel = SelectInst::Create(SI->getCondition(), NewTV, NewFV);
+
+  // Preserve metadata that remains valid for the transformed select.
+  if (MDNode *Prof = SI->getMetadata(LLVMContext::MD_prof))
+    NewSel->setMetadata(LLVMContext::MD_prof, Prof);
+  if (MDNode *Unpred = SI->getMetadata(LLVMContext::MD_unpredictable))
+    NewSel->setMetadata(LLVMContext::MD_unpredictable, Unpred);
+
+  // Preserve !fpmath only for FP-typed selects.
+  if (isa<FPMathOperator>(NewSel))
+    if (MDNode *FPMath = SI->getMetadata(LLVMContext::MD_fpmath))
+      NewSel->setMetadata(LLVMContext::MD_fpmath, FPMath);
+
+  // Preserve source location information.
+  NewSel->setDebugLoc(SI->getDebugLoc());
+
+  return NewSel;
 }
 
 static Value *simplifyInstructionWithPHI(Instruction &I, PHINode *PN,
diff --git a/llvm/test/Transforms/InstCombine/select_meta.ll b/llvm/test/Transforms/InstCombine/select_meta.ll
index f22b5a4fd3c5f..41f912482b90e 100644
--- a/llvm/test/Transforms/InstCombine/select_meta.ll
+++ b/llvm/test/Transforms/InstCombine/select_meta.ll
@@ -380,13 +380,28 @@ define <2 x float> @select_fdiv(i1 %cond, <2 x float> %x, <2 x float> %y) {
   ret <2 x float> %ret
 }
 
+;PR 186471
+
+define i1 @fold_select_fcmp_fpmath(i1 %cond, float %a) {
+; CHECK-LABEL: @fold_select_fcmp_fpmath(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND:%.*]], i1 [[CMP]], i1 false
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, float %a, float 0.000000e+00, !fpmath !4
+  %res = fcmp olt float %lhs, 0.000000e+00
+  ret i1 %res
+}
+
 !1 = !{!"branch_weights", i32 2, i32 10}
 !2 = !{!"branch_weights", i32 3, i32 10}
 !3 = !{}
+!4 = !{float 2.500000e+00}
 
 ;.
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
-; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ; CHECK: [[PROF0]] = !{!"branch_weights", i32 2, i32 10}
 ; CHECK: [[PROF1]] = !{!"branch_weights", i32 10, i32 2}

>From 0f46cba8036d2caddbe82caf63d10ea2e3a2d525 Mon Sep 17 00:00:00 2001
From: Shiyas-N <muhammedshiyasn811 at gmail.com>
Date: Thu, 4 Jun 2026 10:14:40 +0000
Subject: [PATCH 2/2] Use copyMetadata() and drop fpmath propagation

---
 .../Transforms/InstCombine/InstructionCombining.cpp   | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index b21164e5df7e6..531accb0309c7 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1824,15 +1824,8 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
   SelectInst *NewSel = SelectInst::Create(SI->getCondition(), NewTV, NewFV);
 
   // Preserve metadata that remains valid for the transformed select.
-  if (MDNode *Prof = SI->getMetadata(LLVMContext::MD_prof))
-    NewSel->setMetadata(LLVMContext::MD_prof, Prof);
-  if (MDNode *Unpred = SI->getMetadata(LLVMContext::MD_unpredictable))
-    NewSel->setMetadata(LLVMContext::MD_unpredictable, Unpred);
-
-  // Preserve !fpmath only for FP-typed selects.
-  if (isa<FPMathOperator>(NewSel))
-    if (MDNode *FPMath = SI->getMetadata(LLVMContext::MD_fpmath))
-      NewSel->setMetadata(LLVMContext::MD_fpmath, FPMath);
+  NewSel->copyMetadata(*SI,
+                       {LLVMContext::MD_prof, LLVMContext::MD_unpredictable});
 
   // Preserve source location information.
   NewSel->setDebugLoc(SI->getDebugLoc());



More information about the llvm-commits mailing list