brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · ffa892c Raw
184 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=sink -S | FileCheck %s3 4declare i32 @f_load_global() nounwind willreturn readonly5declare i32 @f_load_global_throwable() willreturn readonly6declare i32 @f_load_global_may_not_return() nounwind readonly7declare i32 @f_load_arg(ptr) nounwind willreturn readonly argmemonly8declare void @f_store_global(i32) nounwind willreturn9declare void @f_store_arg(ptr) nounwind willreturn argmemonly10declare void @f_readonly_arg(ptr readonly, ptr) nounwind willreturn argmemonly11declare i32 @f_readnone(i32) nounwind willreturn readnone12 13@A = external global i3214@B = external global i3215 16; Sink readonly call if no stores are in the way.17;18define i32 @test_sink_no_stores(i1 %z) {19; CHECK-LABEL: @test_sink_no_stores(20; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]21; CHECK:       true:22; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()23; CHECK-NEXT:    ret i32 [[L]]24; CHECK:       false:25; CHECK-NEXT:    ret i32 026;27  %l = call i32 @f_load_global()28  br i1 %z, label %true, label %false29true:30  ret i32 %l31false:32  ret i32 033}34 35define i32 @test_throwable_no_stores(i1 %z) {36; CHECK-LABEL: @test_throwable_no_stores(37; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global_throwable()38; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]39; CHECK:       true:40; CHECK-NEXT:    ret i32 [[L]]41; CHECK:       false:42; CHECK-NEXT:    ret i32 043;44  %l = call i32 @f_load_global_throwable()45  br i1 %z, label %true, label %false46true:47  ret i32 %l48false:49  ret i32 050}51 52define i32 @test_may_not_return_no_stores(i1 %z) {53; CHECK-LABEL: @test_may_not_return_no_stores(54; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global_may_not_return()55; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]56; CHECK:       true:57; CHECK-NEXT:    ret i32 [[L]]58; CHECK:       false:59; CHECK-NEXT:    ret i32 060;61  %l = call i32 @f_load_global_may_not_return()62  br i1 %z, label %true, label %false63true:64  ret i32 %l65false:66  ret i32 067}68 69define i32 @test_sink_argmem_store(i1 %z) {70; CHECK-LABEL: @test_sink_argmem_store(71; CHECK-NEXT:    store i32 0, ptr @B, align 472; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]73; CHECK:       true:74; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)75; CHECK-NEXT:    ret i32 [[L]]76; CHECK:       false:77; CHECK-NEXT:    ret i32 078;79  %l = call i32 @f_load_arg(ptr @A)80  store i32 0, ptr @B81  br i1 %z, label %true, label %false82true:83  ret i32 %l84false:85  ret i32 086}87 88define i32 @test_sink_argmem_call(i1 %z) {89; CHECK-LABEL: @test_sink_argmem_call(90; CHECK-NEXT:    call void @f_store_arg(ptr @B)91; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]92; CHECK:       true:93; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)94; CHECK-NEXT:    ret i32 [[L]]95; CHECK:       false:96; CHECK-NEXT:    ret i32 097;98  %l = call i32 @f_load_arg(ptr @A)99  call void @f_store_arg(ptr @B)100  br i1 %z, label %true, label %false101true:102  ret i32 %l103false:104  ret i32 0105}106 107define i32 @test_sink_argmem_multiple(i1 %z) {108; CHECK-LABEL: @test_sink_argmem_multiple(109; CHECK-NEXT:    call void @f_readonly_arg(ptr @A, ptr @B)110; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]111; CHECK:       true:112; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_arg(ptr @A)113; CHECK-NEXT:    ret i32 [[L]]114; CHECK:       false:115; CHECK-NEXT:    ret i32 0116;117  %l = call i32 @f_load_arg(ptr @A)118  call void @f_readonly_arg(ptr @A, ptr @B)119  br i1 %z, label %true, label %false120true:121  ret i32 %l122false:123  ret i32 0124}125 126; But don't sink if there is a store.127define i32 @test_nosink_store(i1 %z) {128; CHECK-LABEL: @test_nosink_store(129; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()130; CHECK-NEXT:    store i32 0, ptr @A, align 4131; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]132; CHECK:       true:133; CHECK-NEXT:    ret i32 [[L]]134; CHECK:       false:135; CHECK-NEXT:    ret i32 0136;137  %l = call i32 @f_load_global()138  store i32 0, ptr @A139  br i1 %z, label %true, label %false140true:141  ret i32 %l142false:143  ret i32 0144}145 146define i32 @test_nosink_call(i1 %z) {147; CHECK-LABEL: @test_nosink_call(148; CHECK-NEXT:    [[L:%.*]] = call i32 @f_load_global()149; CHECK-NEXT:    call void @f_store_global(i32 0)150; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]151; CHECK:       true:152; CHECK-NEXT:    ret i32 [[L]]153; CHECK:       false:154; CHECK-NEXT:    ret i32 0155;156  %l = call i32 @f_load_global()157  call void @f_store_global(i32 0)158  br i1 %z, label %true, label %false159true:160  ret i32 %l161false:162  ret i32 0163}164 165; readnone calls are sunk across stores.166define i32 @test_sink_readnone(i1 %z) {167; CHECK-LABEL: @test_sink_readnone(168; CHECK-NEXT:    store i32 0, ptr @A, align 4169; CHECK-NEXT:    br i1 [[Z:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]170; CHECK:       true:171; CHECK-NEXT:    [[L:%.*]] = call i32 @f_readnone(i32 0)172; CHECK-NEXT:    ret i32 [[L]]173; CHECK:       false:174; CHECK-NEXT:    ret i32 0175;176  %l = call i32 @f_readnone(i32 0)177  store i32 0, ptr @A178  br i1 %z, label %true, label %false179true:180  ret i32 %l181false:182  ret i32 0183}184