Skip to content

Commit 5776527

Browse files
committed
[InstCombine] Allow freezing multiple operands
InstCombine tries to convert `freeze(inst(op))` to `inst(freeze(op))`. Currently, this is limited to the case where a single operand needs to be frozen, and all other operands are guaranteed non-poison. This patch allows the transform even if multiple operands need to be frozen. The existing limitation makes sure that we do not increase the total number of freezes, but it also means that that we may fail to eliminate freezes (via poison flag dropping) and may prevent optimizations (as analysis generally can't look past freeze). Overall, I believe that aggressively pushing freezes upwards is more beneficial than harmful. This is the middle-end version of llvm#145939 in DAGCombine (which is currently reverted for SDAG-specific reasons). Fix test name reset variable names Do single pass recursive propagation
1 parent ff5767a commit 5776527

File tree

12 files changed

+143
-127
lines changed

12 files changed

+143
-127
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,63 +4961,68 @@ Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
49614961
Value *
49624962
InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
49634963
// Try to push freeze through instructions that propagate but don't produce
4964-
// poison as far as possible. If an operand of freeze follows three
4965-
// conditions 1) one-use, 2) does not produce poison, and 3) has all but one
4966-
// guaranteed-non-poison operands then push the freeze through to the one
4967-
// operand that is not guaranteed non-poison. The actual transform is as
4968-
// follows.
4964+
// poison as far as possible. If an operand of freeze does not produce poison
4965+
// then push the freeze through to the operands that are not guaranteed
4966+
// non-poison. The actual transform is as follows.
49694967
// Op1 = ... ; Op1 can be posion
4970-
// Op0 = Inst(Op1, NonPoisonOps...) ; Op0 has only one use and only have
4971-
// ; single guaranteed-non-poison operands
4968+
// Op0 = Inst(Op1, NonPoisonOps...)
49724969
// ... = Freeze(Op0)
49734970
// =>
49744971
// Op1 = ...
49754972
// Op1.fr = Freeze(Op1)
49764973
// ... = Inst(Op1.fr, NonPoisonOps...)
4977-
auto *OrigOp = OrigFI.getOperand(0);
4978-
auto *OrigOpInst = dyn_cast<Instruction>(OrigOp);
49794974

4980-
// While we could change the other users of OrigOp to use freeze(OrigOp), that
4981-
// potentially reduces their optimization potential, so let's only do this iff
4982-
// the OrigOp is only used by the freeze.
4983-
if (!OrigOpInst || !OrigOpInst->hasOneUse() || isa<PHINode>(OrigOp))
4984-
return nullptr;
4975+
auto CanPushFreeze = [](Value *V) {
4976+
if (!isa<Instruction>(V) || isa<PHINode>(V))
4977+
return false;
49854978

4986-
// We can't push the freeze through an instruction which can itself create
4987-
// poison. If the only source of new poison is flags, we can simply
4988-
// strip them (since we know the only use is the freeze and nothing can
4989-
// benefit from them.)
4990-
if (canCreateUndefOrPoison(cast<Operator>(OrigOp),
4991-
/*ConsiderFlagsAndMetadata*/ false))
4992-
return nullptr;
4979+
// We can't push the freeze through an instruction which can itself create
4980+
// poison. If the only source of new poison is flags, we can simply
4981+
// strip them (since we know the only use is the freeze and nothing can
4982+
// benefit from them.)
4983+
return !canCreateUndefOrPoison(cast<Operator>(V),
4984+
/*ConsiderFlagsAndMetadata*/ false);
4985+
};
49934986

4994-
// If operand is guaranteed not to be poison, there is no need to add freeze
4995-
// to the operand. So we first find the operand that is not guaranteed to be
4996-
// poison.
4997-
Value *MaybePoisonOperand = nullptr;
4998-
for (Value *V : OrigOpInst->operands()) {
4999-
if (isa<MetadataAsValue>(V) || isGuaranteedNotToBeUndefOrPoison(V) ||
5000-
// Treat identical operands as a single operand.
5001-
(MaybePoisonOperand && MaybePoisonOperand == V))
4987+
// Pushing freezes up long instruction chains can be expensive. Instead,
4988+
// we directly push the freeze all the way to the leaves. However, we leave
4989+
// deduplication of freezes on the same value for freezeOtherUses().
4990+
Use *OrigUse = &OrigFI.getOperandUse(0);
4991+
SmallPtrSet<Instruction *, 8> Visited;
4992+
SmallVector<Use *, 8> Worklist;
4993+
Worklist.push_back(OrigUse);
4994+
while (!Worklist.empty()) {
4995+
auto *U = Worklist.pop_back_val();
4996+
Value *V = U->get();
4997+
if (!CanPushFreeze(V)) {
4998+
// If we can't push through the original instruction, abort the transform.
4999+
if (U == OrigUse)
5000+
return nullptr;
5001+
5002+
auto *UserI = cast<Instruction>(U->getUser());
5003+
Builder.SetInsertPoint(UserI);
5004+
Value *Frozen = Builder.CreateFreeze(V, V->getName() + ".fr");
5005+
U->set(Frozen);
50025006
continue;
5003-
if (!MaybePoisonOperand)
5004-
MaybePoisonOperand = V;
5005-
else
5006-
return nullptr;
5007-
}
5007+
}
50085008

5009-
OrigOpInst->dropPoisonGeneratingAnnotations();
5009+
auto *I = cast<Instruction>(V);
5010+
if (!Visited.insert(I).second)
5011+
continue;
50105012

5011-
// If all operands are guaranteed to be non-poison, we can drop freeze.
5012-
if (!MaybePoisonOperand)
5013-
return OrigOp;
5013+
// reverse() to emit freezes in a more natural order.
5014+
for (Use &Op : reverse(I->operands())) {
5015+
Value *OpV = Op.get();
5016+
if (isa<MetadataAsValue>(OpV) || isGuaranteedNotToBeUndefOrPoison(OpV))
5017+
continue;
5018+
Worklist.push_back(&Op);
5019+
}
50145020

5015-
Builder.SetInsertPoint(OrigOpInst);
5016-
Value *FrozenMaybePoisonOperand = Builder.CreateFreeze(
5017-
MaybePoisonOperand, MaybePoisonOperand->getName() + ".fr");
5021+
I->dropPoisonGeneratingAnnotations();
5022+
this->Worklist.add(I);
5023+
}
50185024

5019-
OrigOpInst->replaceUsesOfWith(MaybePoisonOperand, FrozenMaybePoisonOperand);
5020-
return OrigOp;
5025+
return OrigUse->get();
50215026
}
50225027

50235028
Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,

llvm/test/Transforms/InstCombine/freeze-fp-ops.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,10 @@ define float @freeze_sqrt(float %arg) {
149149

150150
define float @freeze_powi(float %arg0, i32 %arg1) {
151151
; CHECK-LABEL: @freeze_powi(
152-
; CHECK-NEXT: [[OP:%.*]] = call float @llvm.powi.f32.i32(float [[ARG0:%.*]], i32 [[ARG1:%.*]])
153-
; CHECK-NEXT: [[FREEZE:%.*]] = freeze float [[OP]]
154-
; CHECK-NEXT: ret float [[FREEZE]]
152+
; CHECK-NEXT: [[FREEZE:%.*]] = freeze float [[OP:%.*]]
153+
; CHECK-NEXT: [[ARG1_FR:%.*]] = freeze i32 [[ARG1:%.*]]
154+
; CHECK-NEXT: [[OP1:%.*]] = call float @llvm.powi.f32.i32(float [[FREEZE]], i32 [[ARG1_FR]])
155+
; CHECK-NEXT: ret float [[OP1]]
155156
;
156157
%op = call float @llvm.powi.f32.i32(float %arg0, i32 %arg1)
157158
%freeze = freeze float %op

llvm/test/Transforms/InstCombine/freeze.ll

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,10 @@ define <3 x i4> @partial_undef_vec() {
100100

101101
define i32 @early_freeze_test1(i32 %x, i32 %y) {
102102
; CHECK-LABEL: @early_freeze_test1(
103-
; CHECK-NEXT: [[V1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
104-
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]
105-
; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1_FR]], 1
103+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
104+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
105+
; CHECK-NEXT: [[V1:%.*]] = add i32 [[X_FR]], [[Y_FR]]
106+
; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1]], 1
106107
; CHECK-NEXT: [[V3:%.*]] = and i32 [[V2]], 2
107108
; CHECK-NEXT: ret i32 [[V3]]
108109
;
@@ -144,9 +145,9 @@ define i32 @early_freeze_test3(i32 %v1) {
144145

145146
define i32 @early_freeze_test4(i32 %v1) {
146147
; CHECK-LABEL: @early_freeze_test4(
147-
; CHECK-NEXT: [[V2_FR:%.*]] = freeze i32 [[V2:%.*]]
148-
; CHECK-NEXT: [[V3:%.*]] = mul i32 [[V2_FR]], [[V2_FR]]
149-
; CHECK-NEXT: ret i32 [[V3]]
148+
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1:%.*]]
149+
; CHECK-NEXT: [[V2:%.*]] = mul i32 [[V1_FR]], [[V1_FR]]
150+
; CHECK-NEXT: ret i32 [[V2]]
150151
;
151152
%v2 = mul i32 %v1, %v1
152153
%v2.fr = freeze i32 %v2
@@ -889,18 +890,18 @@ exit: ; preds = %loop
889890
}
890891

891892
; The recurrence for the GEP offset can't produce poison so the freeze should
892-
; be pushed through to the ptr, but this is not currently supported.
893+
; be pushed through to the ptr.
893894
define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
894895
; CHECK-LABEL: @fold_phi_gep_phi_offset(
895896
; CHECK-NEXT: entry:
897+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
896898
; CHECK-NEXT: br label [[LOOP:%.*]]
897899
; CHECK: loop:
898-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
900+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
899901
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
900902
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
901-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
902-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
903-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
903+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
904+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
904905
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
905906
; CHECK: exit:
906907
; CHECK-NEXT: ret void
@@ -921,19 +922,19 @@ exit: ; preds = %loop
921922
ret void
922923
}
923924

924-
; Offset is still guaranteed not to be poison, so the freeze could be moved
925-
; here if we strip inbounds from the GEP, but this is not currently supported.
925+
; Offset is still guaranteed not to be poison, so the freeze can be moved
926+
; here if we strip inbounds from the GEP.
926927
define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
927928
; CHECK-LABEL: @fold_phi_gep_inbounds_phi_offset(
928929
; CHECK-NEXT: entry:
930+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
929931
; CHECK-NEXT: br label [[LOOP:%.*]]
930932
; CHECK: loop:
931-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
933+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
932934
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
933935
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
934-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
935-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
936-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
936+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
937+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
937938
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
938939
; CHECK: exit:
939940
; CHECK-NEXT: ret void
@@ -954,18 +955,19 @@ exit: ; preds = %loop
954955
ret void
955956
}
956957

957-
; GEP can produce poison, check freeze isn't moved.
958-
define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) {
959-
; CHECK-LABEL: @cant_fold_phi_gep_phi_offset(
958+
; Same as previous, but also requires freezing %n.
959+
define void @fold_phi_gep_phi_offset_multiple(ptr %init, ptr %end, i64 %n) {
960+
; CHECK-LABEL: @fold_phi_gep_phi_offset_multiple(
960961
; CHECK-NEXT: entry:
962+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
963+
; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[N:%.*]]
961964
; CHECK-NEXT: br label [[LOOP:%.*]]
962965
; CHECK: loop:
963-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
964-
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
966+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
967+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[TMP1]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
965968
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
966-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
967-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
968-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
969+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
970+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
969971
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
970972
; CHECK: exit:
971973
; CHECK-NEXT: ret void

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5393,11 +5393,10 @@ entry:
53935393

53945394
define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
53955395
; CHECK-LABEL: @icmp_freeze_sext(
5396-
; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
5397-
; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
5398-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
5399-
; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
5400-
; CHECK-NEXT: ret i1 [[CMP2]]
5396+
; CHECK-NEXT: [[Y:%.*]] = freeze i16 [[Y1:%.*]]
5397+
; CHECK-NEXT: [[X:%.*]] = freeze i16 [[X1:%.*]]
5398+
; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X]], [[Y]]
5399+
; CHECK-NEXT: ret i1 [[CMP1]]
54015400
;
54025401
%cmp1 = icmp uge i16 %x, %y
54035402
%ext = sext i1 %cmp1 to i16

llvm/test/Transforms/InstCombine/nsw.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,10 @@ define i32 @sub_sub1_nsw_nsw(i32 %a, i32 %b, i32 %c) {
255255

256256
define i8 @neg_nsw_freeze(i8 %a1, i8 %a2) {
257257
; CHECK-LABEL: @neg_nsw_freeze(
258-
; CHECK-NEXT: [[A_NEG:%.*]] = sub nsw i8 [[A2:%.*]], [[A1:%.*]]
259-
; CHECK-NEXT: [[FR_NEG:%.*]] = freeze i8 [[A_NEG]]
260-
; CHECK-NEXT: ret i8 [[FR_NEG]]
258+
; CHECK-NEXT: [[A1_FR:%.*]] = freeze i8 [[A1:%.*]]
259+
; CHECK-NEXT: [[A2_FR:%.*]] = freeze i8 [[A2:%.*]]
260+
; CHECK-NEXT: [[A_NEG:%.*]] = sub i8 [[A2_FR]], [[A1_FR]]
261+
; CHECK-NEXT: ret i8 [[A_NEG]]
261262
;
262263
%a = sub nsw i8 %a1, %a2
263264
%fr = freeze i8 %a

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,8 @@ define void @cond_freeze_multipleuses(i8 %x, i8 %y) {
26832683

26842684
define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
26852685
; CHECK-LABEL: @select_freeze_icmp_eq(
2686-
; CHECK-NEXT: ret i32 [[Y:%.*]]
2686+
; CHECK-NEXT: [[Y:%.*]] = freeze i32 [[Y1:%.*]]
2687+
; CHECK-NEXT: ret i32 [[Y]]
26872688
;
26882689
%c = icmp eq i32 %x, %y
26892690
%c.fr = freeze i1 %c
@@ -2693,7 +2694,8 @@ define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
26932694

26942695
define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
26952696
; CHECK-LABEL: @select_freeze_icmp_ne(
2696-
; CHECK-NEXT: ret i32 [[X:%.*]]
2697+
; CHECK-NEXT: [[X:%.*]] = freeze i32 [[X1:%.*]]
2698+
; CHECK-NEXT: ret i32 [[X]]
26972699
;
26982700
%c = icmp ne i32 %x, %y
26992701
%c.fr = freeze i1 %c
@@ -2703,9 +2705,9 @@ define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
27032705

27042706
define i32 @select_freeze_icmp_else(i32 %x, i32 %y) {
27052707
; CHECK-LABEL: @select_freeze_icmp_else(
2706-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2707-
; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2708-
; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2708+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
2709+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
2710+
; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.umin.i32(i32 [[X_FR]], i32 [[Y_FR]])
27092711
; CHECK-NEXT: ret i32 [[V]]
27102712
;
27112713
%c = icmp ult i32 %x, %y
@@ -2718,10 +2720,10 @@ declare void @use_i1_i32(i1, i32)
27182720

27192721
define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {
27202722
; CHECK-LABEL: @select_freeze_icmp_multuses(
2721-
; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
2722-
; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2723-
; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2724-
; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]])
2723+
; CHECK-NEXT: [[Y:%.*]] = freeze i32 [[Y1:%.*]]
2724+
; CHECK-NEXT: [[X:%.*]] = freeze i32 [[X1:%.*]]
2725+
; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X]], [[Y]]
2726+
; CHECK-NEXT: call void @use_i1_i32(i1 [[C]], i32 [[X]])
27252727
; CHECK-NEXT: ret void
27262728
;
27272729
%c = icmp ne i32 %x, %y

llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,9 +1353,10 @@ define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {
13531353
; Freeze is transparent as far as negation is concerned
13541354
define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
13551355
; CHECK-LABEL: @negate_freeze(
1356-
; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]]
1357-
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1358-
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1356+
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG:%.*]]
1357+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y:%.*]]
1358+
; CHECK-NEXT: [[T0_NEG1:%.*]] = sub i4 [[Y_FR]], [[T1_NEG]]
1359+
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T0_NEG1]], [[Z:%.*]]
13591360
; CHECK-NEXT: ret i4 [[T2]]
13601361
;
13611362
%t0 = sub i4 %x, %y
@@ -1365,8 +1366,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
13651366
}
13661367
define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
13671368
; CHECK-LABEL: @negate_freeze_extrause(
1368-
; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]]
1369-
; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]]
1369+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X:%.*]]
1370+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y:%.*]]
1371+
; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]
13701372
; CHECK-NEXT: call void @use4(i4 [[T1]])
13711373
; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
13721374
; CHECK-NEXT: ret i4 [[T2]]

llvm/test/Transforms/InstCombine/sub-of-negatible.ll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,9 +1443,10 @@ define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) {
14431443
; Freeze is transparent as far as negation is concerned
14441444
define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
14451445
; CHECK-LABEL: @negate_freeze(
1446-
; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]]
1447-
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1448-
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1446+
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG:%.*]]
1447+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y:%.*]]
1448+
; CHECK-NEXT: [[T0_NEG1:%.*]] = sub i4 [[Y_FR]], [[T1_NEG]]
1449+
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T0_NEG1]], [[Z:%.*]]
14491450
; CHECK-NEXT: ret i4 [[T2]]
14501451
;
14511452
%t0 = sub i4 %x, %y
@@ -1455,8 +1456,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
14551456
}
14561457
define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
14571458
; CHECK-LABEL: @negate_freeze_extrause(
1458-
; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]]
1459-
; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]]
1459+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X:%.*]]
1460+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y:%.*]]
1461+
; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]
14601462
; CHECK-NEXT: call void @use4(i4 [[T1]])
14611463
; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
14621464
; CHECK-NEXT: ret i4 [[T2]]

llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) {
9090
; https://alive2.llvm.org/ce/z/gNhZ2x
9191
define i8 @urem_without_assume(i8 %arg, i8 %arg2) {
9292
; CHECK-LABEL: @urem_without_assume(
93-
; CHECK-NEXT: [[X:%.*]] = urem i8 [[ARG:%.*]], [[ARG2:%.*]]
94-
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
93+
; CHECK-NEXT: [[ARG2:%.*]] = freeze i8 [[ARG3:%.*]]
94+
; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i8 [[ARG:%.*]]
95+
; CHECK-NEXT: [[X_FR:%.*]] = urem i8 [[ARG_FR]], [[ARG2]]
9596
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
9697
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]]
9798
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]

0 commit comments

Comments
 (0)