Skip to content

Commit f8f6965

Browse files
authored
[InstCombine] Allow freezing multiple operands (llvm#154336)
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).
1 parent c540678 commit f8f6965

File tree

12 files changed

+159
-148
lines changed

12 files changed

+159
-148
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 49 additions & 44 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.
4969-
// Op1 = ... ; Op1 can be posion
4970-
// Op0 = Inst(Op1, NonPoisonOps...) ; Op0 has only one use and only have
4971-
// ; single guaranteed-non-poison operands
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.
4967+
// Op1 = ... ; Op1 can be poison
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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,9 @@ define float @freeze_sqrt(float %arg) {
163163
define float @freeze_powi(float %arg0, i32 %arg1) {
164164
; CHECK-LABEL: define float @freeze_powi(
165165
; CHECK-SAME: float [[ARG0:%.*]], i32 [[ARG1:%.*]]) {
166-
; CHECK-NEXT: [[OP:%.*]] = call float @llvm.powi.f32.i32(float [[ARG0]], i32 [[ARG1]])
167-
; CHECK-NEXT: [[FREEZE:%.*]] = freeze float [[OP]]
166+
; CHECK-NEXT: [[ARG0_FR:%.*]] = freeze float [[ARG0]]
167+
; CHECK-NEXT: [[ARG1_FR:%.*]] = freeze i32 [[ARG1]]
168+
; CHECK-NEXT: [[FREEZE:%.*]] = call float @llvm.powi.f32.i32(float [[ARG0_FR]], i32 [[ARG1_FR]])
168169
; CHECK-NEXT: ret float [[FREEZE]]
169170
;
170171
%op = call float @llvm.powi.f32.i32(float %arg0, i32 %arg1)

llvm/test/Transforms/InstCombine/freeze.ll

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ define <3 x i4> @partial_undef_vec() {
106106
; Move the freeze forward to prevent poison from spreading.
107107

108108
define i32 @early_freeze_test1(i32 %x, i32 %y) {
109-
; CHECK-LABEL: define i32 @early_freeze_test1(
110-
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
111-
; CHECK-NEXT: [[V1:%.*]] = add i32 [[X]], [[Y]]
112-
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]
113-
; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1_FR]], 1
109+
; CHECK-LABEL: @early_freeze_test1(
110+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]
111+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]]
112+
; CHECK-NEXT: [[V1:%.*]] = add i32 [[X_FR]], [[Y_FR]]
113+
; CHECK-NEXT: [[V2:%.*]] = shl i32 [[V1]], 1
114114
; CHECK-NEXT: [[V3:%.*]] = and i32 [[V2]], 2
115115
; CHECK-NEXT: ret i32 [[V3]]
116116
;
@@ -153,9 +153,8 @@ define i32 @early_freeze_test3(i32 %v1) {
153153
}
154154

155155
define i32 @early_freeze_test4(i32 %v1) {
156-
; CHECK-LABEL: define i32 @early_freeze_test4(
157-
; CHECK-SAME: i32 [[V1:%.*]]) {
158-
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]
156+
; CHECK-LABEL: @early_freeze_test4(
157+
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1:%.*]]
159158
; CHECK-NEXT: [[V2:%.*]] = mul i32 [[V1_FR]], [[V1_FR]]
160159
; CHECK-NEXT: ret i32 [[V2]]
161160
;
@@ -938,21 +937,20 @@ exit: ; preds = %loop
938937
}
939938

940939
; The recurrence for the GEP offset can't produce poison so the freeze should
941-
; be pushed through to the ptr, but this is not currently supported.
940+
; be pushed through to the ptr.
942941
define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
943-
; CHECK-LABEL: define void @fold_phi_gep_phi_offset(
944-
; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) {
945-
; CHECK-NEXT: [[ENTRY:.*]]:
946-
; CHECK-NEXT: br label %[[LOOP:.*]]
947-
; CHECK: [[LOOP]]:
948-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ]
949-
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]
942+
; CHECK-LABEL: @fold_phi_gep_phi_offset(
943+
; CHECK-NEXT: entry:
944+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
945+
; CHECK-NEXT: br label [[LOOP:%.*]]
946+
; CHECK: loop:
947+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
948+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
950949
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
951-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
952-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
953-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]]
954-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
955-
; CHECK: [[EXIT]]:
950+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
951+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
952+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
953+
; CHECK: exit:
956954
; CHECK-NEXT: ret void
957955
;
958956
entry:
@@ -971,22 +969,21 @@ exit: ; preds = %loop
971969
ret void
972970
}
973971

974-
; Offset is still guaranteed not to be poison, so the freeze could be moved
975-
; here if we strip inbounds from the GEP, but this is not currently supported.
972+
; Offset is still guaranteed not to be poison, so the freeze can be moved
973+
; here if we strip inbounds from the GEP.
976974
define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
977-
; CHECK-LABEL: define void @fold_phi_gep_inbounds_phi_offset(
978-
; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 noundef [[N:%.*]]) {
979-
; CHECK-NEXT: [[ENTRY:.*]]:
980-
; CHECK-NEXT: br label %[[LOOP:.*]]
981-
; CHECK: [[LOOP]]:
982-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ]
983-
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]
975+
; CHECK-LABEL: @fold_phi_gep_inbounds_phi_offset(
976+
; CHECK-NEXT: entry:
977+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
978+
; CHECK-NEXT: br label [[LOOP:%.*]]
979+
; CHECK: loop:
980+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
981+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
984982
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
985-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
986-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
987-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]]
988-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
989-
; CHECK: [[EXIT]]:
983+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
984+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
985+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
986+
; CHECK: exit:
990987
; CHECK-NEXT: ret void
991988
;
992989
entry:
@@ -1005,21 +1002,21 @@ exit: ; preds = %loop
10051002
ret void
10061003
}
10071004

1008-
; GEP can produce poison, check freeze isn't moved.
1009-
define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) {
1010-
; CHECK-LABEL: define void @cant_fold_phi_gep_phi_offset(
1011-
; CHECK-SAME: ptr [[INIT:%.*]], ptr [[END:%.*]], i64 [[N:%.*]]) {
1012-
; CHECK-NEXT: [[ENTRY:.*]]:
1013-
; CHECK-NEXT: br label %[[LOOP:.*]]
1014-
; CHECK: [[LOOP]]:
1015-
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[I_NEXT_FR:%.*]], %[[LOOP]] ]
1016-
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N]], %[[ENTRY]] ], [ [[OFF_NEXT:%.*]], %[[LOOP]] ]
1005+
; Same as previous, but also requires freezing %n.
1006+
define void @fold_phi_gep_phi_offset_multiple(ptr %init, ptr %end, i64 %n) {
1007+
; CHECK-LABEL: @fold_phi_gep_phi_offset_multiple(
1008+
; CHECK-NEXT: entry:
1009+
; CHECK-NEXT: [[TMP0:%.*]] = freeze ptr [[INIT:%.*]]
1010+
; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[N:%.*]]
1011+
; CHECK-NEXT: br label [[LOOP:%.*]]
1012+
; CHECK: loop:
1013+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
1014+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[TMP1]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
10171015
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
1018-
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
1019-
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
1020-
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END]]
1021-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
1022-
; CHECK: [[EXIT]]:
1016+
; CHECK-NEXT: [[I_NEXT]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
1017+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT]], [[END:%.*]]
1018+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
1019+
; CHECK: exit:
10231020
; CHECK-NEXT: ret void
10241021
;
10251022
entry:

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5838,10 +5838,9 @@ entry:
58385838
define i1 @icmp_freeze_sext(i16 %x, i16 %y) {
58395839
; CHECK-LABEL: define i1 @icmp_freeze_sext(
58405840
; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
5841-
; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i16 [[X]], [[Y]]
5842-
; CHECK-NEXT: [[CMP1_FR:%.*]] = freeze i1 [[CMP1]]
5843-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[Y]], 0
5844-
; CHECK-NEXT: [[CMP2:%.*]] = or i1 [[TMP1]], [[CMP1_FR]]
5841+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i16 [[Y]]
5842+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i16 [[X]]
5843+
; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i16 [[X_FR]], [[Y_FR]]
58455844
; CHECK-NEXT: ret i1 [[CMP2]]
58465845
;
58475846
%cmp1 = icmp uge i16 %x, %y

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: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2847,7 +2847,8 @@ define void @cond_freeze_multipleuses(i8 %x, i8 %y) {
28472847
define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
28482848
; CHECK-LABEL: define i32 @select_freeze_icmp_eq(
28492849
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
2850-
; CHECK-NEXT: ret i32 [[Y]]
2850+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
2851+
; CHECK-NEXT: ret i32 [[Y_FR]]
28512852
;
28522853
%c = icmp eq i32 %x, %y
28532854
%c.fr = freeze i1 %c
@@ -2858,7 +2859,8 @@ define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {
28582859
define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
28592860
; CHECK-LABEL: define i32 @select_freeze_icmp_ne(
28602861
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
2861-
; CHECK-NEXT: ret i32 [[X]]
2862+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]
2863+
; CHECK-NEXT: ret i32 [[X_FR]]
28622864
;
28632865
%c = icmp ne i32 %x, %y
28642866
%c.fr = freeze i1 %c
@@ -2869,9 +2871,9 @@ define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {
28692871
define i32 @select_freeze_icmp_else(i32 %x, i32 %y) {
28702872
; CHECK-LABEL: define i32 @select_freeze_icmp_else(
28712873
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
2872-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y]]
2873-
; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2874-
; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2874+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
2875+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]]
2876+
; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.umin.i32(i32 [[X_FR]], i32 [[Y_FR]])
28752877
; CHECK-NEXT: ret i32 [[V]]
28762878
;
28772879
%c = icmp ult i32 %x, %y
@@ -2885,9 +2887,9 @@ declare void @use_i1_i32(i1, i32)
28852887
define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {
28862888
; CHECK-LABEL: define void @select_freeze_icmp_multuses(
28872889
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
2888-
; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X]], [[Y]]
2889-
; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]]
2890-
; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]]
2890+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
2891+
; CHECK-NEXT: [[V:%.*]] = freeze i32 [[X]]
2892+
; CHECK-NEXT: [[C_FR:%.*]] = icmp ne i32 [[V]], [[Y_FR]]
28912893
; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]])
28922894
; CHECK-NEXT: ret void
28932895
;

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,8 +1446,9 @@ define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {
14461446
define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
14471447
; CHECK-LABEL: define i4 @negate_freeze(
14481448
; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {
1449-
; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y]], [[X]]
1450-
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1449+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]]
1450+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]]
1451+
; CHECK-NEXT: [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]]
14511452
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]
14521453
; CHECK-NEXT: ret i4 [[T2]]
14531454
;
@@ -1459,8 +1460,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
14591460
define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
14601461
; CHECK-LABEL: define i4 @negate_freeze_extrause(
14611462
; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {
1462-
; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X]], [[Y]]
1463-
; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]]
1463+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]]
1464+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]]
1465+
; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]
14641466
; CHECK-NEXT: call void @use4(i4 [[T1]])
14651467
; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z]], [[T1]]
14661468
; CHECK-NEXT: ret i4 [[T2]]

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,8 +1543,9 @@ define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) {
15431543
define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
15441544
; CHECK-LABEL: define i4 @negate_freeze(
15451545
; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {
1546-
; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y]], [[X]]
1547-
; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1546+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]]
1547+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]]
1548+
; CHECK-NEXT: [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]]
15481549
; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]
15491550
; CHECK-NEXT: ret i4 [[T2]]
15501551
;
@@ -1556,8 +1557,9 @@ define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
15561557
define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
15571558
; CHECK-LABEL: define i4 @negate_freeze_extrause(
15581559
; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {
1559-
; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X]], [[Y]]
1560-
; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]]
1560+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X]]
1561+
; CHECK-NEXT: [[Y_FR:%.*]] = freeze i4 [[Y]]
1562+
; CHECK-NEXT: [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]
15611563
; CHECK-NEXT: call void @use4(i4 [[T1]])
15621564
; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z]], [[T1]]
15631565
; CHECK-NEXT: ret i4 [[T2]]

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) {
9696
define i8 @urem_without_assume(i8 %arg, i8 %arg2) {
9797
; CHECK-LABEL: define i8 @urem_without_assume(
9898
; CHECK-SAME: i8 [[ARG:%.*]], i8 [[ARG2:%.*]]) {
99-
; CHECK-NEXT: [[X:%.*]] = urem i8 [[ARG]], [[ARG2]]
100-
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
99+
; CHECK-NEXT: [[ARG2_FR:%.*]] = freeze i8 [[ARG2]]
100+
; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i8 [[ARG]]
101+
; CHECK-NEXT: [[X_FR:%.*]] = urem i8 [[ARG_FR]], [[ARG2_FR]]
101102
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
102-
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]]
103+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2_FR]]
103104
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
104105
; CHECK-NEXT: ret i8 [[OUT]]
105106
;

0 commit comments

Comments
 (0)