brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · c08f60a Raw
192 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature2; RUN: opt < %s -passes='require<globals-aa>,memcpyopt' -S -verify-memoryssa | FileCheck %s3 4target datalayout = "e"5 6declare void @foo(ptr)7declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind8declare void @llvm.lifetime.start.p0(ptr nocapture)9declare void @llvm.lifetime.end.p0(ptr nocapture)10 11; Check that the transformation isn't applied if the called function can12; capture the pointer argument (i.e. the nocapture attribute isn't present)13define void @test() {14; CHECK-LABEL: define {{[^@]+}}@test() {15; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 116; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 117; CHECK-NEXT:    call void @foo(ptr [[PTR2]])18; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1]], ptr [[PTR2]], i32 1, i1 false)19; CHECK-NEXT:    call void @foo(ptr [[PTR1]])20; CHECK-NEXT:    ret void21;22  %ptr1 = alloca i823  %ptr2 = alloca i824  call void @foo(ptr %ptr2)25  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)26  call void @foo(ptr %ptr1)27  ret void28}29 30; Same as previous test, but with a bitcasted argument.31define void @test_bitcast() {32; CHECK-LABEL: define {{[^@]+}}@test_bitcast() {33; CHECK-NEXT:    [[PTR1:%.*]] = alloca [2 x i8], align 134; CHECK-NEXT:    [[PTR2:%.*]] = alloca [2 x i8], align 135; CHECK-NEXT:    call void @foo(ptr [[PTR2]])36; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1]], ptr [[PTR2]], i32 2, i1 false)37; CHECK-NEXT:    call void @foo(ptr [[PTR1]])38; CHECK-NEXT:    ret void39;40  %ptr1 = alloca [2 x i8]41  %ptr2 = alloca [2 x i8]42  call void @foo(ptr %ptr2)43  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 2, i1 false)44  call void @foo(ptr %ptr1)45  ret void46}47 48; Lifetime of %ptr2 ends before the potential use of the capture in the second49; call.50define void @test_lifetime_end() {51; CHECK-LABEL: define {{[^@]+}}@test_lifetime_end() {52; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 153; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 154; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PTR2]])55; CHECK-NEXT:    call void @foo(ptr [[PTR1]])56; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PTR2]])57; CHECK-NEXT:    call void @foo(ptr [[PTR1]])58; CHECK-NEXT:    ret void59;60  %ptr1 = alloca i861  %ptr2 = alloca i862  call void @llvm.lifetime.start.p0(ptr %ptr2)63  call void @foo(ptr %ptr2)64  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)65  call void @llvm.lifetime.end.p0(ptr %ptr2)66  call void @foo(ptr %ptr1)67  ret void68}69 70; Lifetime of %ptr2 ends before any potential use of the capture because we71; return from the function.72define void @test_function_end() {73; CHECK-LABEL: define {{[^@]+}}@test_function_end() {74; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 175; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 176; CHECK-NEXT:    call void @foo(ptr [[PTR1]])77; CHECK-NEXT:    ret void78;79  %ptr1 = alloca i880  %ptr2 = alloca i881  call void @foo(ptr %ptr2)82  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)83  ret void84}85 86; A potential use of the capture occurs in a later block, can't be optimized.87define void @test_terminator() {88; CHECK-LABEL: define {{[^@]+}}@test_terminator() {89; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 190; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 191; CHECK-NEXT:    call void @foo(ptr [[PTR2]])92; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1]], ptr [[PTR2]], i32 1, i1 false)93; CHECK-NEXT:    br label [[NEXT:%.*]]94; CHECK:       next:95; CHECK-NEXT:    call void @foo(ptr [[PTR1]])96; CHECK-NEXT:    ret void97;98  %ptr1 = alloca i899  %ptr2 = alloca i8100  call void @foo(ptr %ptr2)101  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)102  br label %next103 104next:105  call void @foo(ptr %ptr1)106  ret void107}108 109; This case can be optimized, but would require a scan across multiple blocks110; and is currently not performed.111define void @test_terminator2() {112; CHECK-LABEL: define {{[^@]+}}@test_terminator2() {113; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 1114; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 1115; CHECK-NEXT:    call void @foo(ptr [[PTR2]])116; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1]], ptr [[PTR2]], i32 1, i1 false)117; CHECK-NEXT:    br label [[NEXT:%.*]]118; CHECK:       next:119; CHECK-NEXT:    ret void120;121  %ptr1 = alloca i8122  %ptr2 = alloca i8123  call void @foo(ptr %ptr2)124  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)125  br label %next126 127next:128  ret void129}130 131declare void @capture(ptr)132 133; This case should not be optimized, because dest is captured before the call.134define void @test_dest_captured_before_alloca() {135; CHECK-LABEL: define {{[^@]+}}@test_dest_captured_before_alloca() {136; CHECK-NEXT:    [[PTR1:%.*]] = alloca i8, align 1137; CHECK-NEXT:    [[PTR2:%.*]] = alloca i8, align 1138; CHECK-NEXT:    call void @capture(ptr [[PTR1]])139; CHECK-NEXT:    call void @foo(ptr [[PTR2]]) #[[ATTR2:[0-9]+]]140; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1]], ptr [[PTR2]], i32 1, i1 false)141; CHECK-NEXT:    ret void142;143  %ptr1 = alloca i8144  %ptr2 = alloca i8145  call void @capture(ptr %ptr1)146  call void @foo(ptr %ptr2) argmemonly147  call void @llvm.memcpy.p0.p0.i32(ptr %ptr1, ptr %ptr2, i32 1, i1 false)148  ret void149}150 151 152@g = internal global i8 0153 154; This case should not be optimized, because @g is captured before the call155; (being a global) and @icmp_g might depend on its identity.156define void @test_dest_captured_before_global() {157; CHECK-LABEL: define {{[^@]+}}@test_dest_captured_before_global() {158; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, align 1159; CHECK-NEXT:    call void @icmp_g(ptr [[PTR]])160; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr @g, ptr [[PTR]], i32 1, i1 false)161; CHECK-NEXT:    ret void162;163  %ptr = alloca i8164  call void @icmp_g(ptr %ptr)165  call void @llvm.memcpy.p0.p0.i32(ptr @g, ptr %ptr, i32 1, i1 false)166  ret void167}168 169define void @icmp_g(ptr %p) {170; CHECK-LABEL: define {{[^@]+}}@icmp_g171; CHECK-SAME: (ptr [[P:%.*]]) {172; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[P]], @g173; CHECK-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]174; CHECK:       if:175; CHECK-NEXT:    store i8 1, ptr [[P]], align 1176; CHECK-NEXT:    ret void177; CHECK:       else:178; CHECK-NEXT:    store i8 2, ptr [[P]], align 1179; CHECK-NEXT:    ret void180;181  %c = icmp eq ptr %p, @g182  br i1 %c, label %if, label %else183 184if:185  store i8 1, ptr %p186  ret void187 188else:189  store i8 2, ptr %p190  ret void191}192