Skip to content

Commit 36b3c26

Browse files
authored
[JumpThreading] Thread over BB with only an unconditional branch (#86312)
Fixes #76609 This patch does: - relax the phis constraint in `CanRedirectPredsOfEmptyBBToSucc` - guarantee the BB has multiple different predecessors to redirect, so that we can handle the case without phis in BB. Without this change and phi constraint, we may redirect the CommonPred. The motivation is consistent with JumpThreading. We always want the branch to jump more direct to the destination, without passing the middle block. In this way, we can expose more other optimization opportunities. An obivous example proposed by @dtcxzyw is like: ```llvm define i32 @test(...) { entry: br i1 %c, label %do.end, label %if.then if.then: ; preds = %entry %call2 = call i32 @dummy() %tobool3.not = icmp eq i32 %call2, 0 br i1 %tobool3.not, label %do.end, label %return do.end: ; preds = %entry, %if.then br label %return return: ; preds = %if.then, %do.end %retval.0 = phi i32 [ 0, %do.end ], [ %call2, %if.then ] ret i32 %retval.0 } ``` `entry` can directly jump to return, without passing `do.end`, and then the if-else pattern can be simplified further: ```llvm define i32 @test(...) { entry: br i1 %c, label %return, label %if.then if.then: ; preds = %entry %call2 = call i32 @dummy() br label %return return: ; preds = %if.then %retval.0 = phi i32 [ 0, %entry ], [ %call2, %if.then ] ret i32 %retval.0 } ```
1 parent 1120d8e commit 36b3c26

File tree

9 files changed

+284
-126
lines changed

9 files changed

+284
-126
lines changed

llvm/lib/Transforms/Utils/Local.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -1019,12 +1019,14 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
10191019
const SmallPtrSetImpl<BasicBlock *> &SuccPreds,
10201020
BasicBlock *&CommonPred) {
10211021

1022-
// There must be phis in BB, otherwise BB will be merged into Succ directly
1023-
if (BB->phis().empty() || Succ->phis().empty())
1022+
// When Succ has no phis, BB may be merged into Succ directly. We don't need
1023+
// to redirect the predecessors of BB in this case.
1024+
if (Succ->phis().empty())
10241025
return false;
10251026

1026-
// BB must have predecessors not shared that can be redirected to Succ
1027-
if (!BB->hasNPredecessorsOrMore(2))
1027+
// BB must have multiple different predecessors, so that at least one of
1028+
// predecessors can be redirected to Succ, except the common predecessor.
1029+
if (BB->getUniquePredecessor() || pred_empty(BB))
10281030
return false;
10291031

10301032
// Get single common predecessors of both BB and Succ

llvm/test/CodeGen/AArch64/and-sink.ll

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
define dso_local i32 @and_sink1(i32 %a, i1 %c) {
1212
; CHECK-LABEL: and_sink1:
1313
; CHECK: // %bb.0:
14-
; CHECK-NEXT: tbz w1, #0, .LBB0_3
14+
; CHECK-NEXT: tbz w1, #0, .LBB0_2
1515
; CHECK-NEXT: // %bb.1: // %bb0
16+
; CHECK-NEXT: tst w0, #0x4
1617
; CHECK-NEXT: adrp x8, A
18+
; CHECK-NEXT: cset w0, eq
1719
; CHECK-NEXT: str wzr, [x8, :lo12:A]
18-
; CHECK-NEXT: tbnz w0, #2, .LBB0_3
19-
; CHECK-NEXT: // %bb.2:
20-
; CHECK-NEXT: mov w0, #1 // =0x1
2120
; CHECK-NEXT: ret
22-
; CHECK-NEXT: .LBB0_3: // %bb2
21+
; CHECK-NEXT: .LBB0_2:
2322
; CHECK-NEXT: mov w0, wzr
2423
; CHECK-NEXT: ret
2524

llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll

+50-72
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ define i32 @combine_gt_ge_10() #0 {
1313
; CHECK: // %bb.0: // %entry
1414
; CHECK-NEXT: adrp x8, :got:a
1515
; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
16-
; CHECK-NEXT: ldr w8, [x8]
17-
; CHECK-NEXT: cmp w8, #10
16+
; CHECK-NEXT: ldr w9, [x8]
1817
; CHECK-NEXT: adrp x8, :got:b
1918
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
19+
; CHECK-NEXT: cmp w9, #10
2020
; CHECK-NEXT: b.le .LBB0_3
2121
; CHECK-NEXT: // %bb.1: // %land.lhs.true
2222
; CHECK-NEXT: adrp x9, :got:c
@@ -29,18 +29,17 @@ define i32 @combine_gt_ge_10() #0 {
2929
; CHECK-NEXT: mov w0, #1 // =0x1
3030
; CHECK-NEXT: ret
3131
; CHECK-NEXT: .LBB0_3: // %lor.lhs.false
32-
; CHECK-NEXT: b.lt .LBB0_6
32+
; CHECK-NEXT: cmp w9, #10
33+
; CHECK-NEXT: b.lt .LBB0_5
3334
; CHECK-NEXT: .LBB0_4: // %land.lhs.true3
3435
; CHECK-NEXT: adrp x9, :got:d
3536
; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
3637
; CHECK-NEXT: ldr w8, [x8]
3738
; CHECK-NEXT: ldr w9, [x9]
3839
; CHECK-NEXT: cmp w8, w9
39-
; CHECK-NEXT: b.ne .LBB0_6
40-
; CHECK-NEXT: // %bb.5:
41-
; CHECK-NEXT: mov w0, #1 // =0x1
40+
; CHECK-NEXT: cset w0, eq
4241
; CHECK-NEXT: ret
43-
; CHECK-NEXT: .LBB0_6: // %if.end
42+
; CHECK-NEXT: .LBB0_5:
4443
; CHECK-NEXT: mov w0, wzr
4544
; CHECK-NEXT: ret
4645
entry:
@@ -145,10 +144,10 @@ define i32 @combine_lt_ge_5() #0 {
145144
; CHECK: // %bb.0: // %entry
146145
; CHECK-NEXT: adrp x8, :got:a
147146
; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
148-
; CHECK-NEXT: ldr w8, [x8]
149-
; CHECK-NEXT: cmp w8, #5
147+
; CHECK-NEXT: ldr w9, [x8]
150148
; CHECK-NEXT: adrp x8, :got:b
151149
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
150+
; CHECK-NEXT: cmp w9, #5
152151
; CHECK-NEXT: b.ge .LBB2_3
153152
; CHECK-NEXT: // %bb.1: // %land.lhs.true
154153
; CHECK-NEXT: adrp x9, :got:c
@@ -161,18 +160,17 @@ define i32 @combine_lt_ge_5() #0 {
161160
; CHECK-NEXT: mov w0, #1 // =0x1
162161
; CHECK-NEXT: ret
163162
; CHECK-NEXT: .LBB2_3: // %lor.lhs.false
164-
; CHECK-NEXT: b.gt .LBB2_6
163+
; CHECK-NEXT: cmp w9, #5
164+
; CHECK-NEXT: b.gt .LBB2_5
165165
; CHECK-NEXT: .LBB2_4: // %land.lhs.true3
166166
; CHECK-NEXT: adrp x9, :got:d
167167
; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
168168
; CHECK-NEXT: ldr w8, [x8]
169169
; CHECK-NEXT: ldr w9, [x9]
170170
; CHECK-NEXT: cmp w8, w9
171-
; CHECK-NEXT: b.ne .LBB2_6
172-
; CHECK-NEXT: // %bb.5:
173-
; CHECK-NEXT: mov w0, #1 // =0x1
171+
; CHECK-NEXT: cset w0, eq
174172
; CHECK-NEXT: ret
175-
; CHECK-NEXT: .LBB2_6: // %if.end
173+
; CHECK-NEXT: .LBB2_5:
176174
; CHECK-NEXT: mov w0, wzr
177175
; CHECK-NEXT: ret
178176
entry:
@@ -499,24 +497,17 @@ define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
499497
; CHECK-NEXT: // %bb.3: // %while.cond.while.end_crit_edge
500498
; CHECK-NEXT: ldr w8, [x19]
501499
; CHECK-NEXT: .LBB7_4: // %while.end
502-
; CHECK-NEXT: cmp w8, #1
503-
; CHECK-NEXT: b.gt .LBB7_7
504-
; CHECK-NEXT: // %bb.5: // %land.lhs.true
505-
; CHECK-NEXT: adrp x8, :got:b
506-
; CHECK-NEXT: adrp x9, :got:d
507-
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
508-
; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
509-
; CHECK-NEXT: ldr w8, [x8]
510-
; CHECK-NEXT: ldr w9, [x9]
511-
; CHECK-NEXT: cmp w8, w9
512-
; CHECK-NEXT: b.ne .LBB7_7
513-
; CHECK-NEXT: // %bb.6:
514-
; CHECK-NEXT: mov w0, #123 // =0x7b
515-
; CHECK-NEXT: b .LBB7_8
516-
; CHECK-NEXT: .LBB7_7: // %if.end
517-
; CHECK-NEXT: mov w0, wzr
518-
; CHECK-NEXT: .LBB7_8: // %return
500+
; CHECK-NEXT: adrp x9, :got:b
501+
; CHECK-NEXT: adrp x10, :got:d
502+
; CHECK-NEXT: ldr x9, [x9, :got_lo12:b]
503+
; CHECK-NEXT: ldr x10, [x10, :got_lo12:d]
519504
; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
505+
; CHECK-NEXT: ldr w9, [x9]
506+
; CHECK-NEXT: ldr w10, [x10]
507+
; CHECK-NEXT: cmp w9, w10
508+
; CHECK-NEXT: ccmp w8, #2, #0, eq
509+
; CHECK-NEXT: mov w8, #123 // =0x7b
510+
; CHECK-NEXT: csel w0, w8, wzr, lt
520511
; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
521512
; CHECK-NEXT: .cfi_def_cfa_offset 0
522513
; CHECK-NEXT: .cfi_restore w19
@@ -564,52 +555,42 @@ return: ; preds = %if.end, %land.lhs.t
564555
define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
565556
; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other:
566557
; CHECK: // %bb.0: // %entry
567-
; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
568-
; CHECK-NEXT: .cfi_def_cfa_offset 16
569-
; CHECK-NEXT: .cfi_offset w19, -8
570-
; CHECK-NEXT: .cfi_offset w30, -16
571-
; CHECK-NEXT: .cfi_remember_state
572558
; CHECK-NEXT: adrp x8, :got:a
573559
; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
574560
; CHECK-NEXT: ldr w8, [x8]
575561
; CHECK-NEXT: cmp w8, #0
576-
; CHECK-NEXT: b.gt .LBB8_3
562+
; CHECK-NEXT: b.gt .LBB8_4
577563
; CHECK-NEXT: // %bb.1: // %while.body.preheader
564+
; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
565+
; CHECK-NEXT: .cfi_def_cfa_offset 16
566+
; CHECK-NEXT: .cfi_offset w19, -8
567+
; CHECK-NEXT: .cfi_offset w30, -16
578568
; CHECK-NEXT: sub w19, w8, #1
579569
; CHECK-NEXT: .LBB8_2: // %while.body
580570
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
581571
; CHECK-NEXT: bl do_something
582572
; CHECK-NEXT: adds w19, w19, #1
583573
; CHECK-NEXT: b.mi .LBB8_2
584-
; CHECK-NEXT: .LBB8_3: // %while.end
585-
; CHECK-NEXT: adrp x8, :got:c
586-
; CHECK-NEXT: ldr x8, [x8, :got_lo12:c]
587-
; CHECK-NEXT: ldr w8, [x8]
588-
; CHECK-NEXT: cmn w8, #2
589-
; CHECK-NEXT: b.lt .LBB8_6
590-
; CHECK-NEXT: // %bb.4: // %land.lhs.true
574+
; CHECK-NEXT: // %bb.3:
575+
; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
576+
; CHECK-NEXT: .cfi_def_cfa_offset 0
577+
; CHECK-NEXT: .cfi_restore w19
578+
; CHECK-NEXT: .cfi_restore w30
579+
; CHECK-NEXT: .LBB8_4: // %while.end
591580
; CHECK-NEXT: adrp x8, :got:b
592581
; CHECK-NEXT: adrp x9, :got:d
582+
; CHECK-NEXT: adrp x10, :got:c
593583
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
594584
; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
585+
; CHECK-NEXT: ldr x10, [x10, :got_lo12:c]
595586
; CHECK-NEXT: ldr w8, [x8]
596587
; CHECK-NEXT: ldr w9, [x9]
588+
; CHECK-NEXT: ldr w10, [x10]
597589
; CHECK-NEXT: cmp w8, w9
598-
; CHECK-NEXT: b.ne .LBB8_6
599-
; CHECK-NEXT: // %bb.5:
600-
; CHECK-NEXT: mov w0, #123 // =0x7b
601-
; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
602-
; CHECK-NEXT: .cfi_def_cfa_offset 0
603-
; CHECK-NEXT: .cfi_restore w19
604-
; CHECK-NEXT: .cfi_restore w30
605-
; CHECK-NEXT: ret
606-
; CHECK-NEXT: .LBB8_6: // %if.end
607-
; CHECK-NEXT: .cfi_restore_state
608-
; CHECK-NEXT: mov w0, wzr
609-
; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
610-
; CHECK-NEXT: .cfi_def_cfa_offset 0
611-
; CHECK-NEXT: .cfi_restore w19
612-
; CHECK-NEXT: .cfi_restore w30
590+
; CHECK-NEXT: mov w8, #-3 // =0xfffffffd
591+
; CHECK-NEXT: ccmp w10, w8, #4, eq
592+
; CHECK-NEXT: mov w8, #123 // =0x7b
593+
; CHECK-NEXT: csel w0, w8, wzr, gt
613594
; CHECK-NEXT: ret
614595
entry:
615596
%0 = load i32, ptr @a, align 4
@@ -782,37 +763,34 @@ define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 {
782763
; CHECK-NEXT: cmp w8, #0
783764
; CHECK-NEXT: csel x9, x0, xzr, gt
784765
; CHECK-NEXT: str x9, [x1]
785-
; CHECK-NEXT: b.le .LBB11_2
766+
; CHECK-NEXT: b.le .LBB11_3
786767
; CHECK-NEXT: // %bb.1: // %lor.lhs.false
787768
; CHECK-NEXT: cmp w8, #2
788-
; CHECK-NEXT: b.ge .LBB11_4
789-
; CHECK-NEXT: b .LBB11_6
790-
; CHECK-NEXT: .LBB11_2: // %land.lhs.true
769+
; CHECK-NEXT: b.ge .LBB11_5
770+
; CHECK-NEXT: // %bb.2:
771+
; CHECK-NEXT: mov w0, wzr
772+
; CHECK-NEXT: ret
773+
; CHECK-NEXT: .LBB11_3: // %land.lhs.true
791774
; CHECK-NEXT: adrp x8, :got:b
792775
; CHECK-NEXT: adrp x9, :got:c
793776
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
794777
; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
795778
; CHECK-NEXT: ldr w8, [x8]
796779
; CHECK-NEXT: ldr w9, [x9]
797780
; CHECK-NEXT: cmp w8, w9
798-
; CHECK-NEXT: b.ne .LBB11_4
799-
; CHECK-NEXT: // %bb.3:
781+
; CHECK-NEXT: b.ne .LBB11_5
782+
; CHECK-NEXT: // %bb.4:
800783
; CHECK-NEXT: mov w0, #1 // =0x1
801784
; CHECK-NEXT: ret
802-
; CHECK-NEXT: .LBB11_4: // %land.lhs.true3
785+
; CHECK-NEXT: .LBB11_5: // %land.lhs.true3
803786
; CHECK-NEXT: adrp x8, :got:b
804787
; CHECK-NEXT: adrp x9, :got:d
805788
; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
806789
; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
807790
; CHECK-NEXT: ldr w8, [x8]
808791
; CHECK-NEXT: ldr w9, [x9]
809792
; CHECK-NEXT: cmp w8, w9
810-
; CHECK-NEXT: b.ne .LBB11_6
811-
; CHECK-NEXT: // %bb.5:
812-
; CHECK-NEXT: mov w0, #1 // =0x1
813-
; CHECK-NEXT: ret
814-
; CHECK-NEXT: .LBB11_6: // %if.end
815-
; CHECK-NEXT: mov w0, wzr
793+
; CHECK-NEXT: cset w0, eq
816794
; CHECK-NEXT: ret
817795
entry:
818796
%0 = load i32, ptr @a, align 4

llvm/test/CodeGen/Hexagon/vect/zext-v4i1.ll

+5-13
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ define i32 @fred(ptr %a0) #0 {
1010
; CHECK-LABEL: fred:
1111
; CHECK: // %bb.0: // %b0
1212
; CHECK-NEXT: {
13-
; CHECK-NEXT: if (p0) jump:nt .LBB0_2
13+
; CHECK-NEXT: r1:0 = combine(r0,#0)
14+
; CHECK-NEXT: if (p0) jumpr r31
1415
; CHECK-NEXT: }
15-
; CHECK-NEXT: // %bb.1: // %b2
16+
; CHECK-NEXT: .LBB0_1: // %b2
1617
; CHECK-NEXT: {
1718
; CHECK-NEXT: r3:2 = combine(#0,#0)
18-
; CHECK-NEXT: r1:0 = memd(r0+#0)
19+
; CHECK-NEXT: r1:0 = memd(r1+#0)
1920
; CHECK-NEXT: }
2021
; CHECK-NEXT: {
2122
; CHECK-NEXT: p0 = vcmph.eq(r1:0,r3:2)
@@ -27,16 +28,7 @@ define i32 @fred(ptr %a0) #0 {
2728
; CHECK-NEXT: r0 = and(r0,#1)
2829
; CHECK-NEXT: }
2930
; CHECK-NEXT: {
30-
; CHECK-NEXT: p0 = cmp.eq(r0,#11)
31-
; CHECK-NEXT: r0 = #1
32-
; CHECK-NEXT: }
33-
; CHECK-NEXT: {
34-
; CHECK-NEXT: if (p0) r0 = #0
35-
; CHECK-NEXT: jumpr r31
36-
; CHECK-NEXT: }
37-
; CHECK-NEXT: .LBB0_2: // %b14
38-
; CHECK-NEXT: {
39-
; CHECK-NEXT: r0 = #0
31+
; CHECK-NEXT: r0 = !cmp.eq(r0,#11)
4032
; CHECK-NEXT: jumpr r31
4133
; CHECK-NEXT: }
4234
b0:

llvm/test/Transforms/JumpThreading/pr79175.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ define i32 @test(i64 %idx, i32 %val) {
1717
; CHECK: cond.end:
1818
; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i32 [[VAL]], 0
1919
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[CMP_I]]
20-
; CHECK-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP0:%.*]]
21-
; CHECK: cond.end.thread:
22-
; CHECK-NEXT: br label [[TMP0]]
20+
; CHECK-NEXT: br i1 [[COND_FR]], label [[TMP0:%.*]], label [[COND_END_THREAD]]
2321
; CHECK: 0:
24-
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ 0, [[COND_END_THREAD]] ], [ [[VAL]], [[COND_END]] ]
22+
; CHECK-NEXT: br label [[COND_END_THREAD]]
23+
; CHECK: cond.end.thread:
24+
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[VAL]], [[COND_END]] ], [ 0, [[TMP0]] ], [ 0, [[FOR_BODY]] ]
2525
; CHECK-NEXT: [[F_IDX:%.*]] = getelementptr inbounds i32, ptr @f, i64 [[IDX]]
2626
; CHECK-NEXT: store i32 [[TMP1]], ptr [[F_IDX]], align 4
2727
; CHECK-NEXT: [[F_RELOAD:%.*]] = load i32, ptr @f, align 4

0 commit comments

Comments
 (0)