Skip to content

Commit d085b42

Browse files
authored
[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 #91178
1 parent 7098cd2 commit d085b42

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4312,6 +4312,10 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43124312
if (match(I, m_Intrinsic<Intrinsic::is_constant>()))
43134313
return nullptr;
43144314

4315+
// Don't simplify freeze.
4316+
if (isa<FreezeInst>(I))
4317+
return nullptr;
4318+
43154319
// Replace Op with RepOp in instruction operands.
43164320
SmallVector<Value *, 8> NewOps;
43174321
bool AnyReplaced = false;

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5183,3 +5183,18 @@ entry:
51835183
%cmp = icmp eq i8 %add2, %add1
51845184
ret i1 %cmp
51855185
}
5186+
5187+
define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
5188+
; CHECK-LABEL: @icmp_freeze_sext(
5189+
; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
5190+
; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
5191+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
5192+
; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
5193+
; CHECK-NEXT: ret i1 [[CMP2]]
5194+
;
5195+
%cmp1 = icmp uge i16 %x, %y
5196+
%ext = sext i1 %cmp1 to i16
5197+
%ext.fr = freeze i16 %ext
5198+
%cmp2 = icmp uge i16 %ext.fr, %y
5199+
ret i1 %cmp2
5200+
}

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4580,3 +4580,35 @@ define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
45804580
%s3 = select i1 %c1, i32 789, i32 %s2
45814581
ret i32 %s3
45824582
}
4583+
4584+
define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {
4585+
; CHECK-LABEL: @test_replace_freeze_multiuse(
4586+
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4587+
; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4588+
; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4589+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4590+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]]
4591+
; CHECK-NEXT: ret i8 [[ADD]]
4592+
;
4593+
%ext = zext i1 %x to i8
4594+
%shl = shl nuw i8 %ext, %y
4595+
%shl.fr = freeze i8 %shl
4596+
%sel = select i1 %x, i8 0, i8 %shl.fr
4597+
%add = add i8 %shl.fr, %sel
4598+
ret i8 %add
4599+
}
4600+
4601+
define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
4602+
; CHECK-LABEL: @test_replace_freeze_oneuse(
4603+
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8
4604+
; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]]
4605+
; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]]
4606+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]
4607+
; CHECK-NEXT: ret i8 [[SEL]]
4608+
;
4609+
%ext = zext i1 %x to i8
4610+
%shl = shl nuw i8 %ext, %y
4611+
%shl.fr = freeze i8 %shl
4612+
%sel = select i1 %x, i8 0, i8 %shl.fr
4613+
ret i8 %sel
4614+
}

llvm/test/Transforms/PGOProfile/chr.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,11 +1298,12 @@ define i32 @test_chr_14(ptr %i, ptr %j, i32 %sum0, i1 %pred, i32 %z) !prof !14 {
12981298
; CHECK-NEXT: entry:
12991299
; CHECK-NEXT: [[Z_FR:%.*]] = freeze i32 [[Z:%.*]]
13001300
; CHECK-NEXT: [[I0:%.*]] = load i32, ptr [[I:%.*]], align 4
1301-
; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[Z_FR]], 1
1302-
; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
1301+
; CHECK-NEXT: [[V1_NOT:%.*]] = icmp eq i32 [[Z_FR]], 1
1302+
; CHECK-NEXT: br i1 [[V1_NOT]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
13031303
; CHECK: entry.split.nonchr:
1304+
; CHECK-NEXT: [[PRED_FR:%.*]] = freeze i1 [[PRED:%.*]]
13041305
; CHECK-NEXT: [[V0:%.*]] = icmp eq i32 [[Z_FR]], 0
1305-
; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i1 [[V0]], [[PRED:%.*]]
1306+
; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i1 [[V0]], [[PRED_FR]]
13061307
; CHECK-NEXT: br i1 [[V3_NONCHR]], label [[BB0_NONCHR:%.*]], label [[BB1]], !prof [[PROF16]]
13071308
; CHECK: bb0.nonchr:
13081309
; CHECK-NEXT: call void @foo()

0 commit comments

Comments
 (0)