1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a --passes=separate-const-offset-from-gep < %s | FileCheck %s 3 4define void @sink_addr(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 5; CHECK-LABEL: define void @sink_addr( 6; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0:[0-9]+]] { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 9; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 10; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 11; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 12; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 13; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 14; CHECK-NEXT: [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256 15; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 16; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 17; CHECK-NEXT: [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512 18; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 19; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 20; CHECK-NEXT: [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768 21; CHECK-NEXT: ret void 22; 23entry: 24 %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 25 %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 26 %const1 = getelementptr half, ptr addrspace(3) %base, i64 256 27 %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 28 %const2 = getelementptr half, ptr addrspace(3) %base, i64 512 29 %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 30 %const3 = getelementptr half, ptr addrspace(3) %base, i64 768 31 %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 32 ret void 33} 34 35define void @illegal_addr_mode(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 36; CHECK-LABEL: define void @illegal_addr_mode( 37; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 38; CHECK-NEXT: entry: 39; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 40; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 41; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 42; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 43; CHECK-NEXT: [[CONST1:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38192 44; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 45; CHECK-NEXT: [[IDX1:%.*]] = getelementptr half, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]] 46; CHECK-NEXT: [[CONST2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38448 47; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 48; CHECK-NEXT: [[IDX2:%.*]] = getelementptr half, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]] 49; CHECK-NEXT: [[CONST3:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38764 50; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 51; CHECK-NEXT: [[IDX3:%.*]] = getelementptr half, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]] 52; CHECK-NEXT: ret void 53; 54entry: 55 %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 56 %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 57 %const1 = getelementptr half, ptr addrspace(3) %base, i64 38192 58 %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 59 %const2 = getelementptr half, ptr addrspace(3) %base, i64 38448 60 %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 61 %const3 = getelementptr half, ptr addrspace(3) %base, i64 38764 62 %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 63 ret void 64} 65 66 67define void @reorder_i8half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 68; CHECK-LABEL: define void @reorder_i8half( 69; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 70; CHECK-NEXT: entry: 71; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 72; CHECK-NEXT: [[BASE:%.*]] = getelementptr i8, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 73; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 74; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 75; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 76; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 77; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i64 256 78; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 79; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 80; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i64 512 81; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 82; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 83; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i64 768 84; CHECK-NEXT: ret void 85; 86entry: 87 %base = getelementptr i8, ptr addrspace(3) %in.ptr, i64 %in.idx0 88 %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 89 %const1 = getelementptr i8, ptr addrspace(3) %base, i64 256 90 %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 91 %const2 = getelementptr i8, ptr addrspace(3) %base, i64 512 92 %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 93 %const3 = getelementptr i8, ptr addrspace(3) %base, i64 768 94 %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 95 ret void 96} 97 98define void @reorder_i64half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 99; CHECK-LABEL: define void @reorder_i64half( 100; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 101; CHECK-NEXT: entry: 102; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 103; CHECK-NEXT: [[BASE:%.*]] = getelementptr i64, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 104; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 105; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 106; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 107; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 108; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP0]], i64 256 109; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 110; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 111; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP2]], i64 512 112; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 113; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 114; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP4]], i64 768 115; CHECK-NEXT: ret void 116; 117entry: 118 %base = getelementptr i64, ptr addrspace(3) %in.ptr, i64 %in.idx0 119 %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 120 %const1 = getelementptr i64, ptr addrspace(3) %base, i64 256 121 %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 122 %const2 = getelementptr i64, ptr addrspace(3) %base, i64 512 123 %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 124 %const3 = getelementptr i64, ptr addrspace(3) %base, i64 768 125 %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 126 ret void 127} 128 129define void @reorder_halfi8(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 130; CHECK-LABEL: define void @reorder_halfi8( 131; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 132; CHECK-NEXT: entry: 133; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 134; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 135; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 136; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 137; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 138; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 139; CHECK-NEXT: [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256 140; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 141; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 142; CHECK-NEXT: [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512 143; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 144; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 145; CHECK-NEXT: [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768 146; CHECK-NEXT: ret void 147; 148entry: 149 %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 150 %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 151 %const1 = getelementptr half, ptr addrspace(3) %base, i64 256 152 %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 153 %const2 = getelementptr half, ptr addrspace(3) %base, i64 512 154 %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 155 %const3 = getelementptr half, ptr addrspace(3) %base, i64 768 156 %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 157 ret void 158} 159 160 161 162define void @bad_index(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 163; CHECK-LABEL: define void @bad_index( 164; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 165; CHECK-NEXT: entry: 166; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 167; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 168; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 169; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 170; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 171; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 172; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i64 1 173; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 174; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 175; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i64 2 176; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 177; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 178; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i64 3 179; CHECK-NEXT: ret void 180; 181entry: 182 %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 183 %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 184 %const1 = getelementptr i8, ptr addrspace(3) %base, i64 1 185 %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 186 %const2 = getelementptr i8, ptr addrspace(3) %base, i64 2 187 %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 188 %const3 = getelementptr i8, ptr addrspace(3) %base, i64 3 189 %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 190 ret void 191} 192 193 194%struct.vec = type { [8 x i8], [4 x half] } 195define void @vector_struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 196; CHECK-LABEL: define void @vector_struct_type( 197; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 198; CHECK-NEXT: entry: 199; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 200; CHECK-NEXT: [[BASE:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 201; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 202; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 203; CHECK-NEXT: [[CONST1:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 256 204; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 205; CHECK-NEXT: [[IDX1:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]] 206; CHECK-NEXT: [[CONST2:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 512 207; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 208; CHECK-NEXT: [[IDX2:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]] 209; CHECK-NEXT: [[CONST3:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 768 210; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 211; CHECK-NEXT: [[IDX3:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]] 212; CHECK-NEXT: ret void 213; 214entry: 215 %base = getelementptr [1024 x %struct.vec], ptr addrspace(3) %in.ptr, i64 %in.idx0 216 %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 217 %const1 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 256 218 %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 219 %const2 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 512 220 %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 221 %const3 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 768 222 %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 223 ret void 224} 225 226define void @struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { 227; CHECK-LABEL: define void @struct_type( 228; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 229; CHECK-NEXT: entry: 230; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 231; CHECK-NEXT: [[BASE:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] 232; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 233; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] 234; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 235; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] 236; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP0]], i64 256 237; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 238; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] 239; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP2]], i64 512 240; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 241; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] 242; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP4]], i64 768 243; CHECK-NEXT: ret void 244; 245entry: 246 %base = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0 247 %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 248 %const1 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 256 249 %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 250 %const2 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 512 251 %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 252 %const3 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 768 253 %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 254 ret void 255} 256 257define void @struct_type_multiindex(ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 %in.idx1, i64 %in.idx2) { 258; CHECK-LABEL: define void @struct_type_multiindex( 259; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i32 [[IN_IDX1:%.*]], i64 [[IN_IDX2:%.*]]) #[[ATTR0]] { 260; CHECK-NEXT: entry: 261; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 262; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]], i32 0, i32 0 263; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX2]] to i32 264; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 [[IDXPROM2]] 265; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP1]], i32 2 266; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX0]] to i32 267; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM3]], i32 0, i32 0 268; CHECK-NEXT: [[IDXPROM5:%.*]] = trunc i64 [[IN_IDX2]] to i32 269; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP3]], i32 [[IDXPROM5]] 270; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i32 4 271; CHECK-NEXT: [[IDXPROM6:%.*]] = trunc i64 [[IN_IDX0]] to i32 272; CHECK-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM6]], i32 0, i32 0 273; CHECK-NEXT: [[IDXPROM8:%.*]] = trunc i64 [[IN_IDX2]] to i32 274; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP6]], i32 [[IDXPROM8]] 275; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP7]], i32 6 276; CHECK-NEXT: ret void 277; 278entry: 279 %const1 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 2 280 %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx2 281 %const2 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 4 282 %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx2 283 %const3 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 6 284 %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx2 285 ret void 286} 287 288define void @multiple_index_maybe_neg(ptr %in.ptr, i64 %in.idx1) { 289; CHECK-LABEL: define void @multiple_index_maybe_neg( 290; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 291; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1]] 292; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1 293; CHECK-NEXT: ret void 294; 295 %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1 296 %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1 297 ret void 298} 299 300define void @multiple_index_nonneg(ptr %in.ptr, i64 %in.idx1) { 301; CHECK-LABEL: define void @multiple_index_nonneg( 302; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { 303; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807 304; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1_NNEG]] 305; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1 306; CHECK-NEXT: ret void 307; 308 %in.idx1.nneg = and i64 %in.idx1, 9223372036854775807 309 %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1 310 %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1.nneg 311 ret void 312} 313