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 3 4define void @foo() { 5; CHECK-LABEL: define void @foo() { 6; CHECK-NEXT: bb17254: 7; CHECK-NEXT: ret void 8; 9 ret void 10} 11 12define void @empty_basic_block() { 13; CHECK-LABEL: define void @empty_basic_block() { 14; CHECK-NEXT: exit: 15; CHECK-NEXT: ret void 16; 17exit: 18 ret void 19} 20 21declare void @effecting() 22 23; Place dead instruction(s) before the terminator 24define 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 30; 31 %1 = add i32 0, 1 32 call void @effecting() 33 ret void 34} 35 36define void @dont_move_above_phi() { 37; CHECK-LABEL: define void @dont_move_above_phi() { 38; CHECK-NEXT: bb76951: 39; CHECK-NEXT: br label [[EXIT:%.*]] 40; CHECK: exit: 41; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[BB76951:%.*]] ] 42; CHECK-NEXT: call void @effecting() 43; CHECK-NEXT: ret void 44; 45 br label %exit 46exit: 47 %1 = phi i32 [0, %0] 48 call void @effecting() 49 ret void 50} 51 52define 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 58; 59 %1 = alloca i32 60 call void @effecting() 61 ret void 62} 63 64declare void @effecting1() 65 66define 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 72; 73 call void @effecting() 74 call void @effecting1() 75 ret void 76} 77 78declare void @effecting2(i32) 79 80define 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 88; 89 %one = add i32 1, 1 90 %two = add i32 2, 2 91 call void @effecting2(i32 %one) 92 call void @effecting2(i32 %two) 93 ret void 94} 95 96define 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:%.*]] 101; CHECK: exit: 102; CHECK-NEXT: call void @effecting2(i32 [[ONE]]) 103; CHECK-NEXT: ret void 104; 105 %one = add i32 1, 1 106 br label %exit 107exit: 108 call void @effecting2(i32 %one) 109 ret void 110} 111 112define 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 121; 122 %2 = load i32, ptr %a 123 %3 = load i32, ptr %b 124 store i32 %3, ptr %a 125 store i32 %2, ptr %b 126 ret void 127} 128 129define 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 139; 140 %2 = load i32, ptr %a 141 store i32 %2, ptr %a 142 %3 = load i32, ptr %b 143 store i32 %3, ptr %b 144 store i32 %2, ptr %a 145 ret void 146} 147 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`. 150define 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 158; 159 %2 = load i32, ptr %a 160 store i32 undef, ptr %b 161 store i32 %2, ptr %a 162 ret void 163} 164