Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -instcombine -S < %s | FileCheck %s
      2 
      3 target datalayout = "e-p:64:64:64-p1:32:32:32-p2:16:16:16-n8:16:32:64"
      4 
      5 
      6 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) nounwind
      7 declare void @llvm.memcpy.p0i8.p1i8.i32(i8*, i8 addrspace(1)*, i32, i32, i1) nounwind
      8 declare void @llvm.memcpy.p0i8.p2i8.i32(i8*, i8 addrspace(2)*, i32, i32, i1) nounwind
      9 
     10 
     11 define i32* @combine_redundant_addrspacecast(i32 addrspace(1)* %x) nounwind {
     12 ; CHECK-LABEL: @combine_redundant_addrspacecast(
     13 ; CHECK: addrspacecast i32 addrspace(1)* %x to i32*
     14 ; CHECK-NEXT: ret
     15   %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
     16   %z = addrspacecast i32 addrspace(3)* %y to i32*
     17   ret i32* %z
     18 }
     19 
     20 define <4 x i32*> @combine_redundant_addrspacecast_vector(<4 x i32 addrspace(1)*> %x) nounwind {
     21 ; CHECK-LABEL: @combine_redundant_addrspacecast_vector(
     22 ; CHECK: addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32*>
     23 ; CHECK-NEXT: ret
     24   %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
     25   %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x i32*>
     26   ret <4 x i32*> %z
     27 }
     28 
     29 define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
     30 ; CHECK-LABEL: @combine_redundant_addrspacecast_types(
     31 ; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
     32 ; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float*
     33 ; CHECK-NEXT: ret
     34   %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
     35   %z = addrspacecast i32 addrspace(3)* %y to float*
     36   ret float* %z
     37 }
     38 
     39 define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
     40 ; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
     41 ; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
     42 ; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float*>
     43 ; CHECK-NEXT: ret
     44   %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
     45   %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*>
     46   ret <4 x float*> %z
     47 }
     48 
     49 define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind {
     50 ; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
     51 ; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
     52 ; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
     53 ; CHECK-NEXT: ret
     54   %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
     55   %z = bitcast i32 addrspace(2)* %y to float addrspace(2)*
     56   ret float addrspace(2)* %z
     57 }
     58 
     59 define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind {
     60 ; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
     61 ; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
     62 ; CHECK-NEXT: ret
     63   %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
     64   %z = bitcast float addrspace(2)* %y to i32 addrspace(2)*
     65   ret i32 addrspace(2)* %z
     66 }
     67 
     68 define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind {
     69 ; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
     70 ; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
     71 ; CHECK-NEXT: ret
     72   %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
     73   %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)*
     74   ret i32 addrspace(2)* %z
     75 }
     76 
     77 define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind {
     78 ; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
     79 ; CHECK: bitcast i32 addrspace(1)* %x to float addrspace(1)*
     80 ; CHECK: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
     81 ; CHECK-NEXT: ret
     82   %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
     83   %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)*
     84   ret float addrspace(2)* %z
     85 }
     86 
     87 define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
     88 ; CHECK-LABEL: @combine_addrspacecast_types(
     89 ; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)*
     90 ; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)*
     91 ; CHECK-NEXT: ret
     92   %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
     93   ret float addrspace(2)* %y
     94 }
     95 
     96 define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
     97 ; CHECK-LABEL: @combine_addrspacecast_types_vector(
     98 ; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*>
     99 ; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float addrspace(2)*>
    100 ; CHECK-NEXT: ret
    101   %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
    102   ret <4 x float addrspace(2)*> %y
    103 }
    104 
    105 define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) {
    106 ; CHECK-LABEL: @canonicalize_addrspacecast(
    107 ; CHECK-NEXT: getelementptr inbounds [16 x i32], [16 x i32] addrspace(1)* %arr, i32 0, i32 0
    108 ; CHECK-NEXT: addrspacecast i32 addrspace(1)* %{{[a-zA-Z0-9]+}} to i32*
    109 ; CHECK-NEXT: load i32, i32*
    110 ; CHECK-NEXT: ret i32
    111   %p = addrspacecast [16 x i32] addrspace(1)* %arr to i32*
    112   %v = load i32, i32* %p
    113   ret i32 %v
    114 }
    115 
    116 @const_array = addrspace(2) constant [60 x i8] [i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
    117                                                 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
    118                                                 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
    119                                                 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22,
    120                                                 i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22 ]
    121 
    122 declare void @foo(i8*) nounwind
    123 
    124 ; A copy from a constant addrspacecast'ed global
    125 ; CHECK-LABEL: @memcpy_addrspacecast(
    126 ; CHECK-NOT:  call void @llvm.memcpy
    127 define i32 @memcpy_addrspacecast() nounwind {
    128 entry:
    129   %alloca = alloca i8, i32 48
    130   call void @llvm.memcpy.p0i8.p1i8.i32(i8* %alloca, i8 addrspace(1)* addrspacecast (i8 addrspace(2)* getelementptr inbounds ([60 x i8], [60 x i8] addrspace(2)* @const_array, i16 0, i16 4) to i8 addrspace(1)*), i32 48, i32 4, i1 false) nounwind
    131   br label %loop.body
    132 
    133 loop.body:
    134   %i = phi i32 [ 0, %entry ], [ %i.inc, %loop.body ]
    135   %sum = phi i32 [ 0, %entry ], [ %sum.inc, %loop.body]
    136   %ptr = getelementptr i8, i8* %alloca, i32 %i
    137   %load = load i8, i8* %ptr
    138   %ext = zext i8 %load to i32
    139   %sum.inc = add i32 %sum, %ext
    140   %i.inc = add i32 %i, 1
    141   %cmp = icmp ne i32 %i, 48
    142   br i1 %cmp, label %loop.body, label %end
    143 
    144 end:
    145   ret i32 %sum.inc
    146 }
    147 
    148 ; CHECK-LABEL: @constant_fold_null(
    149 ; CHECK: i32 addrspace(3)* null to i32 addrspace(4)*
    150 define void @constant_fold_null() #0 {
    151   %cast = addrspacecast i32 addrspace(3)* null to i32 addrspace(4)*
    152   store i32 7, i32 addrspace(4)* %cast
    153   ret void
    154 }
    155 
    156 ; CHECK-LABEL: @constant_fold_undef(
    157 ; CHECK: ret i32 addrspace(4)* undef
    158 define i32 addrspace(4)* @constant_fold_undef() #0 {
    159   %cast = addrspacecast i32 addrspace(3)* undef to i32 addrspace(4)*
    160   ret i32 addrspace(4)* %cast
    161 }
    162 
    163 ; CHECK-LABEL: @constant_fold_null_vector(
    164 ; CHECK: addrspacecast (<4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>)
    165 define <4 x i32 addrspace(4)*> @constant_fold_null_vector() #0 {
    166   %cast = addrspacecast <4 x i32 addrspace(3)*> zeroinitializer to <4 x i32 addrspace(4)*>
    167   ret <4 x i32 addrspace(4)*> %cast
    168 }
    169 
    170 ; CHECK-LABEL: @constant_fold_inttoptr(
    171 ; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*)
    172 define void @constant_fold_inttoptr() #0 {
    173   %cast = addrspacecast i32 addrspace(3)* inttoptr (i32 -1 to i32 addrspace(3)*) to i32 addrspace(4)*
    174   store i32 7, i32 addrspace(4)* %cast
    175   ret void
    176 }
    177 
    178 ; CHECK-LABEL: @constant_fold_gep_inttoptr(
    179 ; CHECK: addrspacecast (i32 addrspace(3)* inttoptr (i64 1274 to i32 addrspace(3)*) to i32 addrspace(4)*)
    180 define void @constant_fold_gep_inttoptr() #0 {
    181   %k = inttoptr i32 1234 to i32 addrspace(3)*
    182   %gep = getelementptr i32, i32 addrspace(3)* %k, i32 10
    183   %cast = addrspacecast i32 addrspace(3)* %gep to i32 addrspace(4)*
    184   store i32 7, i32 addrspace(4)* %cast
    185   ret void
    186 }
    187