1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -S -passes=normalize -verify-each -norm-rename-all=false < %s | FileCheck %s
5 ; CHECK-LABEL: define void @foo() {
12 define void @empty_basic_block() {
13 ; CHECK-LABEL: define void @empty_basic_block() {
15 ; CHECK-NEXT: ret void
21 declare void @effecting()
23 ; Place dead instruction(s) before the terminator
24 define void @call_effecting() {
25 ; CHECK-LABEL: define void @call_effecting() {
26 ; CHECK-NEXT: bb15160:
27 ; CHECK-NEXT: call void @effecting()
28 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 0, 1
29 ; CHECK-NEXT: ret void
32 call void @effecting()
36 define void @dont_move_above_phi() {
37 ; CHECK-LABEL: define void @dont_move_above_phi() {
38 ; CHECK-NEXT: bb76951:
39 ; CHECK-NEXT: br label [[EXIT:%.*]]
41 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[BB76951:%.*]] ]
42 ; CHECK-NEXT: call void @effecting()
43 ; CHECK-NEXT: ret void
48 call void @effecting()
52 define void @dont_move_above_alloca() {
53 ; CHECK-LABEL: define void @dont_move_above_alloca() {
54 ; CHECK-NEXT: bb15160:
55 ; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4
56 ; CHECK-NEXT: call void @effecting()
57 ; CHECK-NEXT: ret void
60 call void @effecting()
64 declare void @effecting1()
66 define void @dont_reorder_effecting() {
67 ; CHECK-LABEL: define void @dont_reorder_effecting() {
68 ; CHECK-NEXT: bb10075:
69 ; CHECK-NEXT: call void @effecting()
70 ; CHECK-NEXT: call void @effecting1()
71 ; CHECK-NEXT: ret void
73 call void @effecting()
74 call void @effecting1()
78 declare void @effecting2(i32)
80 define void @dont_reorder_effecting1() {
81 ; CHECK-LABEL: define void @dont_reorder_effecting1() {
82 ; CHECK-NEXT: bb10075:
83 ; CHECK-NEXT: [[ONE:%.*]] = add i32 1, 1
84 ; CHECK-NEXT: call void @effecting2(i32 [[ONE]])
85 ; CHECK-NEXT: [[TWO:%.*]] = add i32 2, 2
86 ; CHECK-NEXT: call void @effecting2(i32 [[TWO]])
87 ; CHECK-NEXT: ret void
91 call void @effecting2(i32 %one)
92 call void @effecting2(i32 %two)
96 define void @dont_reorder_across_blocks() {
97 ; CHECK-LABEL: define void @dont_reorder_across_blocks() {
98 ; CHECK-NEXT: bb76951:
99 ; CHECK-NEXT: [[ONE:%.*]] = add i32 1, 1
100 ; CHECK-NEXT: br label [[EXIT:%.*]]
102 ; CHECK-NEXT: call void @effecting2(i32 [[ONE]])
103 ; CHECK-NEXT: ret void
108 call void @effecting2(i32 %one)
112 define void @independentldst(ptr %a, ptr %b) {
113 ; CHECK-LABEL: define void @independentldst(
114 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
115 ; CHECK-NEXT: bb10495:
116 ; CHECK-NEXT: %"vl12961([[B]])" = load i32, ptr [[B]], align 4
117 ; CHECK-NEXT: store i32 %"vl12961([[B]])", ptr [[A]], align 4
118 ; CHECK-NEXT: %"vl89528([[A]])" = load i32, ptr [[A]], align 4
119 ; CHECK-NEXT: store i32 %"vl89528([[A]])", ptr [[B]], align 4
120 ; CHECK-NEXT: ret void
122 %2 = load i32, ptr %a
123 %3 = load i32, ptr %b
129 define void @multiple_use_ld(ptr %a, ptr %b) {
130 ; CHECK-LABEL: define void @multiple_use_ld(
131 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
132 ; CHECK-NEXT: bb14927:
133 ; CHECK-NEXT: %"vl16793([[A]])" = load i32, ptr [[A]], align 4
134 ; CHECK-NEXT: store i32 %"vl16793([[A]])", ptr [[A]], align 4
135 ; CHECK-NEXT: %"vl89528([[B]])" = load i32, ptr [[B]], align 4
136 ; CHECK-NEXT: store i32 %"vl89528([[B]])", ptr [[B]], align 4
137 ; CHECK-NEXT: store i32 %"vl16793([[A]])", ptr [[A]], align 4
138 ; CHECK-NEXT: ret void
140 %2 = load i32, ptr %a
142 %3 = load i32, ptr %b
148 ; This is an incorrect transformation. Moving the store above the load could
149 ; change the loaded value. To do this, the pointers would need to be `noalias`.
150 define void @undef_st(ptr %a, ptr %b) {
151 ; CHECK-LABEL: define void @undef_st(
152 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
153 ; CHECK-NEXT: bb10495:
154 ; CHECK-NEXT: store i32 undef, ptr [[B]], align 4
155 ; CHECK-NEXT: %"vl16028([[A]])" = load i32, ptr [[A]], align 4
156 ; CHECK-NEXT: store i32 %"vl16028([[A]])", ptr [[A]], align 4
157 ; CHECK-NEXT: ret void
159 %2 = load i32, ptr %a
160 store i32 undef, ptr %b