Skip to content

Commit 83986a4

Browse files
committed
address comments
- remove unused %cond.2 from tests - bail on backedge from BB of incoming value of phi to BB of freeze - bail if incoming value of phi is from invoke and add a test - bail if phi has multiple values from same predecessor and test
1 parent 3ece5e0 commit 83986a4

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4981,11 +4981,16 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
49814981
return false;
49824982

49834983
if (auto *PN = dyn_cast<PHINode>(V)) {
4984-
if (llvm::any_of(PN->incoming_values(), [this, &PN](Use &U) {
4985-
return DT.dominates(PN->getParent(), PN->getIncomingBlock(U)) ||
4986-
match(U.get(), m_Undef());
4987-
}))
4988-
return false;
4984+
BasicBlock *BB = PN->getParent();
4985+
SmallPtrSet<BasicBlock *, 8> VisitedBBs;
4986+
for (Use &U : PN->incoming_values()) {
4987+
BasicBlock *InBB = PN->getIncomingBlock(U);
4988+
if (DT.dominates(BB, InBB) || isBackEdge(InBB, BB) ||
4989+
isa<InvokeInst>(U) || VisitedBBs.contains(InBB) ||
4990+
match(U.get(), m_Undef()))
4991+
return false;
4992+
VisitedBBs.insert(InBB);
4993+
}
49894994
}
49904995

49914996
// We can't push the freeze through an instruction which can itself create

llvm/test/Transforms/InstCombine/freeze.ll

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,9 +1143,9 @@ exit:
11431143

11441144
; We can remove this freeze as the incoming values to the PHI have the same
11451145
; well-defined start value and the GEP can't produce poison.
1146-
define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %cond.1, i1 %cond.2) {
1146+
define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %cond.1) {
11471147
; CHECK-LABEL: define void @fold_phi_noundef_start_value(
1148-
; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
1148+
; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]]) {
11491149
; CHECK-NEXT: [[ENTRY:.*]]:
11501150
; CHECK-NEXT: br label %[[LOOP:.*]]
11511151
; CHECK: [[LOOP]]:
@@ -1160,7 +1160,7 @@ define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %con
11601160
; CHECK-NEXT: [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
11611161
; CHECK-NEXT: [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
11621162
; CHECK-NEXT: [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
1163-
; CHECK-NEXT: br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP]]
1163+
; CHECK-NEXT: br i1 [[COND_1]], label %[[EXIT:.*]], label %[[LOOP]]
11641164
; CHECK: [[EXIT]]:
11651165
; CHECK-NEXT: ret void
11661166
;
@@ -1182,7 +1182,120 @@ loop.latch:
11821182
%iv.0.int = ptrtoint ptr %iv.0 to i64
11831183
%idx = sub i64 %iv.0.int, %iv.2.fr.int
11841184
%iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
1185-
br i1 %cond.2, label %exit, label %loop
1185+
br i1 %cond.1, label %exit, label %loop
1186+
1187+
exit:
1188+
ret void
1189+
}
1190+
1191+
declare ptr @get_ptr()
1192+
1193+
; When the phi isn't a simple recurrence and has multiple inputs from the same
1194+
; predecessor, we need to be careful to avoid iterator invalidation. The phi
1195+
; must have identical values for the predecessor and at no point should the
1196+
; freeze be pushed to a single one of the uses, e.g.
1197+
;
1198+
; %iv.2 = phi ptr [ %iv.0, %loop ], [ %iv.1.fr, %if.else ], [ %iv.1, %if.else ]
1199+
;
1200+
; We simply don't support this case, although it could be handled if there's a
1201+
; use case.
1202+
define void @fold_phi_non_simple_recurrence_multiple_forward_edges(ptr noundef %init, i1 %cond.0, i1 %cond.1) {
1203+
; CHECK-LABEL: define void @fold_phi_non_simple_recurrence_multiple_forward_edges(
1204+
; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]]) {
1205+
; CHECK-NEXT: [[ENTRY:.*]]:
1206+
; CHECK-NEXT: br label %[[LOOP:.*]]
1207+
; CHECK: [[LOOP]]:
1208+
; CHECK-NEXT: [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1209+
; CHECK-NEXT: br i1 [[COND_0]], label %[[LOOP_LATCH]], label %[[IF_ELSE:.*]]
1210+
; CHECK: [[IF_ELSE]]:
1211+
; CHECK-NEXT: [[IV_1:%.*]] = call ptr @get_ptr()
1212+
; CHECK-NEXT: br i1 false, label %[[LOOP_LATCH]], label %[[LOOP_LATCH]]
1213+
; CHECK: [[LOOP_LATCH]]:
1214+
; CHECK-NEXT: [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP]] ], [ [[IV_1]], %[[IF_ELSE]] ], [ [[IV_1]], %[[IF_ELSE]] ]
1215+
; CHECK-NEXT: [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]
1216+
; CHECK-NEXT: [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i64
1217+
; CHECK-NEXT: [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
1218+
; CHECK-NEXT: [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
1219+
; CHECK-NEXT: [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
1220+
; CHECK-NEXT: br i1 [[COND_1]], label %[[EXIT:.*]], label %[[LOOP]]
1221+
; CHECK: [[EXIT]]:
1222+
; CHECK-NEXT: ret void
1223+
;
1224+
entry:
1225+
br label %loop
1226+
1227+
loop:
1228+
%iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop.latch ]
1229+
br i1 %cond.0, label %loop.latch, label %if.else
1230+
1231+
if.else:
1232+
%iv.1 = call ptr @get_ptr()
1233+
br i1 %cond.0, label %loop.latch, label %loop.latch
1234+
1235+
loop.latch:
1236+
%iv.2 = phi ptr [ %iv.0, %loop ], [ %iv.1, %if.else ], [ %iv.1, %if.else ]
1237+
%iv.2.fr = freeze ptr %iv.2
1238+
%iv.2.fr.int = ptrtoint ptr %iv.2.fr to i64
1239+
%iv.0.int = ptrtoint ptr %iv.0 to i64
1240+
%idx = sub i64 %iv.0.int, %iv.2.fr.int
1241+
%iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
1242+
br i1 %cond.1, label %exit, label %loop
1243+
1244+
exit:
1245+
ret void
1246+
}
1247+
1248+
; When the phi input comes from an invoke, we need to be careful the freeze
1249+
; isn't pushed after the invoke.
1250+
define void @fold_phi_noundef_start_value_with_invoke(ptr noundef %init, i1 %cond.0, i1 %cond.1) personality ptr undef {
1251+
; CHECK-LABEL: define void @fold_phi_noundef_start_value_with_invoke(
1252+
; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]]) personality ptr undef {
1253+
; CHECK-NEXT: [[ENTRY:.*]]:
1254+
; CHECK-NEXT: br label %[[LOOP:.*]]
1255+
; CHECK: [[LOOP]]:
1256+
; CHECK-NEXT: [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1257+
; CHECK-NEXT: br i1 [[COND_0]], label %[[LOOP_LATCH]], label %[[IF_ELSE:.*]]
1258+
; CHECK: [[IF_ELSE]]:
1259+
; CHECK-NEXT: [[IV_1:%.*]] = invoke ptr @get_ptr()
1260+
; CHECK-NEXT: to label %[[LOOP_LATCH]] unwind label %[[UNWIND:.*]]
1261+
; CHECK: [[LOOP_LATCH]]:
1262+
; CHECK-NEXT: [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP]] ], [ [[IV_1]], %[[IF_ELSE]] ]
1263+
; CHECK-NEXT: [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]
1264+
; CHECK-NEXT: [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i64
1265+
; CHECK-NEXT: [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
1266+
; CHECK-NEXT: [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
1267+
; CHECK-NEXT: [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
1268+
; CHECK-NEXT: br i1 [[COND_1]], label %[[EXIT:.*]], label %[[LOOP]]
1269+
; CHECK: [[UNWIND]]:
1270+
; CHECK-NEXT: [[TMP0:%.*]] = landingpad i8
1271+
; CHECK-NEXT: cleanup
1272+
; CHECK-NEXT: unreachable
1273+
; CHECK: [[EXIT]]:
1274+
; CHECK-NEXT: ret void
1275+
;
1276+
entry:
1277+
br label %loop
1278+
1279+
loop:
1280+
%iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop.latch ]
1281+
br i1 %cond.0, label %loop.latch, label %if.else
1282+
1283+
if.else:
1284+
%iv.1 = invoke ptr @get_ptr()
1285+
to label %loop.latch unwind label %unwind
1286+
1287+
loop.latch:
1288+
%iv.2 = phi ptr [ %iv.0, %loop ], [ %iv.1, %if.else ]
1289+
%iv.2.fr = freeze ptr %iv.2
1290+
%iv.2.fr.int = ptrtoint ptr %iv.2.fr to i64
1291+
%iv.0.int = ptrtoint ptr %iv.0 to i64
1292+
%idx = sub i64 %iv.0.int, %iv.2.fr.int
1293+
%iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
1294+
br i1 %cond.1, label %exit, label %loop
1295+
1296+
unwind:
1297+
landingpad i8 cleanup
1298+
unreachable
11861299

11871300
exit:
11881301
ret void

0 commit comments

Comments
 (0)