aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-05-08 10:04:09 +0800
committerGitHub <noreply@github.com>2024-05-08 10:04:09 +0800
commitd085b42cbbefe79a41113abcd2b1e1f2a203acef (patch)
treefb9908dc5383e899b006bd33c2c42d2c129b9fe2
parent7098cd215b95286794d9e0c822e8323ad0509750 (diff)
downloadllvm-d085b42cbbefe79a41113abcd2b1e1f2a203acef.zip
llvm-d085b42cbbefe79a41113abcd2b1e1f2a203acef.tar.gz
llvm-d085b42cbbefe79a41113abcd2b1e1f2a203acef.tar.bz2
[InstSimplify] Do not simplify freeze in `simplifyWithOpReplaced` (#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 https://github.com/llvm/llvm-project/issues/91178
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp4
-rw-r--r--llvm/test/Transforms/InstCombine/icmp.ll15
-rw-r--r--llvm/test/Transforms/InstCombine/select.ll32
-rw-r--r--llvm/test/Transforms/PGOProfile/chr.ll7
4 files changed, 55 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4061dae..37a7259 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 freeze.
+ if (isa<FreezeInst>(I))
+ return nullptr;
+
// Replace Op with RepOp in instruction operands.
SmallVector<Value *, 8> NewOps;
bool AnyReplaced = false;
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 31093c7..2d786c8 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -5183,3 +5183,18 @@ entry:
%cmp = icmp eq i8 %add2, %add1
ret i1 %cmp
}
+
+define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
+; CHECK-LABEL: @icmp_freeze_sext(
+; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
+; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
+; CHECK-NEXT: ret i1 [[CMP2]]
+;
+ %cmp1 = icmp uge i16 %x, %y
+ %ext = sext i1 %cmp1 to i16
+ %ext.fr = freeze i16 %ext
+ %cmp2 = icmp uge i16 %ext.fr, %y
+ ret i1 %cmp2
+}
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 2efe274..2ade6fa 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4580,3 +4580,35 @@ 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: [[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: ret i8 [[SEL]]
+;
+ %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
+}
diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll
index 0551a17..38e8f85 100644
--- a/llvm/test/Transforms/PGOProfile/chr.ll
+++ b/llvm/test/Transforms/PGOProfile/chr.ll
@@ -1298,11 +1298,12 @@ define i32 @test_chr_14(ptr %i, ptr %j, i32 %sum0, i1 %pred, i32 %z) !prof !14 {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[Z_FR:%.*]] = freeze i32 [[Z:%.*]]
; CHECK-NEXT: [[I0:%.*]] = load i32, ptr [[I:%.*]], align 4
-; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[Z_FR]], 1
-; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
+; CHECK-NEXT: [[V1_NOT:%.*]] = icmp eq i32 [[Z_FR]], 1
+; CHECK-NEXT: br i1 [[V1_NOT]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
; CHECK: entry.split.nonchr:
+; CHECK-NEXT: [[PRED_FR:%.*]] = freeze i1 [[PRED:%.*]]
; CHECK-NEXT: [[V0:%.*]] = icmp eq i32 [[Z_FR]], 0
-; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i1 [[V0]], [[PRED:%.*]]
+; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i1 [[V0]], [[PRED_FR]]
; CHECK-NEXT: br i1 [[V3_NONCHR]], label [[BB0_NONCHR:%.*]], label [[BB1]], !prof [[PROF16]]
; CHECK: bb0.nonchr:
; CHECK-NEXT: call void @foo()