[llvm] [InstCombine] Enable select freeze poison folding when storing value (PR #129776)

John McIver via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 6 19:58:39 PST 2025


https://github.com/jmciver updated https://github.com/llvm/llvm-project/pull/129776

>From 97d6bec011195a57d792ea33cd90f19517c9c5d3 Mon Sep 17 00:00:00 2001
From: John McIver <john.mciver.iii at gmail.com>
Date: Tue, 4 Mar 2025 14:10:38 -0700
Subject: [PATCH] [InstCombine] Enable select freeze poison folding when
 storing value

The non-freeze poison argument to select can be one of the following: global,
constant, and noundef arguments.

Alive2 test validation: https://alive2.llvm.org/ce/z/jbtCS6
---
 .../InstCombine/InstructionCombining.cpp      | 22 +++++++++++++------
 llvm/test/Transforms/InstCombine/select.ll    |  9 +++-----
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 4c14dcfb4d75f..f40436f8ecf10 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4812,16 +4812,21 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
   //
   // TODO: This could use getBinopAbsorber() / getBinopIdentity() to avoid
   //       duplicating logic for binops at least.
-  auto getUndefReplacement = [&I](Type *Ty) {
-    Constant *BestValue = nullptr;
-    Constant *NullValue = Constant::getNullValue(Ty);
+  auto getUndefReplacement = [&I, &AC = this->AC, &DT = this->DT](Type *Ty) {
+    Value *SelectArgument = nullptr;
+    if (I.hasOneUse() &&
+        match(I.user_back(),
+              m_c_Select(m_Specific(&I), m_Value(SelectArgument))) &&
+        isGuaranteedNotToBeUndefOrPoison(SelectArgument, &AC, &I, &DT))
+      return SelectArgument;
+    Value *BestValue = nullptr;
+    Value *NullValue = Constant::getNullValue(Ty);
     for (const auto *U : I.users()) {
-      Constant *C = NullValue;
+      Value *C = NullValue;
       if (match(U, m_Or(m_Value(), m_Value())))
         C = ConstantInt::getAllOnesValue(Ty);
       else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value())))
         C = ConstantInt::getTrue(Ty);
-
       if (!BestValue)
         BestValue = C;
       else if (BestValue != C)
@@ -4842,8 +4847,11 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
 
   Constant *C;
   if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) {
-    Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType());
-    return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
+    Value *Replace = getUndefReplacement(I.getType()->getScalarType());
+    if (Constant *ReplaceC = dyn_cast<Constant>(Replace))
+      return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
+    else
+      return replaceInstUsesWith(I, Replace);
   }
 
   // Replace uses of Op with freeze(Op).
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index cc25f4ce24d9a..789d98197d878 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4904,8 +4904,7 @@ define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) {
 
 define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt, i1 %cond) {
 ; CHECK-LABEL: @select_freeze_poison_parameter(
-; CHECK-NEXT:    [[ADDR_SRC:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR_SRC1:%.*]], ptr null
-; CHECK-NEXT:    store ptr [[ADDR_SRC]], ptr [[ADDR_TGT:%.*]], align 8
+; CHECK-NEXT:    store ptr [[ADDR_SRC:%.*]], ptr [[ADDR_TGT:%.*]], align 8
 ; CHECK-NEXT:    ret void
 ;
   %freeze = freeze ptr poison
@@ -4918,8 +4917,7 @@ define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt
 
 define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
 ; CHECK-LABEL: @select_freeze_poison_global(
-; CHECK-NEXT:    [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr @glb, ptr null
-; CHECK-NEXT:    store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8
+; CHECK-NEXT:    store ptr @glb, ptr [[ADDR_TGT:%.*]], align 8
 ; CHECK-NEXT:    ret void
 ;
   %freeze = freeze ptr poison
@@ -4930,8 +4928,7 @@ define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
 
 define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) {
 ; CHECK-LABEL: @select_freeze_poison_constant(
-; CHECK-NEXT:    [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], i32 72, i32 0
-; CHECK-NEXT:    store i32 [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 4
+; CHECK-NEXT:    store i32 72, ptr [[ADDR_TGT:%.*]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %freeze = freeze i32 poison



More information about the llvm-commits mailing list