120 lines · plain
1; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s2 3declare i32 @foo() readonly argmemonly nounwind4declare i32 @foo2() readonly nounwind5declare i32 @bar(ptr %loc2) readonly argmemonly nounwind6 7define void @test(ptr %loc) {8; CHECK-LABEL: @test9; CHECK: @foo10; CHECK-LABEL: loop:11 br label %loop12 13loop:14 %res = call i32 @foo()15 store i32 %res, ptr %loc16 br label %loop17}18 19; Negative test: show argmemonly is required20define void @test_neg(ptr %loc) {21; CHECK-LABEL: @test_neg22; CHECK-LABEL: loop:23; CHECK: @foo24 br label %loop25 26loop:27 %res = call i32 @foo2()28 store i32 %res, ptr %loc29 br label %loop30}31 32define void @test2(ptr noalias %loc, ptr noalias %loc2) {33; CHECK-LABEL: @test234; CHECK: @bar35; CHECK-LABEL: loop:36 br label %loop37 38loop:39 %res = call i32 @bar(ptr %loc2)40 store i32 %res, ptr %loc41 br label %loop42}43 44; Negative test: %might clobber gep45define void @test3(ptr %loc) {46; CHECK-LABEL: @test347; CHECK-LABEL: loop:48; CHECK: @bar49 br label %loop50 51loop:52 %res = call i32 @bar(ptr %loc)53 %gep = getelementptr i32, ptr %loc, i64 100000054 store i32 %res, ptr %gep55 br label %loop56}57 58 59; Negative test: %loc might alias %loc260define void @test4(ptr %loc, ptr %loc2) {61; CHECK-LABEL: @test462; CHECK-LABEL: loop:63; CHECK: @bar64 br label %loop65 66loop:67 %res = call i32 @bar(ptr %loc2)68 store i32 %res, ptr %loc69 br label %loop70}71 72declare i32 @foo_new(ptr) readonly73 74define void @test5(ptr %loc2, ptr noalias %loc) {75; CHECK-LABEL: @test576; CHECK: @bar77; CHECK-LABEL: loop:78 br label %loop79 80loop:81 %res1 = call i32 @bar(ptr %loc2)82 %res = call i32 @foo_new(ptr %loc2)83 store volatile i32 %res1, ptr %loc84 br label %loop85}86 87 88; memcpy doesn't write to it's source argument, so loads to that location89; can still be hoisted90define void @test6(ptr noalias %loc, ptr noalias %loc2) {91; CHECK-LABEL: @test692; CHECK: %val = load i32, ptr %loc293; CHECK-LABEL: loop:94; CHECK: @llvm.memcpy95 br label %loop96 97loop:98 %val = load i32, ptr %loc299 store i32 %val, ptr %loc100 call void @llvm.memcpy.p0.p0.i64(ptr %loc, ptr %loc2, i64 8, i1 false)101 br label %loop102}103 104define void @test7(ptr noalias %loc, ptr noalias %loc2) {105; CHECK-LABEL: @test7106; CHECK: %val = load i32, ptr %loc2107; CHECK-LABEL: loop:108; CHECK: @custom_memcpy109 br label %loop110 111loop:112 %val = load i32, ptr %loc2113 store i32 %val, ptr %loc114 call void @custom_memcpy(ptr %loc, ptr %loc2)115 br label %loop116}117 118declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)119declare void @custom_memcpy(ptr nocapture writeonly, ptr nocapture readonly) argmemonly nounwind120