1 2; RUN: opt -S -dxil-flatten-arrays %s | FileCheck %s 3 4; CHECK-LABEL: alloca_2d_test 5define void @alloca_2d_test () { 6; CHECK-NEXT: alloca [9 x i32], align 4 7; CHECK-NEXT: ret void 8; 9 %1 = alloca [3 x [3 x i32]], align 4 10 ret void 11} 12 13; CHECK-LABEL: alloca_3d_test 14define void @alloca_3d_test () { 15; CHECK-NEXT: alloca [8 x i32], align 4 16; CHECK-NEXT: ret void 17; 18 %1 = alloca [2 x[2 x [2 x i32]]], align 4 19 ret void 20} 21 22; CHECK-LABEL: alloca_4d_test 23define void @alloca_4d_test () { 24; CHECK-NEXT: alloca [16 x i32], align 4 25; CHECK-NEXT: ret void 26; 27 %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4 28 ret void 29} 30 31; CHECK-LABEL: gep_2d_test 32define void @gep_2d_test () { 33 ; CHECK: [[a:%.*]] = alloca [9 x i32], align 4 34 ; CHECK-COUNT-9: getelementptr inbounds [9 x i32], ptr [[a]], i32 {{[0-8]}} 35 ; CHECK-NEXT: ret void 36 %1 = alloca [3 x [3 x i32]], align 4 37 %g2d0 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 0 38 %g1d_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 0 39 %g1d_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 1 40 %g1d_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d0, i32 0, i32 2 41 %g2d1 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 1 42 %g1d1_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 0 43 %g1d1_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 1 44 %g1d1_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d1, i32 0, i32 2 45 %g2d2 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i32 0, i32 2 46 %g1d2_1 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 0 47 %g1d2_2 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 1 48 %g1d2_3 = getelementptr inbounds [3 x i32], [3 x i32]* %g2d2, i32 0, i32 2 49 50 ret void 51} 52 53; CHECK-LABEL: gep_3d_test 54define void @gep_3d_test () { 55 ; CHECK: [[a:%.*]] = alloca [8 x i32], align 4 56 ; CHECK-COUNT-8: getelementptr inbounds [8 x i32], ptr [[a]], i32 {{[0-7]}} 57 ; CHECK-NEXT: ret void 58 %1 = alloca [2 x[2 x [2 x i32]]], align 4 59 %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 0 60 %g2d0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 0 61 %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 0 62 %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0, i32 0, i32 1 63 %g2d1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 1 64 %g1d1_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 0 65 %g1d1_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1, i32 0, i32 1 66 %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %1, i32 0, i32 1 67 %g2d2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 0 68 %g1d2_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 0 69 %g1d2_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d2, i32 0, i32 1 70 %g2d3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 1 71 %g1d3_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 0 72 %g1d3_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d3, i32 0, i32 1 73 ret void 74} 75 76; CHECK-LABEL: gep_4d_test 77define void @gep_4d_test () { 78 ; CHECK: [[a:%.*]] = alloca [16 x i32], align 4 79 ; CHECK-COUNT-16: getelementptr inbounds [16 x i32], ptr [[a]], i32 {{[0-9]|1[0-5]}} 80 ; CHECK-NEXT: ret void 81 %1 = alloca [2x[2 x[2 x [2 x i32]]]], align 4 82 %g4d0 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 0 83 %g3d0 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 0 84 %g2d0_0 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 0 85 %g1d_0 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 0 86 %g1d_1 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_0, i32 0, i32 1 87 %g2d0_1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0, i32 0, i32 1 88 %g1d_2 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 0 89 %g1d_3 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_1, i32 0, i32 1 90 %g3d1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d0, i32 0, i32 1 91 %g2d0_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 0 92 %g1d_4 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 0 93 %g1d_5 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_2, i32 0, i32 1 94 %g2d1_2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1, i32 0, i32 1 95 %g1d_6 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 0 96 %g1d_7 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_2, i32 0, i32 1 97 %g4d1 = getelementptr inbounds [2x[2 x[2 x [2 x i32]]]], [2x[2 x[2 x [2 x i32]]]]* %1, i32 0, i32 1 98 %g3d0_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 0 99 %g2d0_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 0 100 %g1d_8 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 0 101 %g1d_9 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_3, i32 0, i32 1 102 %g2d0_4 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d0_1, i32 0, i32 1 103 %g1d_10 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 0 104 %g1d_11 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_4, i32 0, i32 1 105 %g3d1_1 = getelementptr inbounds [2 x[2 x [2 x i32]]], [2 x[2 x [2 x i32]]]* %g4d1, i32 0, i32 1 106 %g2d0_5 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 0 107 %g1d_12 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 0 108 %g1d_13 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d0_5, i32 0, i32 1 109 %g2d1_3 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %g3d1_1, i32 0, i32 1 110 %g1d_14 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 0 111 %g1d_15 = getelementptr inbounds [2 x i32], [2 x i32]* %g2d1_3, i32 0, i32 1 112 ret void 113} 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 4 122 123@b = internal global [2 x [3 x [4 x i32]]] zeroinitializer, align 16 124 125define void @global_gep_load() { 126 ; CHECK: [[GEP_PTR:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 6 127 ; CHECK: load i32, ptr [[GEP_PTR]], align 4 128 ; CHECK-NEXT: ret void 129 %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 0 130 %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 1 131 %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 2 132 %4 = load i32, i32* %3, align 4 133 ret void 134} 135 136define void @global_gep_load_index(i32 %row, i32 %col, i32 %timeIndex) { 137; CHECK-LABEL: define void @global_gep_load_index( 138; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]], i32 [[TIMEINDEX:%.*]]) { 139; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[TIMEINDEX]], 1 140; CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP1]] 141; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[COL]], 4 142; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]] 143; CHECK-NEXT: [[TMP5:%.*]] = mul i32 [[ROW]], 12 144; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP4]], [[TMP5]] 145; CHECK-NEXT: [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 [[TMP6]] 146; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}} 147; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}} 148; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}} 149; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTFLAT]], align 4 150; CHECK-NEXT: ret void 151; 152 %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row 153 %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col 154 %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 %timeIndex 155 %4 = load i32, i32* %3, align 4 156 ret void 157} 158 159define void @global_incomplete_gep_chain(i32 %row, i32 %col) { 160; CHECK-LABEL: define void @global_incomplete_gep_chain( 161; CHECK-SAME: i32 [[ROW:%.*]], i32 [[COL:%.*]]) { 162; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[COL]], 1 163; CHECK-NEXT: [[TMP2:%.*]] = add i32 0, [[TMP1]] 164; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[ROW]], 3 165; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]] 166; CHECK-NEXT: [[DOTFLAT:%.*]] = getelementptr inbounds [24 x i32], ptr @a.1dim, i32 [[TMP4]] 167; CHECK-NOT: getelementptr inbounds [2 x [3 x [4 x i32]]]{{.*}} 168; CHECK-NOT: getelementptr inbounds [3 x [4 x i32]]{{.*}} 169; CHECK-NOT: getelementptr inbounds [4 x i32]{{.*}} 170; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTFLAT]], align 4 171; CHECK-NEXT: ret void 172; 173 %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @a, i32 0, i32 %row 174 %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 %col 175 %4 = load i32, i32* %2, align 4 176 ret void 177} 178 179define void @global_gep_store() { 180 ; CHECK: [[GEP_PTR:%.*]] = getelementptr inbounds [24 x i32], ptr @b.1dim, i32 13 181 ; CHECK: store i32 1, ptr [[GEP_PTR]], align 4 182 ; CHECK-NEXT: ret void 183 %1 = getelementptr inbounds [2 x [3 x [4 x i32]]], [2 x [3 x [4 x i32]]]* @b, i32 0, i32 1 184 %2 = getelementptr inbounds [3 x [4 x i32]], [3 x [4 x i32]]* %1, i32 0, i32 0 185 %3 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i32 0, i32 1 186 store i32 1, i32* %3, align 4 187 ret void 188} 189 190; Make sure we don't try to walk the body of a function declaration. 191declare void @opaque_function() 192