brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.3 KiB · 0c9f6d9 Raw
232 lines · plain
1// RUN: tco %s | FileCheck %s2// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s3 4// Test applying slice on fir.box5//   subroutine foo(x)6//     real :: x(3:, 4:)7//     call bar(x(5, 6:80:3))8//   end subroutine9 10func.func private @bar1(!fir.box<!fir.array<?xf32>>)11// CHECK-LABEL: define void @test_rebox_1(12// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])13func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {14  // CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }15  %c2 = arith.constant 2 : index16  %c3 = arith.constant 3 : index17  %c4 = arith.constant 4 : index18  %c5 = arith.constant 5 : index19  %c6 = arith.constant 6 : index20  %c80 = arith.constant 80 : index21  %undef = fir.undefined index22  %0 = fir.slice %c5, %undef, %undef, %c6, %c80, %c3 : (index, index, index, index, index, index) -> !fir.slice<2>23  %1 = fir.shift %c3, %c4 : (index, index) -> !fir.shift<2>24 25  // CHECK: %[[EXTRA_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 626  // CHECK: %[[EXTRA:.*]] = load i8, ptr %[[EXTRA_GEP]]27  // CHECK: %[[EXTRA_WITH_ADDENDUM_CORRECTION:.*]] = and i8 %[[EXTRA]]28  // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 4, i32 20240719, i8 1, i8 27, i8 0, i8 undef, [1 x [3 x i64]] undef }, i8 %[[EXTRA_WITH_ADDENDUM_CORRECTION]], 629  // CHECK: %[[INSTRIDE_0_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 230  // CHECK: %[[INSTRIDE_0:.*]] = load i64, ptr %[[INSTRIDE_0_GEP]]31  // CHECK: %[[INSTRIDE_1_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 1, i32 232  // CHECK: %[[INSTRIDE_1:.*]] = load i64, ptr %[[INSTRIDE_1_GEP]]33  // CHECK: %[[INBASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 034  // CHECK: %[[INBASE:.*]] = load ptr, ptr %[[INBASE_GEP]]35  // CHECK: %[[OFFSET_0:.*]] = mul i64 2, %[[INSTRIDE_0]]36  // CHECK: %[[VOIDBASE0:.*]] = getelementptr i8, ptr %[[INBASE]], i64 %[[OFFSET_0]]37  // CHECK: %[[OFFSET_1:.*]] = mul i64 2, %[[INSTRIDE_1]]38  // CHECK: %[[VOIDBASE1:.*]] = getelementptr i8, ptr %[[VOIDBASE0]], i64 %[[OFFSET_1]]39  // CHECK: %[[OUTSTRIDE0:.*]] = mul i64 3, %[[INSTRIDE_1]]40  // CHECK: %[[OUTBOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %{{.*}}, i64 %[[OUTSTRIDE0]], 7, 0, 241  // CHECK: %[[OUTBOX2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[OUTBOX1]], ptr %[[VOIDBASE1]], 042  // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[OUTBOX2]], ptr %[[OUTBOX_ALLOC]], align 843  %2 = fir.rebox %arg0(%1) [%0] : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>, !fir.slice<2>) -> !fir.box<!fir.array<?xf32>>44  // CHECK: call void @bar1(ptr %[[OUTBOX_ALLOC]])45  fir.call @bar1(%2) : (!fir.box<!fir.array<?xf32>>) -> ()46  return47}48 49// Test that character length is propagated in rebox50//   subroutine foo(x)51//     character(*) :: x(:, :)52//     call bar(x(4:30:1, 4:30:1))53//   end subroutine54 55func.func private @bar_rebox_test2(!fir.box<!fir.array<?x?x!fir.char<1,?>>>)56// CHECK-LABEL: define void @test_rebox_2(57// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])58func.func @test_rebox_2(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {59  %c1 = arith.constant 1 : index60  %c4 = arith.constant 4 : index61  %c30 = arith.constant 30 : index62  %0 = fir.slice %c4, %c30, %c1, %c4, %c30, %c1 : (index, index, index, index, index, index) -> !fir.slice<2>63  // CHECK: %[[OUTBOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }64  // CHECK: %[[LEN_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 165  // CHECK: %[[LEN:.*]] = load i64, ptr %[[LEN_GEP]]66  // CHECK: %[[SIZE:.*]] = mul i64 1, %[[LEN]]67  // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } undef, i64 %[[SIZE]], 168 69  %1 = fir.rebox %arg0 [%0]  : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>70  fir.call @bar_rebox_test2(%1) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()71  return72}73 74 75// Test setting a new shape on a fir.box76//   subroutine foo(x)77//     real :: x(:)78//     real, pointer(:, :, :), p79//     p(2:5, 3:7, 4:9) => x80//     call bar(p)81//   end subroutine82 83func.func private @bar_rebox_test3(!fir.box<!fir.array<?x?x?xf32>>)84// CHECK-LABEL: define void @test_rebox_3(85// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])86func.func @test_rebox_3(%arg0: !fir.box<!fir.array<?xf32>>) {87  // CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] }88  %c2 = arith.constant 2 : index89  %c3 = arith.constant 3 : index90  %c4 = arith.constant 4 : index91  %c5 = arith.constant 5 : index92  %1 = fir.shape_shift %c2, %c3, %c3, %c4, %c4, %c5 : (index, index, index, index, index, index) -> !fir.shapeshift<3>93  // CHECK: %[[INSTRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 294  // CHECK: %[[INSTRIDE:.*]] = load i64, ptr %[[INSTRIDE_GEP]]95  // CHECK: %[[INBASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 096  // CHECK: %[[INBASE:.*]] = load ptr, ptr %[[INBASE_GEP]]97  // CHECK: %[[OUTSTRIDE1:.*]] = mul i64 3, %[[INSTRIDE]]98  // CHECK: %[[OUTSTRIDE2:.*]] = mul i64 4, %[[OUTSTRIDE1]]99  // CHECK: %[[OUTBOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %{{.*}}, i64 %[[INSTRIDE]], 7, 0, 2100  // CHECK: %[[OUTBOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX0]], i64 3, 7, 1, 0101  // CHECK: %[[OUTBOX2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX1]], i64 4, 7, 1, 1102  // CHECK: %[[OUTBOX3:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX2]], i64 %[[OUTSTRIDE1]], 7, 1, 2103  // CHECK: %[[OUTBOX4:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX3]], i64 4, 7, 2, 0104  // CHECK: %[[OUTBOX5:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX4]], i64 5, 7, 2, 1105  // CHECK: %[[OUTBOX6:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX5]], i64 %[[OUTSTRIDE2]], 7, 2, 2106  // CHECK: %[[OUTBOX7:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX6]], ptr %[[INBASE]], 0107  // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] } %[[OUTBOX7]], ptr %[[OUTBOX_ALLOC]]108  %2 = fir.rebox %arg0(%1) : (!fir.box<!fir.array<?xf32>>, !fir.shapeshift<3>) -> !fir.box<!fir.array<?x?x?xf32>>109  // CHECK: call void @bar_rebox_test3(ptr %[[OUTBOX_ALLOC]])110  fir.call @bar_rebox_test3(%2) : (!fir.box<!fir.array<?x?x?xf32>>) -> ()111  return112}113 114 115// Test reboxing of character entities where the input has dynamic length and the output has compile116// time constant length.117 118// CHECK-LABEL: define void @test_rebox_4(119// CHECK-SAME: ptr {{[^%]*}}%[[INPUT:.*]])120func.func @test_rebox_4(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>) {121  // CHECK: %[[NEWBOX_STORAGE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }122  // CHECK: %[[EXTENT_GEP:.*]] = getelementptr {{{.*}}}, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 1123  // CHECK: %[[EXTENT:.*]] = load i64, ptr %[[EXTENT_GEP]]124  // CHECK: %[[STRIDE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 2125  // CHECK: %[[STRIDE:.*]] = load i64, ptr %[[STRIDE_GEP]]126  // CHECK: %[[BASE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INPUT]], i32 0, i32 0127  // CHECK: %[[BASE:.*]] = load ptr, ptr %[[BASE_GEP]]128  // CHECK: %[[NEWBOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %{{.*}}, i64 %[[EXTENT]], 7, 0, 1129  // CHECK: %[[NEWBOX2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX1]], i64 %[[STRIDE]], 7, 0, 2130  // CHECK: %[[NEWBOX3:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX2]], ptr %[[BASE]], 0131  // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[NEWBOX3]], ptr %[[NEWBOX_STORAGE]]132  // CHECK: call void @bar_test_rebox_4(ptr %[[NEWBOX_STORAGE]])133 134  %1 = fir.rebox %arg0 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>135  fir.call @bar_test_rebox_4(%1) : (!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>) -> ()136  return137}138func.func private @bar_test_rebox_4(!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>)139 140// Testing complex part slice reboxing141//   subroutine test_cmplx_2(a)142//     complex :: a(:)143//     call bar1(a%re)144//   end subroutine145 146// CHECK-LABEL: define void @test_cmplx_1(147// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])148func.func @test_cmplx_1(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {149  // CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }150  %c1 = arith.constant 1 : index151  %c1_i32 = arith.constant 0 : i32152  %c0 = arith.constant 0 : index153  %0:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.array<?xcomplex<f32>>>, index) -> (index, index, index)154  %1 = fir.slice %c1, %0#1, %c1 path %c1_i32 : (index, index, index, i32) -> !fir.slice<1>155  %2 = fir.rebox %arg0 [%1] : (!fir.box<!fir.array<?xcomplex<f32>>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>156  // CHECK: %[[INSTRIDE_0_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i64 0, i32 1157  // CHECK: %[[INSTRIDE_0:.*]] = load i64, ptr %[[INSTRIDE_0_GEP]]158  // CHECK: %[[INSTRIDE_1_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 2159  // CHECK: %[[INSTRIDE_1:.*]] = load i64, ptr %[[INSTRIDE_1_GEP]]160  // CHECK: %[[FRONT_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 0161  // CHECK: %[[FRONT_PTR:.*]] = load ptr, ptr %[[FRONT_GEP]]162  // CHECK: %[[FIELD_OFFSET_GEP:.*]] = getelementptr { float, float }, ptr %[[FRONT_PTR]], i64 0, i32 0163  // CHECK: %[[FRONT_OFFSET:.*]] = mul i64 0, %[[INSTRIDE_1]]164  // CHECK: %[[OFFSET_GEP:.*]] = getelementptr i8, ptr %[[FIELD_OFFSET_GEP]], i64 %[[FRONT_OFFSET]]165  // CHECK: %[[SUB_1:.*]] = sub i64 %[[INSTRIDE_0]], 1166  // CHECK: %[[ADD_1:.*]] = add i64 %[[SUB_1]], 1167  // CHECK: %[[DIV_1:.*]] = sdiv i64 %[[ADD_1]], 1168  // CHECK: %[[CHECK_NONZERO:.*]] = icmp sgt i64 %[[DIV_1]], 0169  // CHECK: %[[CHECKED_BOUND:.*]] = select i1 %[[CHECK_NONZERO]], i64 %[[DIV_1]], i64 0170  // CHECK: %[[STRIDE:.*]] = mul i64 1, %[[INSTRIDE_1]]171  // CHECK: %[[VAL_BUILD_1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %{{.*}}, i64 %[[CHECKED_BOUND]], 7, 0, 1172  // CHECK: %[[VAL_BUILD_2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[VAL_BUILD_1]], i64 %[[STRIDE]], 7, 0, 2173  // CHECK: %[[VAL_BUILD_3:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[VAL_BUILD_2]], ptr %[[OFFSET_GEP]], 0174  // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[VAL_BUILD_3]], ptr %[[OUTBOX_ALLOC]]175  fir.call @bar1(%2) : (!fir.box<!fir.array<?xf32>>) -> ()176  // CHECK: call void @bar1(ptr %[[OUTBOX_ALLOC]])177  return178}179 180// Testing triple on complex part slice181//   subroutine test_cmplx_2(a)182//     complex :: a(:)183//     call bar1(a(7:60:5)%im)184//   end subroutine185 186// CHECK-LABEL: define void @test_cmplx_2(187// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])188func.func @test_cmplx_2(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {189  // CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }190  %c7 = arith.constant 7 : index191  %c5 = arith.constant 5 : index192  %c60 = arith.constant 60 : index193  %c1_i32 = arith.constant 1 : i32194  %0 = fir.slice %c7, %c60, %c5 path %c1_i32 : (index, index, index, i32) -> !fir.slice<1>195  %1 = fir.rebox %arg0 [%0] : (!fir.box<!fir.array<?xcomplex<f32>>>, !fir.slice<1>) -> !fir.box<!fir.array<11xf32>>196  %2 = fir.convert %1 : (!fir.box<!fir.array<11xf32>>) -> !fir.box<!fir.array<?xf32>>197  // CHECK: %[[INSTRIDE_0_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 7, i32 0, i32 2198  // CHECK: %[[INSTRIDE_0:.*]] = load i64, ptr %[[INSTRIDE_0_GEP]]199  // CHECK: %[[FRONT_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[INBOX]], i32 0, i32 0200  // CHECK: %[[FRONT_PTR:.*]] = load ptr, ptr %[[FRONT_GEP]]201  // CHECK: %[[FIELD_OFFSET_GEP:.*]] = getelementptr { float, float }, ptr %[[FRONT_PTR]], i64 0, i32 1202  // CHECK: %[[FRONT_OFFSET:.*]] = mul i64 6, %[[INSTRIDE_0]]203  // CHECK: %[[OFFSET_GEP:.*]] = getelementptr i8, ptr %[[FIELD_OFFSET_GEP]], i64 %[[FRONT_OFFSET]]204  // CHECK: %[[STRIDE:.*]] = mul i64 5, %[[INSTRIDE_0]]205  // CHECK: %[[VAL_BUILD_1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %{{.*}}, i64 %[[STRIDE]], 7, 0, 2206  // CHECK: %[[VAL_BUILD_2:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[VAL_BUILD_1]], ptr %[[OFFSET_GEP]], 0207  // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[VAL_BUILD_2]], ptr %[[OUTBOX_ALLOC]]208  fir.call @bar1(%2) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()209  // CHECK: call void @bar1(ptr %[[OUTBOX_ALLOC]])210  return211}212 213// Test reboxing of unlimited polymorphic.214 215func.func @rebox_unlimited_polymorphic_box(%arg0 : !fir.class<!fir.array<?xnone>>, %arg1 : !fir.box<!fir.array<?xnone>>, %arg0r : !fir.ref<!fir.class<!fir.array<?xnone>>>, %arg1r : !fir.ref<!fir.box<!fir.array<?xnone>>>) {216  %c1 = arith.constant 1 : index217  %c10 = arith.constant 10 : index218  %1 = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>219  %2 = fir.rebox %arg0 [%1] : (!fir.class<!fir.array<?xnone>>, !fir.slice<1>) -> !fir.class<!fir.array<?xnone>>220  %3 = fir.rebox %arg1 [%1] : (!fir.box<!fir.array<?xnone>>, !fir.slice<1>) -> !fir.box<!fir.array<?xnone>>221  fir.store %2 to %arg0r : !fir.ref<!fir.class<!fir.array<?xnone>>>222  fir.store %3 to %arg1r : !fir.ref<!fir.box<!fir.array<?xnone>>>223  return224}225// CHECK-LABEL: define void @rebox_unlimited_polymorphic_box226// CHECK:  %[[VAL_16:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }227// CHECK:  %[[VAL_17:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }228// ...229// CHECK:  store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %{{.*}}, ptr %[[VAL_17]]230// ...231// CHECK:  store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %{{.*}}, ptr %[[VAL_16]]232