[llvm] [InstSimplify] Do not simplify a multi-use freeze in `simplifyWithOpReplaced` (PR #91215)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon May 6 07:26:48 PDT 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/91215

See the LangRef:
> All uses of a value returned by the same ‘freeze’ instruction are guaranteed to always observe the same value, while different ‘freeze’ instructions may yield different values.

It is incorrect to replace one use of a multi-use freeze with the simplified value.
Proof: https://alive2.llvm.org/ce/z/3Dn9Cd

Fixes https://github.com/llvm/llvm-project/issues/91178

>From 6d3f317c02949897c80e2d74fd9ffb9f6fca3185 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 6 May 2024 22:17:44 +0800
Subject: [PATCH 1/2] [InstSimplify] Add pre-commit tests for PR91178. NFC.

---
 llvm/test/Transforms/InstCombine/select.ll | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 2efe2742ca4916..ecd4f412bed621 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4580,3 +4580,29 @@ define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
   %s3 = select i1 %c1, i32 789, i32 %s2
   ret i32 %s3
 }
+
+define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {
+; CHECK-LABEL: @test_replace_freeze_multiuse(
+; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
+; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]
+; CHECK-NEXT:    ret i8 [[SHL_FR]]
+;
+  %ext = zext i1 %x to i8
+  %shl = shl nuw i8 %ext, %y
+  %shl.fr = freeze i8 %shl
+  %sel = select i1 %x, i8 0, i8 %shl.fr
+  %add = add i8 %shl.fr, %sel
+  ret i8 %add
+}
+
+define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
+; CHECK-LABEL: @test_replace_freeze_oneuse(
+; CHECK-NEXT:    ret i8 0
+;
+  %ext = zext i1 %x to i8
+  %shl = shl nuw i8 %ext, %y
+  %shl.fr = freeze i8 %shl
+  %sel = select i1 %x, i8 0, i8 %shl.fr
+  ret i8 %sel
+}

>From f071efeadc0d2191bc4799078c5cf25b1d3fa5c2 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 6 May 2024 22:19:00 +0800
Subject: [PATCH 2/2] [InstSimplify] Don't simplify a multi-use freeze in
 `simplifyWithOpReplaced`

---
 llvm/lib/Analysis/InstructionSimplify.cpp  | 4 ++++
 llvm/test/Transforms/InstCombine/select.ll | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4061dae83c10f3..06e1a4957bc727 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4312,6 +4312,10 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
   if (match(I, m_Intrinsic<Intrinsic::is_constant>()))
     return nullptr;
 
+  // Don't simplify a use of a multi-use freeze.
+  if (isa<FreezeInst>(I) && !I->hasOneUse())
+    return nullptr;
+
   // Replace Op with RepOp in instruction operands.
   SmallVector<Value *, 8> NewOps;
   bool AnyReplaced = false;
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index ecd4f412bed621..0a880fc986caf1 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4586,7 +4586,9 @@ define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {
 ; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
 ; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
 ; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]
-; CHECK-NEXT:    ret i8 [[SHL_FR]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]]
+; CHECK-NEXT:    ret i8 [[ADD]]
 ;
   %ext = zext i1 %x to i8
   %shl = shl nuw i8 %ext, %y



More information about the llvm-commits mailing list