1; RUN: opt -instcombine -S < %s | FileCheck %s 2 3target datalayout = "e-p:64:64:64-p1:32:32:32-p2:16:16:16-n8:16:32:64" 4 5 6declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) nounwind 7declare void @llvm.memcpy.p0i8.p1i8.i32(i8*, i8 addrspace(1)*, i32, i32, i1) nounwind 8declare void @llvm.memcpy.p0i8.p2i8.i32(i8*, i8 addrspace(2)*, i32, i32, i1) nounwind 9 10 11define 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 20define <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 29define 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 39define <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 49define 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 59define 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 68define 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 77define 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 87define 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 96define <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 105define 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 122declare 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 127define i32 @memcpy_addrspacecast() nounwind { 128entry: 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 133loop.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 144end: 145 ret i32 %sum.inc 146} 147 148; CHECK-LABEL: @constant_fold_null( 149; CHECK: i32 addrspace(3)* null to i32 addrspace(4)* 150define 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 158define 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)*>) 165define <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)*) 172define 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)*) 180define 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