Home | History | Annotate | Download | only in MemCpyOpt
      1 ; RUN: opt -memcpyopt -S < %s | FileCheck %s
      2 
      3 target datalayout = "e-i64:64-f80:128-n8:16:32:64"
      4 target triple = "x86_64-unknown-linux-gnu"
      5 
      6 %S = type { i8*, i8, i32 }
      7 
      8 define void @copy(%S* %src, %S* %dst) {
      9 ; CHECK-LABEL: copy
     10 ; CHECK-NOT: load
     11 ; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
     12 ; CHECK-NEXT: ret void
     13   %1 = load %S, %S* %src
     14   store %S %1, %S* %dst
     15   ret void
     16 }
     17 
     18 define void @noaliassrc(%S* noalias %src, %S* %dst) {
     19 ; CHECK-LABEL: noaliassrc
     20 ; CHECK-NOT: load
     21 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
     22 ; CHECK-NEXT: ret void
     23   %1 = load %S, %S* %src
     24   store %S %1, %S* %dst
     25   ret void
     26 }
     27 
     28 define void @noaliasdst(%S* %src, %S* noalias %dst) {
     29 ; CHECK-LABEL: noaliasdst
     30 ; CHECK-NOT: load
     31 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
     32 ; CHECK-NEXT: ret void
     33   %1 = load %S, %S* %src
     34   store %S %1, %S* %dst
     35   ret void
     36 }
     37 
     38 define void @destroysrc(%S* %src, %S* %dst) {
     39 ; CHECK-LABEL: destroysrc
     40 ; CHECK: load %S, %S* %src
     41 ; CHECK: call void @llvm.memset.p0i8.i64
     42 ; CHECK-NEXT: store %S %1, %S* %dst
     43 ; CHECK-NEXT: ret void
     44   %1 = load %S, %S* %src
     45   store %S zeroinitializer, %S* %src
     46   store %S %1, %S* %dst
     47   ret void
     48 }
     49 
     50 define void @destroynoaliassrc(%S* noalias %src, %S* %dst) {
     51 ; CHECK-LABEL: destroynoaliassrc
     52 ; CHECK-NOT: load
     53 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
     54 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64
     55 ; CHECK-NEXT: ret void
     56   %1 = load %S, %S* %src
     57   store %S zeroinitializer, %S* %src
     58   store %S %1, %S* %dst
     59   ret void
     60 }
     61 
     62 define void @copyalias(%S* %src, %S* %dst) {
     63 ; CHECK-LABEL: copyalias
     64 ; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src
     65 ; CHECK-NOT: load
     66 ; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
     67 ; CHECK-NEXT: store %S [[LOAD]], %S* %dst
     68 ; CHECK-NEXT: ret void
     69   %1 = load %S, %S* %src
     70   %2 = load %S, %S* %src
     71   store %S %1, %S* %dst
     72   store %S %2, %S* %dst
     73   ret void
     74 }
     75 
     76 ; If the store address is computed ina complex manner, make
     77 ; sure we lift the computation as well if needed and possible.
     78 define void @addrproducer(%S* %src, %S* %dst) {
     79 ; CHECK-LABEL: addrproducer
     80 ; CHECK: %dst2 = getelementptr %S, %S* %dst, i64 1
     81 ; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
     82 ; CHECK-NEXT: store %S undef, %S* %dst
     83 ; CHECK-NEXT: ret void
     84   %1 = load %S, %S* %src
     85   store %S undef, %S* %dst
     86   %dst2 = getelementptr %S , %S* %dst, i64 1
     87   store %S %1, %S* %dst2
     88   ret void
     89 }
     90 
     91 define void @aliasaddrproducer(%S* %src, %S* %dst, i32* %dstidptr) {
     92 ; CHECK-LABEL: aliasaddrproducer
     93   %1 = load %S, %S* %src
     94   store %S undef, %S* %dst
     95   %dstindex = load i32, i32* %dstidptr
     96   %dst2 = getelementptr %S , %S* %dst, i32 %dstindex
     97   store %S %1, %S* %dst2
     98   ret void
     99 }
    100 
    101 define void @noaliasaddrproducer(%S* %src, %S* noalias %dst, i32* noalias %dstidptr) {
    102 ; CHECK-LABEL: noaliasaddrproducer
    103   %1 = load %S, %S* %src
    104   store %S undef, %S* %src
    105   %2 = load i32, i32* %dstidptr
    106   %dstindex = or i32 %2, 1
    107   %dst2 = getelementptr %S , %S* %dst, i32 %dstindex
    108   store %S %1, %S* %dst2
    109   ret void
    110 }
    111