Skip to content

Commit 380fa87

Browse files
authored
[InstCombine] Replace all dominated uses of condition with constants (#105510)
This patch replaces all dominated uses of condition with true/false to improve context-sensitive optimizations. It eliminates a bunch of branches in llvm-opt-benchmark. As a side effect, it may introduce new phi nodes in some corner cases. See the following case: ``` define i1 @test(i1 %cmp, i1 %cond) { entry: br i1 %cond, label %bb1, label %bb2 bb1: br i1 %cmp, label %if.then, label %if.else if.then: br %bb2 if.else: br %bb2 bb2: %res = phi i1 [%cmp, %entry], [%cmp, %if.then], [%cmp, %if.else] ret i1 %res } ``` It will be simplified into: ``` define i1 @test(i1 %cmp, i1 %cond) { entry: br i1 %cond, label %bb1, label %bb2 bb1: br i1 %cmp, label %if.then, label %if.else if.then: br %bb2 if.else: br %bb2 bb2: %res = phi i1 [%cmp, %entry], [true, %if.then], [false, %if.else] ret i1 %res } ``` I am planning to fix this in late pipeline/CGP since this problem exists before the patch.
1 parent 84580a0 commit 380fa87

16 files changed

+238
-76
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3705,6 +3705,23 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
37053705
return nullptr;
37063706
}
37073707

3708+
// Replace all dominated uses of the condition with true/false
3709+
if (BI.getSuccessor(0) != BI.getSuccessor(1)) {
3710+
for (auto &U : make_early_inc_range(Cond->uses())) {
3711+
BasicBlockEdge Edge0(BI.getParent(), BI.getSuccessor(0));
3712+
if (DT.dominates(Edge0, U)) {
3713+
replaceUse(U, ConstantInt::getTrue(Cond->getType()));
3714+
addToWorklist(cast<Instruction>(U.getUser()));
3715+
continue;
3716+
}
3717+
BasicBlockEdge Edge1(BI.getParent(), BI.getSuccessor(1));
3718+
if (DT.dominates(Edge1, U)) {
3719+
replaceUse(U, ConstantInt::getFalse(Cond->getType()));
3720+
addToWorklist(cast<Instruction>(U.getUser()));
3721+
}
3722+
}
3723+
}
3724+
37083725
DC.registerBranch(&BI);
37093726
return nullptr;
37103727
}

llvm/test/Transforms/InstCombine/assume.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ define i1 @nonnull3B(ptr %a, i1 %control) {
485485
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) [ "nonnull"(ptr [[LOAD]]) ]
486486
; CHECK-NEXT: ret i1 [[CMP]]
487487
; CHECK: not_taken:
488-
; CHECK-NEXT: ret i1 [[CONTROL]]
488+
; CHECK-NEXT: ret i1 false
489489
;
490490
entry:
491491
%load = load ptr, ptr %a
@@ -513,7 +513,7 @@ define i1 @nonnull3C(ptr %a, i1 %control) {
513513
; CHECK: exit:
514514
; CHECK-NEXT: ret i1 [[CMP2]]
515515
; CHECK: not_taken:
516-
; CHECK-NEXT: ret i1 [[CONTROL]]
516+
; CHECK-NEXT: ret i1 false
517517
;
518518
entry:
519519
%load = load ptr, ptr %a
@@ -543,7 +543,7 @@ define i1 @nonnull3D(ptr %a, i1 %control) {
543543
; CHECK: exit:
544544
; CHECK-NEXT: ret i1 [[CMP2]]
545545
; CHECK: not_taken:
546-
; CHECK-NEXT: ret i1 [[CONTROL]]
546+
; CHECK-NEXT: ret i1 false
547547
;
548548
entry:
549549
%load = load ptr, ptr %a

llvm/test/Transforms/InstCombine/branch.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,99 @@ t:
242242
f:
243243
ret i32 3
244244
}
245+
246+
define i32 @dom_true(i1 %cmp) {
247+
; CHECK-LABEL: @dom_true(
248+
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
249+
; CHECK: if.then:
250+
; CHECK-NEXT: ret i32 1
251+
; CHECK: if.else:
252+
; CHECK-NEXT: ret i32 0
253+
;
254+
br i1 %cmp, label %if.then, label %if.else
255+
256+
if.then:
257+
%zext = zext i1 %cmp to i32
258+
ret i32 %zext
259+
260+
if.else:
261+
ret i32 0
262+
}
263+
264+
define i32 @dom_false(i1 %cmp) {
265+
; CHECK-LABEL: @dom_false(
266+
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
267+
; CHECK: if.then:
268+
; CHECK-NEXT: ret i32 0
269+
; CHECK: if.else:
270+
; CHECK-NEXT: ret i32 0
271+
;
272+
br i1 %cmp, label %if.else, label %if.then
273+
274+
if.then:
275+
%zext = zext i1 %cmp to i32
276+
ret i32 %zext
277+
278+
if.else:
279+
ret i32 0
280+
}
281+
282+
define i32 @dom_true_phi(i1 %cmp) {
283+
; CHECK-LABEL: @dom_true_phi(
284+
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
285+
; CHECK: if.then:
286+
; CHECK-NEXT: br label [[IF_END:%.*]]
287+
; CHECK: if.else:
288+
; CHECK-NEXT: br label [[IF_END]]
289+
; CHECK: if.end:
290+
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
291+
; CHECK-NEXT: ret i32 [[ZEXT]]
292+
;
293+
br i1 %cmp, label %if.then, label %if.else
294+
295+
if.then:
296+
br label %if.end
297+
298+
if.else:
299+
br label %if.end
300+
301+
if.end:
302+
%phi = phi i1 [ true, %if.then ], [ %cmp, %if.else ]
303+
%zext = zext i1 %phi to i32
304+
ret i32 %zext
305+
}
306+
307+
; Negative tests
308+
309+
define i32 @same_dest(i1 %cmp) {
310+
; CHECK-LABEL: @same_dest(
311+
; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_THEN]]
312+
; CHECK: if.then:
313+
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP:%.*]] to i32
314+
; CHECK-NEXT: ret i32 [[ZEXT]]
315+
;
316+
br i1 %cmp, label %if.then, label %if.then
317+
318+
if.then:
319+
%zext = zext i1 %cmp to i32
320+
ret i32 %zext
321+
}
322+
323+
define i32 @not_dom(i1 %cmp) {
324+
; CHECK-LABEL: @not_dom(
325+
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
326+
; CHECK: if.then:
327+
; CHECK-NEXT: br label [[IF_ELSE]]
328+
; CHECK: if.else:
329+
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
330+
; CHECK-NEXT: ret i32 [[ZEXT]]
331+
;
332+
br i1 %cmp, label %if.then, label %if.else
333+
334+
if.then:
335+
br label %if.else
336+
337+
if.else:
338+
%zext = zext i1 %cmp to i32
339+
ret i32 %zext
340+
}

llvm/test/Transforms/InstCombine/compare-unescaped.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ define i1 @compare_and_call_after() {
8686
; CHECK-NEXT: call void @escape(ptr [[M]])
8787
; CHECK-NEXT: ret i1 true
8888
; CHECK: just_return:
89-
; CHECK-NEXT: ret i1 [[CMP]]
89+
; CHECK-NEXT: ret i1 false
9090
;
9191
%m = call ptr @malloc(i64 24)
9292
%lgp = load ptr, ptr @gp, align 8, !nonnull !0

llvm/test/Transforms/InstCombine/icmp-dom.ll

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
196196
; CHECK: t:
197197
; CHECK-NEXT: ret i1 false
198198
; CHECK: f:
199-
; CHECK-NEXT: ret i1 [[CMP]]
199+
; CHECK-NEXT: ret i1 false
200200
;
201201
entry:
202202
%cmp = icmp sgt i32 %x, %y
@@ -216,7 +216,7 @@ define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
216216
; CHECK: t:
217217
; CHECK-NEXT: ret i1 false
218218
; CHECK: f:
219-
; CHECK-NEXT: ret i1 [[CMP]]
219+
; CHECK-NEXT: ret i1 false
220220
;
221221
entry:
222222
%cmp = icmp eq i32 %x, %y
@@ -236,7 +236,7 @@ define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
236236
; CHECK: t:
237237
; CHECK-NEXT: ret i1 true
238238
; CHECK: f:
239-
; CHECK-NEXT: ret i1 [[CMP]]
239+
; CHECK-NEXT: ret i1 false
240240
;
241241
entry:
242242
%cmp = icmp ult i32 %x, %y
@@ -256,7 +256,7 @@ define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
256256
; CHECK: t:
257257
; CHECK-NEXT: ret i1 true
258258
; CHECK: f:
259-
; CHECK-NEXT: ret i1 [[CMP]]
259+
; CHECK-NEXT: ret i1 false
260260
;
261261
entry:
262262
%cmp = icmp ugt i32 %x, %y
@@ -271,10 +271,10 @@ f:
271271
define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
272272
; CHECK-LABEL: @falseblock_cmp_is_false(
273273
; CHECK-NEXT: entry:
274-
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
275-
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
274+
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
275+
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[F:%.*]], label [[T:%.*]]
276276
; CHECK: t:
277-
; CHECK-NEXT: ret i1 [[CMP]]
277+
; CHECK-NEXT: ret i1 true
278278
; CHECK: f:
279279
; CHECK-NEXT: ret i1 false
280280
;
@@ -294,7 +294,7 @@ define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
294294
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
295295
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
296296
; CHECK: t:
297-
; CHECK-NEXT: ret i1 [[CMP]]
297+
; CHECK-NEXT: ret i1 true
298298
; CHECK: f:
299299
; CHECK-NEXT: ret i1 false
300300
;
@@ -314,7 +314,7 @@ define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
314314
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
315315
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
316316
; CHECK: t:
317-
; CHECK-NEXT: ret i1 [[CMP]]
317+
; CHECK-NEXT: ret i1 true
318318
; CHECK: f:
319319
; CHECK-NEXT: ret i1 true
320320
;
@@ -334,7 +334,7 @@ define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
334334
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
335335
; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
336336
; CHECK: t:
337-
; CHECK-NEXT: ret i1 [[CMP]]
337+
; CHECK-NEXT: ret i1 true
338338
; CHECK: f:
339339
; CHECK-NEXT: ret i1 true
340340
;

llvm/test/Transforms/InstCombine/indexed-gep-compares.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ define i1 @test7() {
292292
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[BB7]] ]
293293
; CHECK-NEXT: br i1 [[CMP]], label [[BB10:%.*]], label [[BB7]]
294294
; CHECK: bb10:
295-
; CHECK-NEXT: ret i1 [[CMP]]
295+
; CHECK-NEXT: ret i1 true
296296
;
297297
entry:
298298
br label %bb7

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,11 +1664,9 @@ define i64 @pr92084(double %x) {
16641664
; CHECK-NEXT: [[CMP:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00
16651665
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
16661666
; CHECK: if.then1:
1667-
; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE]], label [[IF_THEN2:%.*]]
1667+
; CHECK-NEXT: br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]]
16681668
; CHECK: if.then2:
1669-
; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64
1670-
; CHECK-NEXT: [[AND:%.*]] = and i64 [[CAST]], 1
1671-
; CHECK-NEXT: ret i64 [[AND]]
1669+
; CHECK-NEXT: ret i64 poison
16721670
; CHECK: if.else:
16731671
; CHECK-NEXT: ret i64 0
16741672
;

llvm/test/Transforms/InstCombine/phi-known-bits-operand-order.ll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ define void @phi_recurrence_start_first() {
1616
; CHECK-NEXT: br i1 [[COND_V]], label [[IF_THEN:%.*]], label [[WHILE_END:%.*]]
1717
; CHECK: if.then:
1818
; CHECK-NEXT: [[START]] = add nuw nsw i32 [[CELL_0]], 1
19-
; CHECK-NEXT: br i1 [[COND_V]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
19+
; CHECK-NEXT: [[COND_V2:%.*]] = call i1 @cond()
20+
; CHECK-NEXT: br i1 [[COND_V2]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
2021
; CHECK: for.cond11:
2122
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[START]], [[IF_THEN]] ], [ [[STEP:%.*]], [[FOR_COND11]] ]
2223
; CHECK-NEXT: [[CMP13:%.*]] = icmp ult i32 [[I_1]], 100
@@ -37,7 +38,8 @@ while.cond: ; preds = %entry, %for.cond26
3738

3839
if.then: ; preds = %while.cond
3940
%start = add nsw i32 %cell.0, 1
40-
br i1 %cond.v, label %for.cond11, label %for.cond26
41+
%cond.v2 = call i1 @cond()
42+
br i1 %cond.v2, label %for.cond11, label %for.cond26
4143

4244
for.cond11: ; preds = %for.cond11, %if.then
4345
%i.1 = phi i32 [ %start, %if.then ], [ %step, %for.cond11 ]
@@ -62,7 +64,8 @@ define void @phi_recurrence_step_first() {
6264
; CHECK-NEXT: br i1 [[COND_V]], label [[IF_THEN:%.*]], label [[WHILE_END:%.*]]
6365
; CHECK: if.then:
6466
; CHECK-NEXT: [[START]] = add nuw nsw i32 [[CELL_0]], 1
65-
; CHECK-NEXT: br i1 [[COND_V]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
67+
; CHECK-NEXT: [[COND_V2:%.*]] = call i1 @cond()
68+
; CHECK-NEXT: br i1 [[COND_V2]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
6669
; CHECK: for.cond11:
6770
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[STEP:%.*]], [[FOR_COND11]] ], [ [[START]], [[IF_THEN]] ]
6871
; CHECK-NEXT: [[CMP13:%.*]] = icmp ult i32 [[I_1]], 100
@@ -83,7 +86,8 @@ while.cond: ; preds = %entry, %for.cond26
8386

8487
if.then: ; preds = %while.cond
8588
%start = add nsw i32 %cell.0, 1
86-
br i1 %cond.v, label %for.cond11, label %for.cond26
89+
%cond.v2 = call i1 @cond()
90+
br i1 %cond.v2, label %for.cond11, label %for.cond26
8791

8892
for.cond11: ; preds = %for.cond11, %if.then
8993
%i.1 = phi i32 [ %step, %for.cond11 ], [ %start, %if.then]

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,7 @@ define i1 @phi_knownnonzero_eq_multiuse_oricmp(i32 %n, i32 %s, ptr %P, i32 %val)
15431543
; CHECK-NEXT: [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
15441544
; CHECK-NEXT: br label [[CLEANUP]]
15451545
; CHECK: cleanup:
1546-
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ [[CMP1]], [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1546+
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
15471547
; CHECK-NEXT: ret i1 [[FINAL]]
15481548
;
15491549
entry:
@@ -1581,13 +1581,13 @@ define i1 @phi_knownnonzero_ne_multiuse_oricmp_commuted(i32 %n, i32 %s, ptr %P,
15811581
; CHECK: if.end:
15821582
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
15831583
; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[VAL:%.*]], [[PHI]]
1584-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ORPHI]], 0
1585-
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[CLEANUP:%.*]]
1584+
; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[ORPHI]], 0
1585+
; CHECK-NEXT: br i1 [[CMP1_NOT]], label [[CLEANUP:%.*]], label [[NEXT:%.*]]
15861586
; CHECK: next:
15871587
; CHECK-NEXT: [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
15881588
; CHECK-NEXT: br label [[CLEANUP]]
15891589
; CHECK: cleanup:
1590-
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ [[CMP1]], [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1590+
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
15911591
; CHECK-NEXT: ret i1 [[FINAL]]
15921592
;
15931593
entry:
@@ -1634,7 +1634,7 @@ define i1 @phi_knownnonzero_eq_multiuse_andicmp(i32 %n, i32 %s, ptr %P, i32 %val
16341634
; CHECK-NEXT: [[BOOL2:%.*]] = icmp eq i32 [[PHI]], 0
16351635
; CHECK-NEXT: br label [[CLEANUP]]
16361636
; CHECK: cleanup:
1637-
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ [[CMP1]], [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1637+
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
16381638
; CHECK-NEXT: ret i1 [[FINAL]]
16391639
;
16401640
entry:
@@ -1675,13 +1675,13 @@ define i1 @phi_knownnonzero_ne_multiuse_andicmp(i32 %n, i32 %s, ptr %P, i32 %val
16751675
; CHECK: if.end:
16761676
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[SEL]], [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
16771677
; CHECK-NEXT: [[ANDPHI:%.*]] = and i32 [[PHI]], [[VAL:%.*]]
1678-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[ANDPHI]], 0
1679-
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[CLEANUP:%.*]]
1678+
; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[ANDPHI]], 0
1679+
; CHECK-NEXT: br i1 [[CMP1_NOT]], label [[CLEANUP:%.*]], label [[NEXT:%.*]]
16801680
; CHECK: next:
16811681
; CHECK-NEXT: [[BOOL2:%.*]] = icmp ne i32 [[PHI]], 0
16821682
; CHECK-NEXT: br label [[CLEANUP]]
16831683
; CHECK: cleanup:
1684-
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ [[CMP1]], [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
1684+
; CHECK-NEXT: [[FINAL:%.*]] = phi i1 [ false, [[IF_END]] ], [ [[BOOL2]], [[NEXT]] ]
16851685
; CHECK-NEXT: ret i1 [[FINAL]]
16861686
;
16871687
entry:

0 commit comments

Comments
 (0)