brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.1 KiB · a2e1055 Raw
332 lines · plain
1 2; RUN: opt -S -dxil-flatten-arrays  %s | FileCheck %s3 4; CHECK-LABEL: alloca_2d_test5define void @alloca_2d_test ()  {6; CHECK-NEXT:    alloca [9 x i32], align 47; CHECK-NEXT:    ret void8;9  %1 = alloca [3 x [3 x i32]], align 410  ret void11}12 13; CHECK-LABEL: alloca_3d_test14define void @alloca_3d_test ()  {15; CHECK-NEXT:    alloca [8 x i32], align 416; CHECK-NEXT:    ret void17;18  %1 = alloca [2 x[2 x [2 x i32]]], align 419  ret void20}21 22; CHECK-LABEL: alloca_4d_test23define void @alloca_4d_test ()  {24; CHECK-NEXT:    alloca [16 x i32], align 425; CHECK-NEXT:    ret void26;27  %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 428  ret void29}30 31; CHECK-LABEL: gep_2d_test32define void @gep_2d_test ()  {33    ; CHECK: [[a:%.*]] = alloca [9 x i32], align 434    ; CHECK-COUNT-9: getelementptr inbounds [9 x i32], ptr [[a]], i32 0, i32 {{[0-8]}}35    ; CHECK-NEXT:    ret void36    %1 = alloca [3 x [3 x i32]], align 437    %g2d0 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 038    %g1d_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 039    %g1d_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 140    %g1d_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 241    %g2d1 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 142    %g1d1_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 043    %g1d1_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 144    %g1d1_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 245    %g2d2 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 246    %g1d2_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 047    %g1d2_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 148    %g1d2_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 249    50    ret void51}52 53; CHECK-LABEL: gep_3d_test54define void @gep_3d_test ()  {55    ; CHECK: [[a:%.*]] = alloca [8 x i32], align 456    ; CHECK-COUNT-8: getelementptr inbounds [8 x i32], ptr [[a]], i32 0, i32 {{[0-7]}}57    ; CHECK-NEXT:    ret void58    %1 = alloca [2 x[2 x [2 x i32]]], align 459    %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 060    %g2d0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 061    %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 062    %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 163    %g2d1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 164    %g1d1_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 065    %g1d1_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 166    %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 167    %g2d2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 068    %g1d2_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 069    %g1d2_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 170    %g2d3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 171    %g1d3_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 072    %g1d3_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 173    ret void74}75 76; CHECK-LABEL: gep_4d_test77define void @gep_4d_test ()  {78    ; CHECK: [[a:%.*]] = alloca [16 x i32], align 479    ; CHECK-COUNT-16: getelementptr inbounds [16 x i32], ptr [[a]], i32 0, i32 {{[0-9]|1[0-5]}}80    ; CHECK-NEXT:    ret void81    %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 482    %g4d0 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 083    %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 084    %g2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 085    %g1d_0 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 086    %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 187    %g2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 188    %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 089    %g1d_3 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 190    %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 191    %g2d0_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 092    %g1d_4 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 093    %g1d_5 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 194    %g2d1_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 195    %g1d_6 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 096    %g1d_7 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 197    %g4d1 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 198    %g3d0_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 099    %g2d0_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 0100    %g1d_8 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 0101    %g1d_9 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 1102    %g2d0_4 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 1103    %g1d_10 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 0104    %g1d_11 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 1105    %g3d1_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 1106    %g2d0_5 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 0107    %g1d_12 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 0108    %g1d_13 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 1109    %g2d1_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 1110    %g1d_14 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 0111    %g1d_15 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 1112    ret void113}114 115 116@a = internal global [2 x [3 x [4 x i32]]] [[3 x [4 x i32]] [[4 x i32] [i32 0, i32 1, i32 2, i32 3], 117                                                             [4 x i32] [i32 4, i32 5, i32 6, i32 7], 118                                                             [4 x i32] [i32 8, i32 9, i32 10, i32 11]], 119                                            [3 x [4 x i32]] [[4 x i32] [i32 12, i32 13, i32 14, i32 15], 120                                                             [4 x i32] [i32 16, i32 17, i32 18, i32 19], 121                                                             [4 x i32] [i32 20, i32 21, i32 22, i32 23]]], align 4122 123@b = internal global [2 x [3 x [4 x i32]]] zeroinitializer, align 16124 125define void @global_gep_load() {126  ; CHECK-LABEL: define void @global_gep_load(127  ; CHECK: {{.*}} = load i32, ptr getelementptr inbounds ([24 x i32], ptr @a.1dim, i32 0, i32 6), align 4128  ; CHECK-NEXT:    ret void129  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 0130  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 1131  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 2132  %4 = load i32, i32* %3, align 4133  ret void134}135 136define void @global_nested_geps() {137  ; CHECK-LABEL: define void @global_nested_geps(138  ; CHECK: {{.*}} = load i32, ptr getelementptr inbounds ([24 x i32], ptr @a.1dim, i32 0, i32 6), align 4139  ; CHECK-NEXT:    ret void140  %1 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* getelementptr inbounds ([3 x [4 x i32]], [3 x [4 x i32]]* getelementptr inbounds ([2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 0), i32 0, i32 1), i32 0, i32 2), align 4141  ret void142}143 144define void @global_gep_load_index(i32 %row, i32 %col, i32 %timeIndex) {145; CHECK-LABEL: define void @global_gep_load_index(146; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]], i32 [[TIMEINDEX:%.*]]) {147; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[TIMEINDEX]], 1148; CHECK-NEXT:    [[TMP2:%.*]] = add i32 0, [[TMP1]]149; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[COL]], 4150; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]151; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[ROW]], 12152; CHECK-NEXT:    [[TMP6:%.*]] = add i32 [[TMP4]], [[TMP5]]153; CHECK-NEXT:    [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 0, i32 [[TMP6]]154; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}}155; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}}156; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}}157; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTFLAT]], align 4158; CHECK-NEXT:    ret void159;160  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row161  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col162  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 %timeIndex163  %4 = load i32, i32* %3, align 4164  ret void165}166 167define void @global_incomplete_gep_chain(i32 %row, i32 %col) {168; CHECK-LABEL: define void @global_incomplete_gep_chain(169; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]]) {170; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[COL]], 4171; CHECK-NEXT:    [[TMP2:%.*]] = add i32 0, [[TMP1]]172; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[ROW]], 12173; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]174; CHECK-NEXT:    [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 0, i32 [[TMP4]]175; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}}176; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}}177; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}}178; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTFLAT]], align 4179; CHECK-NEXT:    ret void180;181  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row182  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col183  %4 = load i32, i32* %2, align 4184  ret void185}186 187define void @global_gep_store() {188  ; CHECK: store i32 1, ptr getelementptr inbounds ([24 x i32], ptr @b.1dim, i32 0, i32 13), align 4189  ; CHECK-NEXT:    ret void190  %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @b, i32 0, i32 1191  %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 0192  %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 1193  store i32 1, i32* %3, align 4194  ret void195}196 197@g = local_unnamed_addr addrspace(3) global [2 x [2 x float]] zeroinitializer, align 4198define void @two_index_gep() {199  ; CHECK-LABEL: define void @two_index_gep(200  ; CHECK: [[THREAD_ID:%.*]] =  tail call i32 @llvm.dx.thread.id(i32 0)201  ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[THREAD_ID]], 2202  ; CHECK-NEXT: [[ADD:%.*]] = add i32 1, [[MUL]]203  ; CHECK-NEXT: [[GEP_PTR:%.*]] = getelementptr inbounds nuw [4 x float], ptr addrspace(3) @g.1dim, i32 0, i32 [[ADD]]204  ; CHECK-NEXT: load float, ptr addrspace(3) [[GEP_PTR]], align 4205  ; CHECK-NEXT: ret void206  %1 = tail call i32 @llvm.dx.thread.id(i32 0)207  %2 = getelementptr inbounds nuw [2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 %1, i32 1208  %3 = load float, ptr addrspace(3) %2, align 4209  ret void210}211 212define void @two_index_gep_const() {213  ; CHECK-LABEL: define void @two_index_gep_const(214  ; CHECK-NEXT: load float, ptr addrspace(3) getelementptr inbounds nuw ([4 x float], ptr addrspace(3) @g.1dim, i32 0, i32 3), align 4215  ; CHECK-NEXT: ret void216  %1 = getelementptr inbounds nuw [2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 1, i32 1217  %3 = load float, ptr addrspace(3) %1, align 4218  ret void219}220 221define void @zero_index_global() {222  ; CHECK-LABEL: define void @zero_index_global(223  ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [4 x float], ptr addrspace(3) @g.1dim, i32 0, i32 0224  ; CHECK-NEXT: load float, ptr addrspace(3) [[GEP]], align 4225  ; CHECK-NEXT: ret void226  %1 = getelementptr inbounds nuw [2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 0, i32 0227  %2 = load float, ptr addrspace(3) %1, align 4228  ret void229}230 231; Note: A ConstantExpr GEP with all 0 indices is equivalent to the pointer232; operand of the GEP. Therefore the visitLoadInst will not see the pointer operand233; as a ConstantExpr GEP and will not create a GEP instruction to be visited.234; The later dxil-legalize pass will insert a GEP in this instance.235define void @zero_index_global_const() {236  ; CHECK-LABEL: define void @zero_index_global_const(237  ; CHECK-NEXT: load float, ptr addrspace(3) @g.1dim, align 4238  ; CHECK-NEXT: ret void239  %1 = load float, ptr addrspace(3) getelementptr inbounds nuw ([2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 0, i32 0), align 4240  ret void241}242 243define void @gep_4d_index_test()  {244    ; CHECK-LABEL: gep_4d_index_test245    ; CHECK: [[a:%.*]] = alloca [16 x i32], align 4246    ; CHECK-NEXT: getelementptr inbounds [16 x i32], ptr %.1dim, i32 0, i32 1247    ; CHECK-NEXT: getelementptr inbounds [16 x i32], ptr %.1dim, i32 0, i32 3248    ; CHECK-NEXT: getelementptr inbounds [16 x i32], ptr %.1dim, i32 0, i32 7249    ; CHECK-NEXT: getelementptr inbounds [16 x i32], ptr %.1dim, i32 0, i32 15250    ; CHECK-NEXT:    ret void251    %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4252    %2 = getelementptr inbounds [2 x [2 x[2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 0, i32 0, i32 0, i32 1253    %3 = getelementptr inbounds [2 x [2 x[2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 0, i32 0, i32 1, i32 1254    %4 = getelementptr inbounds [2 x [2 x[2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 0, i32 1, i32 1, i32 1255    %5 = getelementptr inbounds [2 x [2 x[2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 1, i32 1, i32 1, i32 1256    ret void257}258 259define void @gep_4d_index_and_gep_chain_mixed() {260  ; CHECK-LABEL: gep_4d_index_and_gep_chain_mixed261  ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [16 x i32], align 4262  ; CHECK-COUNT-16: getelementptr inbounds [16 x i32], ptr [[ALLOCA]], i32 0, i32 {{[0-9]|1[0-5]}}263  ; CHECK-NEXT: ret void264  %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4265  %a4d0_0 = getelementptr inbounds [2 x [2 x [2 x [2 x i32]]]], [2 x [2 x[2 x [2 x i32]]]]* %1, i32 0, i32 0, i32 0266  %a2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %a4d0_0, i32 0, i32 0, i32 0267  %a2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %a4d0_0, i32 0, i32 0, i32 1268  %a2d1_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %a4d0_0, i32 0, i32 1, i32 0269  %a2d1_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %a4d0_0, i32 0, i32 1, i32 1270  %b4d0_1 = getelementptr inbounds [2 x [2 x [2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 0, i32 1271  %b2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %b4d0_1, i32 0, i32 0, i32 0272  %b2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %b4d0_1, i32 0, i32 0, i32 1273  %b2d1_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %b4d0_1, i32 0, i32 1, i32 0274  %b2d1_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %b4d0_1, i32 0, i32 1, i32 1275  %c4d1_0 = getelementptr inbounds [2 x [2 x [2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 1, i32 0276  %c2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %c4d1_0, i32 0, i32 0, i32 0277  %c2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %c4d1_0, i32 0, i32 0, i32 1278  %c2d1_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %c4d1_0, i32 0, i32 1, i32 0279  %c2d1_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %c4d1_0, i32 0, i32 1, i32 1280  %g4d1_1 = getelementptr inbounds [2 x [2 x [2 x [2 x i32]]]], [2 x [2 x [2 x [2 x i32]]]]* %1, i32 0, i32 1, i32 1281  %g2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g4d1_1, i32 0, i32 0, i32 0282  %g2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g4d1_1, i32 0, i32 0, i32 1283  %g2d1_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g4d1_1, i32 0, i32 1, i32 0284  %g2d1_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g4d1_1, i32 0, i32 1, i32 1285  ret void286}287 288; This test demonstrates that the collapsing of GEP chains occurs regardless of289; the source element type given to the GEP. As long as the root pointer being290; indexed to is an aggregate data structure, the GEP will be flattened.291define void @gep_scalar_flatten() {292  ; CHECK-LABEL: gep_scalar_flatten293  ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [24 x i32]294  ; CHECK-NEXT: getelementptr inbounds nuw [24 x i32], ptr [[ALLOCA]], i32 0, i32 17295  ; CHECK-NEXT: getelementptr inbounds nuw [24 x i32], ptr [[ALLOCA]], i32 0, i32 17296  ; CHECK-NEXT: getelementptr inbounds nuw [24 x i32], ptr [[ALLOCA]], i32 0, i32 23297  ; CHECK-NEXT: ret void298  %a = alloca [2 x [3 x [4 x i32]]], align 4299  %i8root = getelementptr inbounds nuw i8, [2 x [3 x [4 x i32]]]* %a, i32 68 ; %a[1][1][1]300  %i32root = getelementptr inbounds nuw i32, [2 x [3 x [4 x i32]]]* %a, i32 17 ; %a[1][1][1]301  %c0 = getelementptr inbounds nuw [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* %a, i32 0, i32 1 ; %a[1]302  %c1 = getelementptr inbounds nuw i32, [3 x [4 x i32]]* %c0, i32 8 ; %a[1][2]303  %c2 = getelementptr inbounds nuw i8, [4 x i32]* %c1, i32 12 ; %a[1][2][3]304  ret void305}306 307define void @gep_scalar_flatten_dynamic(i32 %index) {308  ; CHECK-LABEL: gep_scalar_flatten_dynamic309  ; CHECK-SAME: i32 [[INDEX:%.*]]) {310  ; CHECK-NEXT:  [[ALLOCA:%.*]] = alloca [6 x i32], align 4311  ; CHECK-NEXT:  [[I8INDEX:%.*]] = mul i32 [[INDEX]], 12312  ; CHECK-NEXT:  [[MUL:%.*]] = mul i32 [[I8INDEX]], 1313  ; CHECK-NEXT:  [[DIV:%.*]] = lshr i32 [[MUL]], 2314  ; CHECK-NEXT:  [[ADD:%.*]] = add i32 0, [[DIV]]315  ; CHECK-NEXT:  getelementptr inbounds nuw [6 x i32], ptr [[ALLOCA]], i32 0, i32 [[ADD]]316  ; CHECK-NEXT:  [[I32INDEX:%.*]] = mul i32 [[INDEX]], 3317  ; CHECK-NEXT:  [[MUL:%.*]] = mul i32 [[I32INDEX]], 1318  ; CHECK-NEXT:  [[ADD:%.*]] = add i32 0, [[MUL]]319  ; CHECK-NEXT:  getelementptr inbounds nuw [6 x i32], ptr [[ALLOCA]], i32 0, i32 [[ADD]]320  ; CHECK-NEXT:  ret void321  ;322  %a = alloca [2 x [3 x i32]], align 4323  %i8index = mul i32 %index, 12324  %i8root = getelementptr inbounds nuw i8, [2 x [3 x i32]]* %a, i32 %i8index;325  %i32index = mul i32 %index, 3326  %i32root = getelementptr inbounds nuw i32, [2 x [3 x i32]]* %a, i32 %i32index;327  ret void328}329 330; Make sure we don't try to walk the body of a function declaration.331declare void @opaque_function()332