xref: /llvm-project/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll (revision 23abf931386002fb9d2c11d026846475c224c641)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s
3
4declare void @side_effect_0() nofree
5
6declare void @side_effect_1(i32 %x) nofree
7
8declare void @no_side_effect() readonly
9
10; TODO: We can PRE the load into the cold path, removing it from the hot path.
11define i32 @test_01(ptr %p) {
12; CHECK-LABEL: @test_01(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    br label [[LOOP:%.*]]
15; CHECK:       loop:
16; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
17; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4
18; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[X]], 100
19; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
20; CHECK:       hot_path:
21; CHECK-NEXT:    br label [[BACKEDGE]]
22; CHECK:       cold_path:
23; CHECK-NEXT:    call void @side_effect_0() #[[ATTR0:[0-9]+]]
24; CHECK-NEXT:    br label [[BACKEDGE]]
25; CHECK:       backedge:
26; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]
27; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
28; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
29; CHECK:       exit:
30; CHECK-NEXT:    ret i32 [[X]]
31;
32entry:
33  br label %loop
34
35loop:
36  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]
37  %x = load i32, ptr %p
38  %cond = icmp ult i32 %x, 100
39  br i1 %cond, label %hot_path, label %cold_path
40
41hot_path:
42  br label %backedge
43
44cold_path:
45  call void @side_effect_0() nofree
46  br label %backedge
47
48backedge:
49  %iv.next = add i32 %iv, %x
50  %loop.cond = icmp ult i32 %iv.next, 1000
51  br i1 %loop.cond, label %loop, label %exit
52
53exit:
54  ret i32 %x
55}
56
57; TODO: We can PRE the load into the cold path, removing it from the hot path.
58define i32 @test_02(ptr %p) {
59; CHECK-LABEL: @test_02(
60; CHECK-NEXT:  entry:
61; CHECK-NEXT:    br label [[LOOP:%.*]]
62; CHECK:       loop:
63; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
64; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P:%.*]], align 4
65; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[X]], 100
66; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
67; CHECK:       hot_path:
68; CHECK-NEXT:    br label [[BACKEDGE]]
69; CHECK:       cold_path:
70; CHECK-NEXT:    call void @side_effect_1(i32 [[X]]) #[[ATTR0]]
71; CHECK-NEXT:    br label [[BACKEDGE]]
72; CHECK:       backedge:
73; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X]]
74; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
75; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
76; CHECK:       exit:
77; CHECK-NEXT:    ret i32 [[X]]
78;
79entry:
80  br label %loop
81
82loop:
83  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]
84  %x = load i32, ptr %p
85  %cond = icmp ult i32 %x, 100
86  br i1 %cond, label %hot_path, label %cold_path
87
88hot_path:
89  br label %backedge
90
91cold_path:
92  call void @side_effect_1(i32 %x) nofree
93  br label %backedge
94
95backedge:
96  %iv.next = add i32 %iv, %x
97  %loop.cond = icmp ult i32 %iv.next, 1000
98  br i1 %loop.cond, label %loop, label %exit
99
100exit:
101  ret i32 %x
102}
103
104define i32 @test_03(ptr %p) {
105; CHECK-LABEL: @test_03(
106; CHECK-NEXT:  entry:
107; CHECK-NEXT:    [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
108; CHECK-NEXT:    br label [[LOOP:%.*]]
109; CHECK:       loop:
110; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
111; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[X_PRE]], 100
112; CHECK-NEXT:    br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
113; CHECK:       hot_path:
114; CHECK-NEXT:    br label [[BACKEDGE]]
115; CHECK:       cold_path:
116; CHECK-NEXT:    call void @no_side_effect()
117; CHECK-NEXT:    br label [[BACKEDGE]]
118; CHECK:       backedge:
119; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], [[X_PRE]]
120; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
121; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
122; CHECK:       exit:
123; CHECK-NEXT:    ret i32 [[X_PRE]]
124;
125entry:
126  br label %loop
127
128loop:
129  %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]
130  %x = load i32, ptr %p
131  %cond = icmp ult i32 %x, 100
132  br i1 %cond, label %hot_path, label %cold_path
133
134hot_path:
135  br label %backedge
136
137cold_path:
138  call void @no_side_effect()
139  br label %backedge
140
141backedge:
142  %iv.next = add i32 %iv, %x
143  %loop.cond = icmp ult i32 %iv.next, 1000
144  br i1 %loop.cond, label %loop, label %exit
145
146exit:
147  ret i32 %x
148}
149