| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 |
| ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a --passes=separate-const-offset-from-gep < %s | FileCheck %s |
| |
| define void @sink_addr(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @sink_addr( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr half, ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr half, ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr half, ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @illegal_addr_mode(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @illegal_addr_mode( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[CONST1:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38192 |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX1:%.*]] = getelementptr half, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[CONST2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38448 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX2:%.*]] = getelementptr half, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[CONST3:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i64 38764 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX3:%.*]] = getelementptr half, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr half, ptr addrspace(3) %base, i64 38192 |
| %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr half, ptr addrspace(3) %base, i64 38448 |
| %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr half, ptr addrspace(3) %base, i64 38764 |
| %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| |
| define void @reorder_i8half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @reorder_i8half( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr i8, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[IDX13:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 256 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[IDX25:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i32 512 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[IDX37:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i32 768 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr i8, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr i8, ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr i8, ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr i8, ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @reorder_i64half(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @reorder_i64half( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr i64, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP0]], i64 256 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP2]], i64 512 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i64, ptr addrspace(3) [[TMP4]], i64 768 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr i64, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr i64, ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr i64, ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr i64, ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @reorder_halfi8(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @reorder_halfi8( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr half, ptr addrspace(3) [[TMP0]], i64 256 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr half, ptr addrspace(3) [[TMP2]], i64 512 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr half, ptr addrspace(3) [[TMP4]], i64 768 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr half, ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr half, ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr half, ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| |
| |
| define void @bad_index(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @bad_index( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr half, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[IDX13:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i32 1 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[IDX25:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP2]], i32 2 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr half, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[IDX37:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 3 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr half, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr half, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr i8, ptr addrspace(3) %base, i64 1 |
| %idx1 = getelementptr half, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr i8, ptr addrspace(3) %base, i64 2 |
| %idx2 = getelementptr half, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr i8, ptr addrspace(3) %base, i64 3 |
| %idx3 = getelementptr half, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| |
| %struct.vec = type { [8 x i8], [4 x half] } |
| define void @vector_struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @vector_struct_type( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[CONST1:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 256 |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX1:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST1]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[CONST2:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 512 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX2:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST2]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[CONST3:%.*]] = getelementptr [1024 x %struct.vec], ptr addrspace(3) [[BASE]], i64 768 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX3:%.*]] = getelementptr i8, ptr addrspace(3) [[CONST3]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr [1024 x %struct.vec], ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr [1024 x %struct.vec], ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @struct_type(ptr addrspace(3) %in.ptr, i64 %in.idx0, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @struct_type( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[BASE:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]] |
| ; CHECK-NEXT: [[IDXPROM1:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[IDX0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM1]] |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP0]], i64 256 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM3]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP2]], i64 512 |
| ; CHECK-NEXT: [[IDXPROM4:%.*]] = trunc i64 [[IN_IDX1]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[BASE]], i32 [[IDXPROM4]] |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[TMP4]], i64 768 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %base = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0 |
| %idx0 = getelementptr i8, ptr addrspace(3) %base, i64 %in.idx1 |
| %const1 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 256 |
| %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx1 |
| %const2 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 512 |
| %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx1 |
| %const3 = getelementptr %struct.vec, ptr addrspace(3) %base, i64 768 |
| %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @struct_type_multiindex(ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 %in.idx1, i64 %in.idx2) { |
| ; CHECK-LABEL: define void @struct_type_multiindex( |
| ; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX0:%.*]], i32 [[IN_IDX1:%.*]], i64 [[IN_IDX2:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_VEC:%.*]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]], i32 0, i32 0 |
| ; CHECK-NEXT: [[IDXPROM2:%.*]] = trunc i64 [[IN_IDX2]] to i32 |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i32 [[IDXPROM2]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP1]], i32 2 |
| ; CHECK-NEXT: [[IDXPROM3:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM3]], i32 0, i32 0 |
| ; CHECK-NEXT: [[IDXPROM5:%.*]] = trunc i64 [[IN_IDX2]] to i32 |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP3]], i32 [[IDXPROM5]] |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP4]], i32 4 |
| ; CHECK-NEXT: [[IDXPROM6:%.*]] = trunc i64 [[IN_IDX0]] to i32 |
| ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_VEC]], ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM6]], i32 0, i32 0 |
| ; CHECK-NEXT: [[IDXPROM8:%.*]] = trunc i64 [[IN_IDX2]] to i32 |
| ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP6]], i32 [[IDXPROM8]] |
| ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP7]], i32 6 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %const1 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 2 |
| %idx1 = getelementptr i8, ptr addrspace(3) %const1, i64 %in.idx2 |
| %const2 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 4 |
| %idx2 = getelementptr i8, ptr addrspace(3) %const2, i64 %in.idx2 |
| %const3 = getelementptr %struct.vec, ptr addrspace(3) %in.ptr, i64 %in.idx0, i32 0, i32 6 |
| %idx3 = getelementptr i8, ptr addrspace(3) %const3, i64 %in.idx2 |
| ret void |
| } |
| |
| define void @multiple_index_maybe_neg(ptr %in.ptr, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @multiple_index_maybe_neg( |
| ; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1 |
| %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1 |
| ret void |
| } |
| |
| define void @multiple_index_nonneg(ptr %in.ptr, i64 %in.idx1) { |
| ; CHECK-LABEL: define void @multiple_index_nonneg( |
| ; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807 |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[IN_PTR]], i64 0, i64 [[IN_IDX1_NNEG]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x <2 x i8>], ptr [[TMP1]], i64 0, i64 1 |
| ; CHECK-NEXT: ret void |
| ; |
| %in.idx1.nneg = and i64 %in.idx1, 9223372036854775807 |
| %const1 = getelementptr inbounds [2 x <2 x i8>], ptr %in.ptr, i64 0, i64 1 |
| %idx1 = getelementptr inbounds [2 x <2 x i8>], ptr %const1, i64 0, i64 %in.idx1.nneg |
| ret void |
| } |