1// RUN: tco %s | FileCheck %s 2// RUN: %flang_fc1 -mmlir -disable-external-name-interop -emit-llvm %s -o -| FileCheck %s 3 4 5// CHECK-LABEL: define void @_QPtest_callee(ptr %0) 6func.func @_QPtest_callee(%arg0: !fir.box<!fir.array<?xi32>>) { 7 return 8} 9 10// CHECK-LABEL: define void @_QPtest_slice() 11func.func @_QPtest_slice() { 12// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8 13// CHECK: %[[a2:.*]] = alloca [20 x i32], i64 1, align 4 14// CHECK: %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0 15// CHECK: %[[a4:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } 16// CHECK: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]] 17// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0 18// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a4]], ptr %[[a1]], align 8 19// CHECK: call void @_QPtest_callee(ptr %[[a1]]) 20 %c20 = arith.constant 20 : index 21 %c1_i64 = arith.constant 1 : i64 22 %c10_i64 = arith.constant 10 : i64 23 %c2_i64 = arith.constant 2 : i64 24 %0 = fir.alloca !fir.array<20xi32> {bindc_name = "x", uniq_name = "_QFtest_sliceEx"} 25 %1 = fir.shape %c20 : (index) -> !fir.shape<1> 26 %2 = fir.slice %c1_i64, %c10_i64, %c2_i64 : (i64, i64, i64) -> !fir.slice<1> 27 %3 = fir.embox %0(%1) [%2] : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>> 28 fir.call @_QPtest_callee(%3) : (!fir.box<!fir.array<?xi32>>) -> () 29 return 30} 31 32// CHECK-LABEL: define void @_QPtest_dt_callee(ptr %0) 33func.func @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>) { 34 return 35} 36 37// CHECK-LABEL: define void @_QPtest_dt_slice() 38func.func @_QPtest_dt_slice() { 39// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8 40// CHECK: %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8 41// CHECK: %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0 42// CHECK: %[[a5:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } 43// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]] 44// CHECK-SAME: [i64 1, i64 5, i64 mul 45// CHECK-SAME: (i64 ptrtoint (ptr getelementptr (%_QFtest_dt_sliceTt, ptr null, i32 1) to i64), i64 2)]] } 46// CHECK-SAME: , ptr %[[a4]], 0 47 48// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a5]], ptr %[[a1]], align 8 49// CHECK: call void @_QPtest_dt_callee(ptr %[[a1]]) 50 %c20 = arith.constant 20 : index 51 %c1_i64 = arith.constant 1 : i64 52 %c10_i64 = arith.constant 10 : i64 53 %c2_i64 = arith.constant 2 : i64 54 %0 = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFtest_dt_sliceEv"} 55 %1 = fir.alloca !fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>> {bindc_name = "x", uniq_name = "_QFtest_dt_sliceEx"} 56 %2 = fir.field_index i, !fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}> 57 %3 = fir.shape %c20 : (index) -> !fir.shape<1> 58 %4 = fir.slice %c1_i64, %c10_i64, %c2_i64 path %2 : (i64, i64, i64, !fir.field) -> !fir.slice<1> 59 %5 = fir.embox %1(%3) [%4] : (!fir.ref<!fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>> 60 fir.call @_QPtest_dt_callee(%5) : (!fir.box<!fir.array<?xi32>>) -> () 61 return 62} 63 64func.func private @takesRank2CharBox(!fir.box<!fir.array<?x?x!fir.char<1,?>>>) 65 66// CHECK-LABEL: define void @emboxSubstring( 67// CHECK-SAME: ptr captures(none) %[[arg0:.*]]) 68func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) { 69 %c2 = arith.constant 2 : index 70 %c3 = arith.constant 3 : index 71 %c1 = arith.constant 1 : index 72 %c1_i64 = arith.constant 1 : i64 73 %c2_i64 = arith.constant 2 : i64 74 %0 = fir.shape %c2, %c3 : (index, index) -> !fir.shape<2> 75 %1 = fir.slice %c1, %c2, %c1, %c1, %c3, %c1 substr %c1_i64, %c2_i64 : (index, index, index, index, index, index, i64, i64) -> !fir.slice<2> 76 %2 = fir.embox %arg0(%0) [%1] : (!fir.ref<!fir.array<2x3x!fir.char<1,4>>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>> 77 // CHECK: %[[addr:.*]] = getelementptr [3 x [2 x [4 x i8]]], ptr %[[arg0]], i64 0, i64 0, i64 0, i64 1 78 // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 2), i32 20240719, i8 2, i8 40, i8 0, i8 0 79 // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] } 80 // CHECK-SAME: ptr %[[addr]], 0 81 82 fir.call @takesRank2CharBox(%2) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> () 83 return 84} 85 86func.func private @do_something(!fir.box<!fir.array<?xf32>>) -> () 87// CHECK: define void @fir_dev_issue_1416 88// CHECK-SAME: ptr captures(none) %[[base_addr:.*]], i64 %[[low:.*]], i64 %[[up:.*]], i64 %[[at:.*]]) 89func.func @fir_dev_issue_1416(%arg0: !fir.ref<!fir.array<40x?xf32>>, %low: index, %up: index, %at : index) { 90 // Test fir.embox with a constant interior array shape. 91 %c1 = arith.constant 1 : index 92 %c40 = arith.constant 40 : index 93 %0 = fir.undefined index 94 %1 = fir.shape_shift %c1, %c40, %low, %up : (index, index, index, index) -> !fir.shapeshift<2> 95 %2 = fir.slice %c1, %c40, %c1, %at, %0, %0 : (index, index, index, index, index, index) -> !fir.slice<2> 96// CHECK: %[[diff:.*]] = sub i64 %[[at]], %[[low]] 97// CHECK: %[[mul:.*]] = mul i64 %[[diff]], 1 98// CHECK: %[[offset:.*]] = add i64 %[[mul]], 0 99// CHECK: %[[addr:.*]] = getelementptr [40 x float], ptr %0, i64 %[[offset]], i64 0 100// CHECK: %[[box:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } 101// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 27, i8 0, i8 0, [1 x [3 x i64]] [{{.*}} [i64 1, i64 40, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64)]] }, ptr %[[addr]], 0 102 %3 = fir.embox %arg0(%1) [%2] : (!fir.ref<!fir.array<40x?xf32>>, !fir.shapeshift<2>, !fir.slice<2>) -> !fir.box<!fir.array<?xf32>> 103 fir.call @do_something(%3) : (!fir.box<!fir.array<?xf32>>) -> () 104 return 105} 106 107// CHECK-LABEL: define void @_QPtest_allocator1() 108func.func @_QPtest_allocator1() { 109 %c20 = arith.constant 20 : index 110 %0 = fir.alloca !fir.array<20xi32> {bindc_name = "x", uniq_name = "_QFtest_sliceEx"} 111 %1 = fir.shape %c20 : (index) -> !fir.shape<1> 112 %3 = fir.embox %0(%1) {allocator_idx = 1 : i32} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>> 113 fir.call @_QPtest_callee(%3) : (!fir.box<!fir.array<?xi32>>) -> () 114 return 115} 116 117// %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 2, [1 x [3 x i64]] [[3 x i64] [i64 1, i64 20, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64)]] } 118 119// CHECK-LABEL: define void @_QPtest_allocator2() 120func.func @_QPtest_allocator2() { 121 %c20 = arith.constant 20 : index 122 %0 = fir.alloca !fir.array<20xi32> {bindc_name = "x", uniq_name = "_QFtest_sliceEx"} 123 %1 = fir.shape %c20 : (index) -> !fir.shape<1> 124 %3 = fir.embox %0(%1) {allocator_idx = 3 : i32} : (!fir.ref<!fir.array<20xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>> 125 fir.call @_QPtest_callee(%3) : (!fir.box<!fir.array<?xi32>>) -> () 126 return 127} 128 129// CHECK: %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20240719, i8 1, i8 9, i8 0, i8 6 130