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
4 declare void @side_effect_0() nofree
6 declare void @side_effect_1(i32 %x) nofree
8 declare void @no_side_effect() readonly
10 ; TODO: We can PRE the load into the cold path, removing it from the hot path.
11 define i32 @test_01(ptr %p) {
12 ; CHECK-LABEL: @test_01(
14 ; CHECK-NEXT: br label [[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:%.*]]
21 ; CHECK-NEXT: br label [[BACKEDGE]]
23 ; CHECK-NEXT: call void @side_effect_0() #[[ATTR0:[0-9]+]]
24 ; CHECK-NEXT: br label [[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:%.*]]
30 ; CHECK-NEXT: ret i32 [[X]]
36 %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]
38 %cond = icmp ult i32 %x, 100
39 br i1 %cond, label %hot_path, label %cold_path
45 call void @side_effect_0() nofree
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
57 ; TODO: We can PRE the load into the cold path, removing it from the hot path.
58 define i32 @test_02(ptr %p) {
59 ; CHECK-LABEL: @test_02(
61 ; CHECK-NEXT: br label [[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:%.*]]
68 ; CHECK-NEXT: br label [[BACKEDGE]]
70 ; CHECK-NEXT: call void @side_effect_1(i32 [[X]]) #[[ATTR0]]
71 ; CHECK-NEXT: br label [[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:%.*]]
77 ; CHECK-NEXT: ret i32 [[X]]
83 %iv = phi i32 [ 0, %entry], [%iv.next, %backedge]
85 %cond = icmp ult i32 %x, 100
86 br i1 %cond, label %hot_path, label %cold_path
92 call void @side_effect_1(i32 %x) nofree
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
104 define i32 @test_03(ptr %p) {
105 ; CHECK-LABEL: @test_03(
107 ; CHECK-NEXT: [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
108 ; CHECK-NEXT: br label [[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:%.*]]
114 ; CHECK-NEXT: br label [[BACKEDGE]]
116 ; CHECK-NEXT: call void @no_side_effect()
117 ; CHECK-NEXT: br label [[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:%.*]]
123 ; CHECK-NEXT: ret i32 [[X_PRE]]
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
138 call void @no_side_effect()
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