164 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -S -passes='normalize<no-rename-all>' -verify-each < %s | FileCheck %s3 4define void @foo() {5; CHECK-LABEL: define void @foo() {6; CHECK-NEXT: bb17254:7; CHECK-NEXT: ret void8;9 ret void10}11 12define void @empty_basic_block() {13; CHECK-LABEL: define void @empty_basic_block() {14; CHECK-NEXT: exit:15; CHECK-NEXT: ret void16;17exit:18 ret void19}20 21declare void @effecting()22 23; Place dead instruction(s) before the terminator24define void @call_effecting() {25; CHECK-LABEL: define void @call_effecting() {26; CHECK-NEXT: bb14885:27; CHECK-NEXT: call void @effecting()28; CHECK-NEXT: [[TMP0:%.*]] = add i32 0, 129; CHECK-NEXT: ret void30;31 %1 = add i32 0, 132 call void @effecting()33 ret void34}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 void44;45 br label %exit46exit:47 %1 = phi i32 [0, %0]48 call void @effecting()49 ret void50}51 52define void @dont_move_above_alloca() {53; CHECK-LABEL: define void @dont_move_above_alloca() {54; CHECK-NEXT: bb14885:55; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 456; CHECK-NEXT: call void @effecting()57; CHECK-NEXT: ret void58;59 %1 = alloca i3260 call void @effecting()61 ret void62}63 64declare void @effecting1()65 66define void @dont_reorder_effecting() {67; CHECK-LABEL: define void @dont_reorder_effecting() {68; CHECK-NEXT: bb45003:69; CHECK-NEXT: call void @effecting()70; CHECK-NEXT: call void @effecting1()71; CHECK-NEXT: ret void72;73 call void @effecting()74 call void @effecting1()75 ret void76}77 78declare void @effecting2(i32)79 80define void @dont_reorder_effecting1() {81; CHECK-LABEL: define void @dont_reorder_effecting1() {82; CHECK-NEXT: bb45003:83; CHECK-NEXT: [[ONE:%.*]] = add i32 1, 184; CHECK-NEXT: call void @effecting2(i32 [[ONE]])85; CHECK-NEXT: [[TWO:%.*]] = add i32 2, 286; CHECK-NEXT: call void @effecting2(i32 [[TWO]])87; CHECK-NEXT: ret void88;89 %one = add i32 1, 190 %two = add i32 2, 291 call void @effecting2(i32 %one)92 call void @effecting2(i32 %two)93 ret void94}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, 1100; CHECK-NEXT: br label [[EXIT:%.*]]101; CHECK: exit:102; CHECK-NEXT: call void @effecting2(i32 [[ONE]])103; CHECK-NEXT: ret void104;105 %one = add i32 1, 1106 br label %exit107exit:108 call void @effecting2(i32 %one)109 ret void110}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 4117; CHECK-NEXT: store i32 %"vl12961([[B]])", ptr [[A]], align 4118; CHECK-NEXT: %"vl89528([[A]])" = load i32, ptr [[A]], align 4119; CHECK-NEXT: store i32 %"vl89528([[A]])", ptr [[B]], align 4120; CHECK-NEXT: ret void121;122 %2 = load i32, ptr %a123 %3 = load i32, ptr %b124 store i32 %3, ptr %a125 store i32 %2, ptr %b126 ret void127}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 4134; CHECK-NEXT: store i32 %"vl16793([[A]])", ptr [[A]], align 4135; CHECK-NEXT: %"vl89528([[B]])" = load i32, ptr [[B]], align 4136; CHECK-NEXT: store i32 %"vl89528([[B]])", ptr [[B]], align 4137; CHECK-NEXT: store i32 %"vl16793([[A]])", ptr [[A]], align 4138; CHECK-NEXT: ret void139;140 %2 = load i32, ptr %a141 store i32 %2, ptr %a142 %3 = load i32, ptr %b143 store i32 %3, ptr %b144 store i32 %2, ptr %a145 ret void146}147 148; This is an incorrect transformation. Moving the store above the load could149; 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 4155; CHECK-NEXT: %"vl16028([[A]])" = load i32, ptr [[A]], align 4156; CHECK-NEXT: store i32 %"vl16028([[A]])", ptr [[A]], align 4157; CHECK-NEXT: ret void158;159 %2 = load i32, ptr %a160 store i32 undef, ptr %b161 store i32 %2, ptr %a162 ret void163}164