1; RUN: opt -S -mtriple=amdgcn--amdhsa -load-store-vectorizer < %s | FileCheck %s 2 3; Check that vectorizer can find a GEP through bitcast 4; CHECK-LABEL: @vect_zext_bitcast_f32_to_i32_idx 5; CHECK: load <4 x i32> 6define void @vect_zext_bitcast_f32_to_i32_idx(float addrspace(1)* %arg1, i32 %base) { 7 %add1 = add nuw i32 %base, 0 8 %zext1 = zext i32 %add1 to i64 9 %gep1 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext1 10 %f2i1 = bitcast float addrspace(1)* %gep1 to i32 addrspace(1)* 11 %load1 = load i32, i32 addrspace(1)* %f2i1, align 4 12 %add2 = add nuw i32 %base, 1 13 %zext2 = zext i32 %add2 to i64 14 %gep2 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext2 15 %f2i2 = bitcast float addrspace(1)* %gep2 to i32 addrspace(1)* 16 %load2 = load i32, i32 addrspace(1)* %f2i2, align 4 17 %add3 = add nuw i32 %base, 2 18 %zext3 = zext i32 %add3 to i64 19 %gep3 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext3 20 %f2i3 = bitcast float addrspace(1)* %gep3 to i32 addrspace(1)* 21 %load3 = load i32, i32 addrspace(1)* %f2i3, align 4 22 %add4 = add nuw i32 %base, 3 23 %zext4 = zext i32 %add4 to i64 24 %gep4 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext4 25 %f2i4 = bitcast float addrspace(1)* %gep4 to i32 addrspace(1)* 26 %load4 = load i32, i32 addrspace(1)* %f2i4, align 4 27 ret void 28} 29 30; CHECK-LABEL: @vect_zext_bitcast_i8_st1_to_i32_idx 31; CHECK: load i32 32; CHECK: load i32 33; CHECK: load i32 34; CHECK: load i32 35define void @vect_zext_bitcast_i8_st1_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) { 36 %add1 = add nuw i32 %base, 0 37 %zext1 = zext i32 %add1 to i64 38 %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1 39 %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)* 40 %load1 = load i32, i32 addrspace(1)* %f2i1, align 4 41 %add2 = add nuw i32 %base, 1 42 %zext2 = zext i32 %add2 to i64 43 %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2 44 %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)* 45 %load2 = load i32, i32 addrspace(1)* %f2i2, align 4 46 %add3 = add nuw i32 %base, 2 47 %zext3 = zext i32 %add3 to i64 48 %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3 49 %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)* 50 %load3 = load i32, i32 addrspace(1)* %f2i3, align 4 51 %add4 = add nuw i32 %base, 3 52 %zext4 = zext i32 %add4 to i64 53 %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4 54 %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)* 55 %load4 = load i32, i32 addrspace(1)* %f2i4, align 4 56 ret void 57} 58 59; CHECK-LABEL: @vect_zext_bitcast_i8_st4_to_i32_idx 60; CHECK: load <4 x i32> 61define void @vect_zext_bitcast_i8_st4_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) { 62 %add1 = add nuw i32 %base, 0 63 %zext1 = zext i32 %add1 to i64 64 %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1 65 %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)* 66 %load1 = load i32, i32 addrspace(1)* %f2i1, align 4 67 %add2 = add nuw i32 %base, 4 68 %zext2 = zext i32 %add2 to i64 69 %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2 70 %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)* 71 %load2 = load i32, i32 addrspace(1)* %f2i2, align 4 72 %add3 = add nuw i32 %base, 8 73 %zext3 = zext i32 %add3 to i64 74 %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3 75 %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)* 76 %load3 = load i32, i32 addrspace(1)* %f2i3, align 4 77 %add4 = add nuw i32 %base, 12 78 %zext4 = zext i32 %add4 to i64 79 %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4 80 %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)* 81 %load4 = load i32, i32 addrspace(1)* %f2i4, align 4 82 ret void 83} 84 85; CHECK-LABEL: @vect_zext_bitcast_negative_ptr_delta 86; CHECK: load <2 x i32> 87define void @vect_zext_bitcast_negative_ptr_delta(i32 addrspace(1)* %p, i32 %base) { 88 %p.bitcasted = bitcast i32 addrspace(1)* %p to i16 addrspace(1)* 89 %a.offset = add nuw i32 %base, 4 90 %t.offset.zexted = zext i32 %base to i64 91 %a.offset.zexted = zext i32 %a.offset to i64 92 %t.ptr = getelementptr inbounds i16, i16 addrspace(1)* %p.bitcasted, i64 %t.offset.zexted 93 %a.ptr = getelementptr inbounds i16, i16 addrspace(1)* %p.bitcasted, i64 %a.offset.zexted 94 %b.ptr = getelementptr inbounds i16, i16 addrspace(1)* %t.ptr, i64 6 95 %a.ptr.bitcasted = bitcast i16 addrspace(1)* %a.ptr to i32 addrspace(1)* 96 %b.ptr.bitcasted = bitcast i16 addrspace(1)* %b.ptr to i32 addrspace(1)* 97 %a.val = load i32, i32 addrspace(1)* %a.ptr.bitcasted 98 %b.val = load i32, i32 addrspace(1)* %b.ptr.bitcasted 99 ret void 100} 101 102; Check i1 corner case 103; CHECK-LABEL: @zexted_i1_gep_index 104; CHECK: load i32 105; CHECK: load i32 106define void @zexted_i1_gep_index(i32 addrspace(1)* %p, i32 %val) { 107 %selector = icmp eq i32 %val, 0 108 %flipped = xor i1 %selector, 1 109 %index.0 = zext i1 %selector to i64 110 %index.1 = zext i1 %flipped to i64 111 %gep.0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.0 112 %gep.1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.1 113 %val0 = load i32, i32 addrspace(1)* %gep.0 114 %val1 = load i32, i32 addrspace(1)* %gep.1 115 ret void 116} 117 118; Check i1 corner case 119; CHECK-LABEL: @sexted_i1_gep_index 120; CHECK: load i32 121; CHECK: load i32 122define void @sexted_i1_gep_index(i32 addrspace(1)* %p, i32 %val) { 123 %selector = icmp eq i32 %val, 0 124 %flipped = xor i1 %selector, 1 125 %index.0 = sext i1 %selector to i64 126 %index.1 = sext i1 %flipped to i64 127 %gep.0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.0 128 %gep.1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.1 129 %val0 = load i32, i32 addrspace(1)* %gep.0 130 %val1 = load i32, i32 addrspace(1)* %gep.1 131 ret void 132} 133