277 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s3target datalayout = "e-p:32:32:32-p1:64:64:64-p2:8:8:8-p3:16:16:16-p4:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32"4 5@g = addrspace(3) global i32 896 7@const_zero_i8_as1 = addrspace(1) constant i8 08@const_zero_i32_as1 = addrspace(1) constant i32 09 10@const_zero_i8_as2 = addrspace(2) constant i8 011@const_zero_i32_as2 = addrspace(2) constant i32 012 13@const_zero_i8_as3 = addrspace(3) constant i8 014@const_zero_i32_as3 = addrspace(3) constant i32 015 16; Test constant folding of inttoptr (ptrtoint constantexpr)17; The intermediate integer size is the same as the pointer size18define ptr addrspace(3) @test_constant_fold_inttoptr_as_pointer_same_size() {19; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_same_size(20; CHECK-NEXT: ret ptr addrspace(3) @const_zero_i32_as321;22 %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i3223 %y = inttoptr i32 %x to ptr addrspace(3)24 ret ptr addrspace(3) %y25}26 27; The intermediate integer size is larger than the pointer size28define ptr addrspace(2) @test_constant_fold_inttoptr_as_pointer_smaller() {29; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller(30; CHECK-NEXT: ret ptr addrspace(2) @const_zero_i32_as231;32 %x = ptrtoint ptr addrspace(2) @const_zero_i32_as2 to i1633 %y = inttoptr i16 %x to ptr addrspace(2)34 ret ptr addrspace(2) %y35}36 37; Different address spaces that are the same size, but they are38; different so nothing should happen39define ptr addrspace(4) @test_constant_fold_inttoptr_as_pointer_smaller_different_as() {40; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_as(41; CHECK-NEXT: ret ptr addrspace(4) inttoptr (i16 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i16) to ptr addrspace(4))42;43 %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i1644 %y = inttoptr i16 %x to ptr addrspace(4)45 ret ptr addrspace(4) %y46}47 48; Make sure we don't introduce a bitcast between different sized49; address spaces when folding this50define ptr addrspace(2) @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as() {51; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_smaller_different_size_as(52; CHECK-NEXT: ret ptr addrspace(2) inttoptr (i32 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i32) to ptr addrspace(2))53;54 %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i3255 %y = inttoptr i32 %x to ptr addrspace(2)56 ret ptr addrspace(2) %y57}58 59; The intermediate integer size is too small, nothing should happen60define ptr addrspace(3) @test_constant_fold_inttoptr_as_pointer_larger() {61; CHECK-LABEL: @test_constant_fold_inttoptr_as_pointer_larger(62; CHECK-NEXT: ret ptr addrspace(3) inttoptr (i8 ptrtoint (ptr addrspace(3) @const_zero_i32_as3 to i8) to ptr addrspace(3))63;64 %x = ptrtoint ptr addrspace(3) @const_zero_i32_as3 to i865 %y = inttoptr i8 %x to ptr addrspace(3)66 ret ptr addrspace(3) %y67}68 69define i8 @const_fold_ptrtoint() {70; CHECK-LABEL: @const_fold_ptrtoint(71; CHECK-NEXT: ret i8 472;73 ret i8 ptrtoint (ptr addrspace(2) inttoptr (i4 4 to ptr addrspace(2)) to i8)74}75 76; Test that mask happens when the destination pointer is smaller than77; the original78define i8 @const_fold_ptrtoint_mask() {79; CHECK-LABEL: @const_fold_ptrtoint_mask(80; CHECK-NEXT: ret i8 181;82 ret i8 ptrtoint (ptr addrspace(3) inttoptr (i32 257 to ptr addrspace(3)) to i8)83}84 85; Address space 0 is too small for the correct mask, should mask with86; 64-bits instead of 3287define i64 @const_fold_ptrtoint_mask_small_as0() {88; CHECK-LABEL: @const_fold_ptrtoint_mask_small_as0(89; CHECK-NEXT: ret i64 -190;91 ret i64 ptrtoint (ptr addrspace(1) inttoptr (i128 -1 to ptr addrspace(1)) to i64)92}93 94define ptr addrspace(3) @const_inttoptr() {95; CHECK-LABEL: @const_inttoptr(96; CHECK-NEXT: ret ptr addrspace(3) inttoptr (i16 4 to ptr addrspace(3))97;98 %p = inttoptr i16 4 to ptr addrspace(3)99 ret ptr addrspace(3) %p100}101 102define i16 @const_ptrtoint() {103; CHECK-LABEL: @const_ptrtoint(104; CHECK-NEXT: ret i16 ptrtoint (ptr addrspace(3) @g to i16)105;106 %i = ptrtoint ptr addrspace(3) @g to i16107 ret i16 %i108}109 110define i16 @const_inttoptr_ptrtoint() {111; CHECK-LABEL: @const_inttoptr_ptrtoint(112; CHECK-NEXT: ret i16 9113;114 ret i16 ptrtoint (ptr addrspace(3) inttoptr (i16 9 to ptr addrspace(3)) to i16)115}116 117define i1 @constant_fold_cmp_constantexpr_inttoptr() {118; CHECK-LABEL: @constant_fold_cmp_constantexpr_inttoptr(119; CHECK-NEXT: ret i1 true120;121 %x = icmp eq ptr addrspace(3) inttoptr (i16 0 to ptr addrspace(3)), null122 ret i1 %x123}124 125define i1 @constant_fold_inttoptr_null(i16 %i) {126; CHECK-LABEL: @constant_fold_inttoptr_null(127; CHECK-NEXT: ret i1 false128;129 %x = icmp eq ptr addrspace(3) inttoptr (i16 99 to ptr addrspace(3)), inttoptr (i16 0 to ptr addrspace(3))130 ret i1 %x131}132 133define i1 @constant_fold_ptrtoint_null() {134; CHECK-LABEL: @constant_fold_ptrtoint_null(135; CHECK-NEXT: [[X:%.*]] = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), 0136; CHECK-NEXT: ret i1 [[X]]137;138 %x = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), ptrtoint (ptr addrspace(3) null to i16)139 ret i1 %x140}141 142define i1 @constant_fold_ptrtoint_null_2() {143; CHECK-LABEL: @constant_fold_ptrtoint_null_2(144; CHECK-NEXT: [[X:%.*]] = icmp eq i16 0, ptrtoint (ptr addrspace(3) @g to i16)145; CHECK-NEXT: ret i1 [[X]]146;147 %x = icmp eq i16 ptrtoint (ptr addrspace(3) null to i16), ptrtoint (ptr addrspace(3) @g to i16)148 ret i1 %x149}150 151define i1 @constant_fold_ptrtoint() {152; CHECK-LABEL: @constant_fold_ptrtoint(153; CHECK-NEXT: ret i1 true154;155 %x = icmp eq i16 ptrtoint (ptr addrspace(3) @g to i16), ptrtoint (ptr addrspace(3) @g to i16)156 ret i1 %x157}158 159define i1 @constant_fold_inttoptr() {160; CHECK-LABEL: @constant_fold_inttoptr(161; CHECK-NEXT: ret i1 false162;163 %x = icmp eq ptr addrspace(3) inttoptr (i16 99 to ptr addrspace(3)), inttoptr (i16 27 to ptr addrspace(3))164 ret i1 %x165}166 167@g_float_as3 = addrspace(3) global float zeroinitializer168@g_v4f_as3 = addrspace(3) global <4 x float> zeroinitializer169 170define float @constant_fold_bitcast_ftoi_load() {171; CHECK-LABEL: @constant_fold_bitcast_ftoi_load(172; CHECK-NEXT: [[A:%.*]] = load float, ptr addrspace(3) @g, align 4173; CHECK-NEXT: ret float [[A]]174;175 %a = load float, ptr addrspace(3) @g, align 4176 ret float %a177}178 179define i32 @constant_fold_bitcast_itof_load() {180; CHECK-LABEL: @constant_fold_bitcast_itof_load(181; CHECK-NEXT: [[A:%.*]] = load i32, ptr addrspace(3) @g_float_as3, align 4182; CHECK-NEXT: ret i32 [[A]]183;184 %a = load i32, ptr addrspace(3) @g_float_as3, align 4185 ret i32 %a186}187 188define <4 x float> @constant_fold_bitcast_vector_as() {189; CHECK-LABEL: @constant_fold_bitcast_vector_as(190; CHECK-NEXT: [[A:%.*]] = load <4 x float>, ptr addrspace(3) @g_v4f_as3, align 4191; CHECK-NEXT: ret <4 x float> [[A]]192;193 %a = load <4 x float>, ptr addrspace(3) @g_v4f_as3, align 4194 ret <4 x float> %a195}196 197@i32_array_as3 = addrspace(3) global [10 x i32] zeroinitializer198 199define i32 @test_cast_gep_small_indices_as() {200; CHECK-LABEL: @test_cast_gep_small_indices_as(201; CHECK-NEXT: [[X:%.*]] = load i32, ptr addrspace(3) @i32_array_as3, align 4202; CHECK-NEXT: ret i32 [[X]]203;204 %x = load i32, ptr addrspace(3) @i32_array_as3, align 4205 ret i32 %x206}207 208%struct.foo = type { float, float, [4 x i32], ptr addrspace(3) }209 210@constant_fold_global_ptr = addrspace(3) global %struct.foo {211 float 0.0,212 float 0.0,213 [4 x i32] zeroinitializer,214 ptr addrspace(3) @i32_array_as3215}216 217define i32 @test_cast_gep_large_indices_as() {218; CHECK-LABEL: @test_cast_gep_large_indices_as(219; CHECK-NEXT: [[X:%.*]] = load i32, ptr addrspace(3) @i32_array_as3, align 4220; CHECK-NEXT: ret i32 [[X]]221;222 %x = load i32, ptr addrspace(3) @i32_array_as3, align 4223 ret i32 %x224}225 226define i32 @test_constant_cast_gep_struct_indices_as() {227; CHECK-LABEL: @test_constant_cast_gep_struct_indices_as(228; CHECK-NEXT: [[Y:%.*]] = load i32, ptr addrspace(3) getelementptr inbounds nuw (i8, ptr addrspace(3) @constant_fold_global_ptr, i16 16), align 4229; CHECK-NEXT: ret i32 [[Y]]230;231 %x = getelementptr %struct.foo, ptr addrspace(3) @constant_fold_global_ptr, i18 0, i32 2, i12 2232 %y = load i32, ptr addrspace(3) %x, align 4233 ret i32 %y234}235 236@constant_data_as3 = addrspace(3) constant [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5]237 238define i32 @test_read_data_from_global_as3() {239; CHECK-LABEL: @test_read_data_from_global_as3(240; CHECK-NEXT: ret i32 2241;242 %x = getelementptr [5 x i32], ptr addrspace(3) @constant_data_as3, i32 0, i32 1243 %y = load i32, ptr addrspace(3) %x, align 4244 ret i32 %y245}246 247@a = addrspace(1) constant i32 9248@b = addrspace(1) constant i32 23249@c = addrspace(1) constant i32 34250@d = addrspace(1) constant i32 99251 252@ptr_array = addrspace(2) constant [4 x ptr addrspace(1)] [ ptr addrspace(1) @a, ptr addrspace(1) @b, ptr addrspace(1) @c, ptr addrspace(1) @d]253@indirect = addrspace(0) constant ptr addrspace(2) getelementptr inbounds ([4 x ptr addrspace(1)], ptr addrspace(2) @ptr_array, i1 0, i32 2)254 255define i32 @constant_through_array_as_ptrs() {256; CHECK-LABEL: @constant_through_array_as_ptrs(257; CHECK-NEXT: ret i32 34258;259 %p = load ptr addrspace(2), ptr addrspace(0) @indirect, align 4260 %a = load ptr addrspace(1), ptr addrspace(2) %p, align 4261 %b = load i32, ptr addrspace(1) %a, align 4262 ret i32 %b263}264 265@shared_mem = external addrspace(3) global [0 x i8]266 267define float @canonicalize_addrspacecast(i32 %i) {268; CHECK-LABEL: @canonicalize_addrspacecast(269; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds float, ptr addrspacecast (ptr addrspace(3) @shared_mem to ptr), i32 [[I:%.*]]270; CHECK-NEXT: [[V:%.*]] = load float, ptr [[P]], align 4271; CHECK-NEXT: ret float [[V]]272;273 %p = getelementptr inbounds float, ptr addrspacecast (ptr addrspace(3) @shared_mem to ptr), i32 %i274 %v = load float, ptr %p275 ret float %v276}277