Skip to content

[InstSimplify] Do not simplify freeze in simplifyWithOpReplaced #91215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 8, 2024

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented May 6, 2024

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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes #91178

@llvmbot
Copy link
Member

llvmbot commented May 6, 2024

@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-analysis

Author: Yingwei Zheng (dtcxzyw)

Changes

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 #91178


Full diff: https://github.com/llvm/llvm-project/pull/91215.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+4)
  • (modified) llvm/test/Transforms/InstCombine/select.ll (+28)
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 2efe2742ca4916..0a880fc986caf1 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4580,3 +4580,31 @@ 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:    [[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
+  %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
+}

@dtcxzyw
Copy link
Member Author

dtcxzyw commented May 7, 2024

Another case with one-use freeze: https://alive2.llvm.org/ce/z/Qyh5h6

define i1 @func638(i16 %0, i16 %1) {
  %3 = icmp uge i16 %0, %1
  %4 = sext i1 %3 to i16
  %5 = freeze i16 %4
  %6 = icmp uge i16 %5, %1
  ret i1 %6
}

----------------------------------------
define i1 @func638(i16 %#0, i16 %#1) {
#2:
  %#3 = icmp uge i16 %#0, %#1
  %#4 = sext i1 %#3 to i16
  %#5 = freeze i16 %#4
  %#6 = icmp uge i16 %#5, %#1
  ret i1 %#6
}
=>
define i1 @func638(i16 %#0, i16 %#1) nofree noundef willreturn memory(none) {
#2:
  %#3 = icmp uge i16 %#0, %#1
  %.fr = freeze i1 %#3
  ret i1 %.fr
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
i16 %#0 = poison
i16 %#1 = #x0000 (0)

Source:
i1 %#3 = poison
i16 %#4 = poison
i16 %#5 = #x0000 (0)
i1 %#6 = #x1 (1)

Target:
i1 %#3 = poison
i1 %.fr = #x0 (0)
Source value: #x1 (1)
Target value: #x0 (0)

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors

@llvmbot llvmbot added the PGO Profile Guided Optimizations label May 7, 2024
dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request May 7, 2024
@dtcxzyw dtcxzyw changed the title [InstSimplify] Do not simplify a multi-use freeze in simplifyWithOpReplaced [InstSimplify] Do not simplify freeze in simplifyWithOpReplaced May 7, 2024
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dtcxzyw dtcxzyw merged commit d085b42 into llvm:main May 8, 2024
5 checks passed
@dtcxzyw dtcxzyw deleted the fix-pr91178 branch May 8, 2024 02:04
@dtcxzyw dtcxzyw added this to the LLVM 18.X Release milestone May 8, 2024
@dtcxzyw
Copy link
Member Author

dtcxzyw commented May 8, 2024

/cherry-pick d085b42

@llvmbot
Copy link
Member

llvmbot commented May 8, 2024

Failed to cherry-pick: d085b42

https://github.com/llvm/llvm-project/actions/runs/8995135964

Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request

AZero13 pushed a commit to AZero13/llvm-project that referenced this pull request May 8, 2024
…vm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)

Revert "[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#91215)"

This reverts commit 1c2eb18d52976fef89972e89c52d2ec5ed7e4868.

[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)
@tstellar
Copy link
Collaborator

tstellar commented May 9, 2024

@dtcxzyw Did you create a pull request for backporting this?

@dtcxzyw
Copy link
Member Author

dtcxzyw commented May 9, 2024

@dtcxzyw Did you create a pull request for backporting this?

See #91419

AZero13 pushed a commit to AZero13/llvm-project that referenced this pull request May 9, 2024
…vm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)

Revert "[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#91215)"

This reverts commit 1c2eb18d52976fef89972e89c52d2ec5ed7e4868.

[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)
tstellar pushed a commit to AZero13/llvm-project that referenced this pull request May 14, 2024
…vm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)

Revert "[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#91215)"

This reverts commit 1c2eb18d52976fef89972e89c52d2ec5ed7e4868.

[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)
tstellar pushed a commit to AZero13/llvm-project that referenced this pull request May 14, 2024
…vm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)

Revert "[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#91215)"

This reverts commit 1c2eb18d52976fef89972e89c52d2ec5ed7e4868.

[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (llvm#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 freezes with the simplified value.

Proof:
https://alive2.llvm.org/ce/z/3Dn9Cd
https://alive2.llvm.org/ce/z/Qyh5h6

Fixes llvm#91178

(cherry picked from commit d085b42)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

[InstCombine] Miscompilation which simplifies a use of a multi-use freeze
4 participants