2957 lines · plain
1// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=CHECK,CHECK-COMDAT,GENERIC2// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=CHECK,CHECK-COMDAT,GENERIC3// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=CHECK,CHECK-COMDAT,GENERIC4// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=CHECK,CHECK-COMDAT,GENERIC5// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-pc-win32" %s | FileCheck %s --check-prefixes=CHECK,CHECK-COMDAT,GENERIC6// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-apple-darwin" %s | FileCheck %s --check-prefixes=CHECK,CHECK-NO-COMDAT,GENERIC7// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=amdgcn-amd-amdhsa, datalayout=e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" %s | FileCheck -check-prefixes=CHECK,AMDGPU %s8 9//===================================================10// SUMMARY: Tests for FIR --> LLVM MLIR conversion11//===================================================12 13// Test simple global LLVM conversion14 15fir.global @g_i0 : i32 {16 %1 = arith.constant 0 : i3217 fir.has_value %1 : i3218}19 20// CHECK: llvm.mlir.global external @g_i0()21// GENERIC-SAME: {addr_space = 0 : i32}22// AMDGPU-SAME: {addr_space = 1 : i32}23// CHECK-SAME: i32 {24// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i32) : i3225// CHECK: llvm.return %[[C0]] : i3226// CHECK: }27 28// -----29 30fir.global @g_ci5 constant : i32 {31 %c = arith.constant 5 : i3232 fir.has_value %c : i3233}34 35// CHECK: llvm.mlir.global external constant @g_ci5()36// GENERIC-SAME: {addr_space = 0 : i32}37// AMDGPU-SAME: {addr_space = 1 : i32}38// CHECK-SAME: i32 {39// CHECK: %[[C5:.*]] = llvm.mlir.constant(5 : i32) : i3240// CHECK: llvm.return %[[C5]] : i3241// CHECK: }42 43// -----44 45fir.global internal @i_i515 (515:i32) : i3246// CHECK: llvm.mlir.global internal @i_i515(515 : i32)47// GENERIC-SAME: {addr_space = 0 : i32}48// AMDGPU-SAME: {addr_space = 1 : i32}49// CHECK-SAME: : i3250 51// -----52 53fir.global common @C_i511 (0:i32) : i3254// CHECK: llvm.mlir.global common @C_i511(0 : i32)55// GENERIC-SAME: {addr_space = 0 : i32}56// AMDGPU-SAME: {addr_space = 1 : i32}57// CHECK-SAME: : i3258 59// -----60 61fir.global weak @w_i86 (86:i32) : i3262// CHECK: llvm.mlir.global weak @w_i86(86 : i32)63// GENERIC-SAME: {addr_space = 0 : i32}64// AMDGPU-SAME: {addr_space = 1 : i32}65// CHECK-SAME: : i3266 67// -----68 69fir.global linkonce @w_i86 (86:i32) : i3270// CHECK-COMDAT: llvm.mlir.global linkonce @w_i86(86 : i32) comdat(@__llvm_comdat::@w_i86) {addr_space = 0 : i32} : i3271// CHECK-NO-COMDAT: llvm.mlir.global linkonce @w_i86(86 : i32) {addr_space = 0 : i32} : i3272 73// -----74 75// Test conversion of fir.address_of with fir.global76 77func.func @f1() {78 %0 = fir.address_of(@symbol) : !fir.ref<i64>79 return80}81 82fir.global @symbol : i64 {83 %0 = arith.constant 1 : i6484 fir.has_value %0 : i6485}86 87// CHECK: %[[ADDROF:.*]] = llvm.mlir.addressof @[[SYMBOL:.*]] : !llvm.ptr88// AMDGPU: %{{.*}} = llvm.addrspacecast %[[ADDROF]] : !llvm.ptr<1> to !llvm.ptr89 90// CHECK: llvm.mlir.global external @[[SYMBOL]]()91// GENERIC-SAME: {addr_space = 0 : i32}92// AMDGPU-SAME: {addr_space = 1 : i32}93// CHECK-SAME: i64 {94// CHECK: %{{.*}} = llvm.mlir.constant(1 : i64) : i6495// CHECK: llvm.return %{{.*}} : i6496// CHECK: }97 98// -----99 100// Test global with insert_on_range operation covering the full array101// in initializer region.102 103fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {104 %c0_i32 = arith.constant 1 : i32105 %0 = fir.undefined !fir.array<32x32xi32>106 %2 = fir.insert_on_range %0, %c0_i32 from (0, 0) to (31, 31) : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>107 fir.has_value %2 : !fir.array<32x32xi32>108}109 110// CHECK: llvm.mlir.global internal @_QEmultiarray() 111// GENERIC-SAME: {addr_space = 0 : i32}112// AMDGPU-SAME: {addr_space = 1 : i32}113// CHECK-SAME: : !llvm.array<32 x array<32 x i32>> {114// CHECK: %[[CST:.*]] = llvm.mlir.constant(dense<1> : vector<32x32xi32>) : !llvm.array<32 x array<32 x i32>>115// CHECK: llvm.return %[[CST]] : !llvm.array<32 x array<32 x i32>>116// CHECK: }117 118// -----119 120// Test global with insert_on_range operation not covering the full array121// in initializer region.122 123fir.global internal @_QEmultiarray : !fir.array<32xi32> {124 %c0_i32 = arith.constant 1 : i32125 %0 = fir.undefined !fir.array<32xi32>126 %2 = fir.insert_on_range %0, %c0_i32 from (5) to (31) : (!fir.array<32xi32>, i32) -> !fir.array<32xi32>127 fir.has_value %2 : !fir.array<32xi32>128}129 130// CHECK: llvm.mlir.global internal @_QEmultiarray() 131// GENERIC-SAME: {addr_space = 0 : i32}132// AMDGPU-SAME: {addr_space = 1 : i32}133// CHECK-SAME: : !llvm.array<32 x i32> {134// CHECK: %[[CST:.*]] = llvm.mlir.constant(1 : i32) : i32135// CHECK: %{{.*}} = llvm.mlir.undef : !llvm.array<32 x i32>136// CHECK: %{{.*}} = llvm.insertvalue %[[CST]], %{{.*}}[5] : !llvm.array<32 x i32>137// CHECK-COUNT-24: %{{.*}} = llvm.insertvalue %[[CST]], %{{.*}}[{{.*}}] : !llvm.array<32 x i32>138// CHECK: %{{.*}} = llvm.insertvalue %[[CST]], %{{.*}}[31] : !llvm.array<32 x i32>139// CHECK-NOT: llvm.insertvalue140// CHECK: llvm.return %{{.*}} : !llvm.array<32 x i32>141// CHECK: }142 143// -----144 145// Test global with box146 147fir.global internal @_QFEx : !fir.box<!fir.ptr<i32>> {148 %0 = fir.zero_bits !fir.ptr<i32>149 %1 = fir.embox %0 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>150 fir.has_value %1 : !fir.box<!fir.ptr<i32>>151}152 153// CHECK-LABEL: llvm.mlir.global internal @_QFEx()154// CHECK-SAME: !llvm.struct<([[DES_FIELDS:.*]])>155// CHECK: %[[T0:.*]] = llvm.mlir.undef : !llvm.struct<([[DES_FIELDS]])>156// CHECK: %[[T1:.*]] = llvm.insertvalue %{{.*}}, %[[T0]][1] : !llvm.struct<([[DES_FIELDS]])>157// CHECK: %[[T2:.*]] = llvm.insertvalue %{{.*}}, %[[T1]][2] : !llvm.struct<([[DES_FIELDS]])>158// CHECK: %[[T3:.*]] = llvm.insertvalue %{{.*}}, %[[T2]][3] : !llvm.struct<([[DES_FIELDS]])>159// CHECK: %[[T4:.*]] = llvm.insertvalue %{{.*}}, %[[T3]][4] : !llvm.struct<([[DES_FIELDS]])>160// CHECK: %[[T5:.*]] = llvm.insertvalue %{{.*}}, %[[T4]][5] : !llvm.struct<([[DES_FIELDS]])>161// CHECK: %[[T6:.*]] = llvm.insertvalue %{{.*}}, %[[T5]][6] : !llvm.struct<([[DES_FIELDS]])>162// CHECK: %[[GDES:.*]] = llvm.insertvalue %{{.*}}, %[[T6]][0] : !llvm.struct<([[DES_FIELDS]])>163// CHECK: llvm.return %[[GDES]] : !llvm.struct<([[DES_FIELDS]])>164 165// -----166 167// Test fir.zero_bits operation with LLVM ptr type168 169func.func @zero_test_ptr() {170 %z = fir.zero_bits !llvm.ptr171 return172}173 174// CHECK: %{{.*}} = llvm.mlir.zero : !llvm.ptr175// CHECK-NOT: fir.zero_bits176 177// -----178 179// Test fir.zero_bits operation with integer type.180 181func.func @zero_test_integer() {182 %z0 = fir.zero_bits i8183 %z1 = fir.zero_bits i16184 %z2 = fir.zero_bits i32185 %z3 = fir.zero_bits i64186 return187}188 189// CHECK: %{{.*}} = llvm.mlir.zero : i8190// CHECK: %{{.*}} = llvm.mlir.zero : i16191// CHECK: %{{.*}} = llvm.mlir.zero : i32192// CHECK: %{{.*}} = llvm.mlir.zero : i64193// CHECK-NOT: fir.zero_bits194 195// -----196 197// Test fir.zero_bits operation with floating points types.198 199func.func @zero_test_float() {200 %z0 = fir.zero_bits f16201 %z1 = fir.zero_bits bf16202 %z2 = fir.zero_bits f32203 %z3 = fir.zero_bits f64204 %z4 = fir.zero_bits f80205 %z5 = fir.zero_bits f128206 return207}208 209// CHECK: %{{.*}} = llvm.mlir.zero : f16210// CHECK: %{{.*}} = llvm.mlir.zero : bf16211// CHECK: %{{.*}} = llvm.mlir.zero : f32212// CHECK: %{{.*}} = llvm.mlir.zero : f64213// CHECK: %{{.*}} = llvm.mlir.zero : f80214// CHECK: %{{.*}} = llvm.mlir.zero : f128215// CHECK-NOT: fir.zero_bits216 217// -----218 219// Test fir.zero_bits with aggregate types.220 221func.func @zero_aggregate() {222 %a = fir.zero_bits !fir.array<10xf32>223 %b = fir.zero_bits !fir.type<a{i:i32,j:f32}>224 return225}226// CHECK: %{{.*}} = llvm.mlir.zero : !llvm.array<10 x f32>227// CHECK: %{{.*}} = llvm.mlir.zero : !llvm.struct<"a", (i32, f32)>228// CHECK-NOT: fir.zero_bits229 230// -----231 232 233// Verify that fir.allocmem is transformed to a call to malloc234// and that fir.freemem is transformed to a call to free235// Single item case236 237func.func @test_alloc_and_freemem_one() {238 %z0 = fir.allocmem i32239 fir.freemem %z0 : !fir.heap<i32>240 return241}242 243// CHECK-LABEL: llvm.func @test_alloc_and_freemem_one() {244// CHECK-DAG: %[[N:.*]] = llvm.mlir.constant(4 : i64) : i64245// CHECK-DAG: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64246// CHECK-DAG: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64247// CHECK-NEXT: %[[CMP:.*]] = llvm.icmp "sgt" %[[N]], %[[ZERO]] : i64248// CHECK-NEXT: %[[SZ:.*]] = llvm.select %[[CMP]], %[[N]], %[[ONE]] : i1, i64249// CHECK-NEXT: llvm.call @malloc(%[[SZ]])250// CHECK: llvm.call @free(%{{.*}})251// CHECK-NEXT: llvm.return252 253// -----254// Verify that fir.allocmem is transformed to a call to malloc255// and that fir.freemem is transformed to a call to free256// Several item case257 258func.func @test_alloc_and_freemem_several() {259 %z0 = fir.allocmem !fir.array<100xf32>260 fir.freemem %z0 : !fir.heap<!fir.array<100xf32>>261 return262}263 264// CHECK-LABEL: llvm.func @test_alloc_and_freemem_several() {265// CHECK-DAG: %[[N:.*]] = llvm.mlir.constant(400 : i64) : i64266// CHECK-DAG: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64267// CHECK-DAG: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64268// CHECK-NEXT: %[[CMP:.*]] = llvm.icmp "sgt" %[[N]], %[[ZERO]] : i64269// CHECK-NEXT: %[[SZ:.*]] = llvm.select %[[CMP]], %[[N]], %[[ONE]] : i1, i64270// CHECK: [[MALLOC:%.*]] = llvm.call @malloc(%[[SZ]])271// CHECK: llvm.call @free([[MALLOC]])272// CHECK: llvm.return273 274 275func.func @test_with_shape(%ncols: index, %nrows: index) {276 %1 = fir.allocmem !fir.array<?x?xf32>, %ncols, %nrows277 fir.freemem %1 : !fir.heap<!fir.array<?x?xf32>>278 return279}280 281// CHECK-LABEL: llvm.func @test_with_shape282// CHECK-SAME: %[[NCOLS:.*]]: i64, %[[NROWS:.*]]: i64283// CHECK: %[[FOUR:.*]] = llvm.mlir.constant(4 : i64) : i64284// CHECK: %[[DIM1_SIZE:.*]] = llvm.mul %[[FOUR]], %[[NCOLS]] : i64285// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[DIM1_SIZE]], %[[NROWS]] : i64286// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64287// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64288// CHECK: %[[CMP:.*]] = llvm.icmp "sgt" %[[TOTAL_SIZE]], %[[ZERO]] : i64289// CHECK: %[[SZ:.*]] = llvm.select %[[CMP]], %[[TOTAL_SIZE]], %[[ONE]] : i1, i64290// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[SZ]])291// CHECK: llvm.call @free(%[[MEM]]) : (!llvm.ptr) -> ()292// CHECK: llvm.return293// CHECK: }294 295func.func @test_string_with_shape(%len: index, %nelems: index) {296 %1 = fir.allocmem !fir.array<?x!fir.char<1,?>>(%len : index), %nelems297 fir.freemem %1 : !fir.heap<!fir.array<?x!fir.char<1,?>>>298 return299}300 301// CHECK-LABEL: llvm.func @test_string_with_shape302// CHECK-SAME: %[[LEN:.*]]: i64, %[[NELEMS:.*]]: i64)303// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64304// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[ONE]], %[[LEN]] : i64305// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[LEN_SIZE]], %[[NELEMS]] : i64306// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64307// CHECK: %[[ONEA:.*]] = llvm.mlir.constant(1 : i64) : i64308// CHECK: %[[CMP:.*]] = llvm.icmp "sgt" %[[TOTAL_SIZE]], %[[ZERO]] : i64309// CHECK: %[[SZ:.*]] = llvm.select %[[CMP]], %[[TOTAL_SIZE]], %[[ONEA]] : i1, i64310// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[SZ]])311// CHECK: llvm.call @free(%[[MEM]]) : (!llvm.ptr) -> ()312// CHECK: llvm.return313// CHECK: }314 315// -----316 317// Verify that fir.unreachable is transformed to llvm.unreachable318 319func.func @test_unreachable() {320 fir.unreachable321}322 323// CHECK: llvm.func @test_unreachable() {324// CHECK-NEXT: llvm.unreachable325// CHECK-NEXT: }326 327// -----328 329// Test `fir.select` operation conversion pattern.330// Check that the if-then-else ladder is correctly constructed and that we331// branch to the correct block.332 333func.func @select(%arg : index, %arg2 : i32) -> i32 {334 %0 = arith.constant 1 : i32335 %1 = arith.constant 2 : i32336 %2 = arith.constant 3 : i32337 %3 = arith.constant 4 : i32338 fir.select %arg:index [ 1, ^bb1(%0:i32),339 2, ^bb2(%2,%arg,%arg2:i32,index,i32),340 3, ^bb3(%arg2,%2:i32,i32),341 4, ^bb4(%1:i32),342 unit, ^bb5 ]343 ^bb1(%a : i32) :344 return %a : i32345 ^bb2(%b : i32, %b2 : index, %b3:i32) :346 %castidx = arith.index_cast %b2 : index to i32347 %4 = arith.addi %b, %castidx : i32348 %5 = arith.addi %4, %b3 : i32349 return %5 : i32350 ^bb3(%c:i32, %c2:i32) :351 %6 = arith.addi %c, %c2 : i32352 return %6 : i32353 ^bb4(%d : i32) :354 return %d : i32355 ^bb5 :356 %zero = arith.constant 0 : i32357 return %zero : i32358}359 360// CHECK-LABEL: func @select(361// CHECK-SAME: %[[SELECTVALUE:.*]]: [[IDX:.*]],362// CHECK-SAME: %[[ARG1:.*]]: i32)363// CHECK: %[[C0:.*]] = llvm.mlir.constant(1 : i32) : i32364// CHECK: %[[C1:.*]] = llvm.mlir.constant(2 : i32) : i32365// CHECK: %[[C2:.*]] = llvm.mlir.constant(3 : i32) : i32366// CHECK: llvm.switch %[[SELECTVALUE]] : i64, ^bb5 [367// CHECK: 1: ^bb1(%[[C0]] : i32),368// CHECK: 2: ^bb2(%[[C2]], %[[SELECTVALUE]], %[[ARG1]] : i32, [[IDX]], i32),369// CHECK: 3: ^bb3(%[[ARG1]], %[[C2]] : i32, i32),370// CHECK: 4: ^bb4(%[[C1]] : i32)371// CHECK: ]372 373// -----374 375// Test `fir.select_rank` operation conversion pattern.376// Check that the if-then-else ladder is correctly constructed and that we377// branch to the correct block.378 379func.func @select_rank(%arg : i32, %arg2 : i32) -> i32 {380 %0 = arith.constant 1 : i32381 %1 = arith.constant 2 : i32382 %2 = arith.constant 3 : i32383 %3 = arith.constant 4 : i32384 fir.select_rank %arg:i32 [ 1, ^bb1(%0:i32),385 2, ^bb2(%2,%arg,%arg2:i32,i32,i32),386 3, ^bb3(%arg2,%2:i32,i32),387 4, ^bb4(%1:i32),388 unit, ^bb5 ]389 ^bb1(%a : i32) :390 return %a : i32391 ^bb2(%b : i32, %b2 : i32, %b3:i32) :392 %4 = arith.addi %b, %b2 : i32393 %5 = arith.addi %4, %b3 : i32394 return %5 : i32395 ^bb3(%c:i32, %c2:i32) :396 %6 = arith.addi %c, %c2 : i32397 return %6 : i32398 ^bb4(%d : i32) :399 return %d : i32400 ^bb5 :401 %zero = arith.constant 0 : i32402 return %zero : i32403}404 405// CHECK-LABEL: func @select_rank(406// CHECK-SAME: %[[SELECTVALUE:.*]]: i32,407// CHECK-SAME: %[[ARG1:.*]]: i32)408// CHECK: %[[C0:.*]] = llvm.mlir.constant(1 : i32) : i32409// CHECK: %[[C1:.*]] = llvm.mlir.constant(2 : i32) : i32410// CHECK: %[[C2:.*]] = llvm.mlir.constant(3 : i32) : i32411// CHECK: %[[SELECTOR:.*]] = llvm.sext %[[SELECTVALUE]] : i{{.*}} to i64412// CHECK: llvm.switch %[[SELECTOR]] : i64, ^bb5 [413// CHECK: 1: ^bb1(%[[C0]] : i32),414// CHECK: 2: ^bb2(%[[C2]], %[[SELECTVALUE]], %[[ARG1]] : i32, i32, i32),415// CHECK: 3: ^bb3(%[[ARG1]], %[[C2]] : i32, i32),416// CHECK: 4: ^bb4(%[[C1]] : i32)417// CHECK: ]418 419// -----420 421// Test fir.extract_value operation conversion with derived type.422 423func.func @extract_derived_type() -> f32 {424 %0 = fir.undefined !fir.type<derived{f:f32}>425 %1 = fir.extract_value %0, ["f", !fir.type<derived{f:f32}>] : (!fir.type<derived{f:f32}>) -> f32426 return %1 : f32427}428 429// CHECK-LABEL: llvm.func @extract_derived_type430// CHECK: %[[STRUCT:.*]] = llvm.mlir.undef : !llvm.struct<"derived", (f32)>431// CHECK: %[[VALUE:.*]] = llvm.extractvalue %[[STRUCT]][0] : !llvm.struct<"derived", (f32)>432// CHECK: llvm.return %[[VALUE]] : f32433 434// -----435 436// Test fir.extract_value operation conversion with a multi-dimensional array437// of tuple.438 439func.func @extract_array(%a : !fir.array<10x10xtuple<i32, f32>>) -> f32 {440 %0 = fir.extract_value %a, [5 : index, 4 : index, 1 : index] : (!fir.array<10x10xtuple<i32, f32>>) -> f32441 return %0 : f32442}443 444// CHECK-LABEL: llvm.func @extract_array(445// CHECK-SAME: %[[ARR:.*]]: !llvm.array<10 x array<10 x struct<(i32, f32)>>>446// CHECK: %[[VALUE:.*]] = llvm.extractvalue %[[ARR]][4, 5, 1] : !llvm.array<10 x array<10 x struct<(i32, f32)>>>447// CHECK: llvm.return %[[VALUE]] : f32448 449// -----450 451// Test fir.insert_value operation conversion with a multi-dimensional array452// of tuple.453 454func.func @extract_array(%a : !fir.array<10x10xtuple<i32, f32>>) {455 %f = arith.constant 2.0 : f32456 %i = arith.constant 1 : i32457 %0 = fir.insert_value %a, %i, [5 : index, 4 : index, 0 : index] : (!fir.array<10x10xtuple<i32, f32>>, i32) -> !fir.array<10x10xtuple<i32, f32>>458 %1 = fir.insert_value %a, %f, [5 : index, 4 : index, 1 : index] : (!fir.array<10x10xtuple<i32, f32>>, f32) -> !fir.array<10x10xtuple<i32, f32>>459 return460}461 462// CHECK-LABEL: llvm.func @extract_array(463// CHECK-SAME: %[[ARR:.*]]: !llvm.array<10 x array<10 x struct<(i32, f32)>>>464// CHECK: %{{.*}} = llvm.insertvalue %{{.*}}, %[[ARR]][4, 5, 0] : !llvm.array<10 x array<10 x struct<(i32, f32)>>>465// CHECK: %{{.*}} = llvm.insertvalue %{{.*}}, %[[ARR]][4, 5, 1] : !llvm.array<10 x array<10 x struct<(i32, f32)>>>466// CHECK: llvm.return467 468// -----469 470// Test fir.insert_value operation conversion with derived type.471 472func.func @insert_tuple(%a : tuple<i32, f32>) {473 %f = arith.constant 2.0 : f32474 %1 = fir.insert_value %a, %f, [1 : index] : (tuple<i32, f32>, f32) -> tuple<i32, f32>475 return476}477 478// CHECK-LABEL: func @insert_tuple(479// CHECK-SAME: %[[TUPLE:.*]]: !llvm.struct<(i32, f32)>480// CHECK: %{{.*}} = llvm.insertvalue %{{.*}}, %[[TUPLE]][1] : !llvm.struct<(i32, f32)>481// CHECK: llvm.return482 483// -----484 485// Test `fir.call` -> `llvm.call` conversion for functions that take no arguments486// and return nothing487 488func.func @dummy_basic() {489 return490}491 492func.func @test_call_basic() {493 fir.call @dummy_basic() : () -> ()494 return495}496 497// CHECK-LABEL: func @test_call_basic() {498// CHECK-NEXT: llvm.call @dummy_basic() : () -> ()499// CHECK-NEXT: return500// CHECK-NEXT: }501 502// Test `fir.call` -> `llvm.call` conversion for functions that take one503// argument and return nothing504 505func.func @dummy_with_arg(%arg0 : i32) {506 return507}508 509func.func @test_call_with_arg(%arg0 : i32) {510 fir.call @dummy_with_arg(%arg0) : (i32) -> ()511 return512}513 514// CHECK-LABEL: llvm.func @test_call_with_arg(%arg0: i32) {515// CHECK-NEXT: llvm.call @dummy_with_arg(%arg0) : (i32) -> ()516// CHECK-NEXT: llvm.return517// CHECK-NEXT: }518 519// Test `fir.call` -> `llvm.call` conversion for functions that take no520// arguments, but return a value521 522func.func @dummy_return_val() -> i32 {523 %1 = arith.constant 123 : i32524 return %1 : i32525}526 527func.func @test_call_return_val() -> i32 {528 %1 = fir.call @dummy_return_val() : () -> (i32)529 return %1 : i32530}531 532// CHECK-LABEL: llvm.func @test_call_return_val() -> i32 {533// CHECK-NEXT: %0 = llvm.call @dummy_return_val() : () -> i32534// CHECK-NEXT: llvm.return %0 : i32535// CHECK-NEXT: }536 537// -----538 539// Test FIR complex addition conversion540// given: (x + iy) + (x' + iy')541// result: (x + x') + i(y + y')542 543func.func @fir_complex_add(%a: complex<f128>, %b: complex<f128>) -> complex<f128> {544 %c = fir.addc %a, %b {fastmath = #arith.fastmath<fast>} : complex<f128>545 return %c : complex<f128>546}547 548// CHECK-LABEL: llvm.func @fir_complex_add(549// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>,550// CHECK-SAME: %[[ARG1:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f128, f128)> {551// CHECK: %[[X0:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>552// CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>553// CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)>554// CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)>555// CHECK: %[[ADD_X0_X1:.*]] = llvm.fadd %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128556// CHECK: %[[ADD_Y0_Y1:.*]] = llvm.fadd %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128557// CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)>558// CHECK: %{{.*}} = llvm.insertvalue %[[ADD_X0_X1]], %{{.*}}[0] : !llvm.struct<(f128, f128)>559// CHECK: %{{.*}} = llvm.insertvalue %[[ADD_Y0_Y1]], %{{.*}}[1] : !llvm.struct<(f128, f128)>560// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>561 562// -----563 564// Test FIR complex substraction conversion565// given: (x + iy) - (x' + iy')566// result: (x - x') + i(y - y')567 568func.func @fir_complex_sub(%a: complex<f128>, %b: complex<f128>) -> complex<f128> {569 %c = fir.subc %a, %b {fastmath = #arith.fastmath<fast>} : complex<f128>570 return %c : complex<f128>571}572 573// CHECK-LABEL: llvm.func @fir_complex_sub(574// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>,575// CHECK-SAME: %[[ARG1:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f128, f128)> {576// CHECK: %[[X0:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>577// CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>578// CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)>579// CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)>580// CHECK: %[[SUB_X0_X1:.*]] = llvm.fsub %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128581// CHECK: %[[SUB_Y0_Y1:.*]] = llvm.fsub %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128582// CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)>583// CHECK: %{{.*}} = llvm.insertvalue %[[SUB_X0_X1]], %{{.*}}[0] : !llvm.struct<(f128, f128)>584// CHECK: %{{.*}} = llvm.insertvalue %[[SUB_Y0_Y1]], %{{.*}}[1] : !llvm.struct<(f128, f128)>585// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>586 587// -----588 589// Test FIR complex multiply conversion590// given: (x + iy) * (x' + iy')591// result: (xx'-yy')+i(xy'+yx')592 593func.func @fir_complex_mul(%a: complex<f128>, %b: complex<f128>) -> complex<f128> {594 %c = fir.mulc %a, %b {fastmath = #arith.fastmath<fast>} : complex<f128>595 return %c : complex<f128>596}597 598// CHECK-LABEL: llvm.func @fir_complex_mul(599// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>,600// CHECK-SAME: %[[ARG1:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f128, f128)> {601// CHECK: %[[X0:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>602// CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>603// CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)>604// CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)>605// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128606// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128607// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128608// CHECK: %[[ADD:.*]] = llvm.fadd %[[MUL_X0_Y1]], %[[MUL_Y0_X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128609// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128610// CHECK: %[[SUB:.*]] = llvm.fsub %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128611// CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)>612// CHECK: %{{.*}} = llvm.insertvalue %[[SUB]], %{{.*}}[0] : !llvm.struct<(f128, f128)>613// CHECK: %{{.*}} = llvm.insertvalue %[[ADD]], %{{.*}}[1] : !llvm.struct<(f128, f128)>614// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>615 616// -----617 618// Test FIR complex division conversion619// given: (x + iy) / (x' + iy')620// result: ((xx'+yy')/d) + i((yx'-xy')/d) where d = x'x' + y'y'621 622func.func @fir_complex_div(%a: complex<f128>, %b: complex<f128>) -> complex<f128> {623 %c = fir.divc %a, %b {fastmath = #arith.fastmath<fast>} : complex<f128>624 return %c : complex<f128>625}626 627// CHECK-LABEL: llvm.func @fir_complex_div(628// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>,629// CHECK-SAME: %[[ARG1:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f128, f128)> {630// CHECK: %[[X0:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>631// CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>632// CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)>633// CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)>634// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128635// CHECK: %[[MUL_X1_X1:.*]] = llvm.fmul %[[X1]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128636// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] {fastmathFlags = #llvm.fastmath<fast>} : f128637// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128638// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128639// CHECK: %[[MUL_Y1_Y1:.*]] = llvm.fmul %[[Y1]], %[[Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128640// CHECK: %[[ADD_X1X1_Y1Y1:.*]] = llvm.fadd %[[MUL_X1_X1]], %[[MUL_Y1_Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128641// CHECK: %[[ADD_X0X1_Y0Y1:.*]] = llvm.fadd %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128642// CHECK: %[[SUB_Y0X1_X0Y1:.*]] = llvm.fsub %[[MUL_Y0_X1]], %[[MUL_X0_Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128643// CHECK: %[[DIV0:.*]] = llvm.fdiv %[[ADD_X0X1_Y0Y1]], %[[ADD_X1X1_Y1Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128644// CHECK: %[[DIV1:.*]] = llvm.fdiv %[[SUB_Y0X1_X0Y1]], %[[ADD_X1X1_Y1Y1]] {fastmathFlags = #llvm.fastmath<fast>} : f128645// CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)>646// CHECK: %{{.*}} = llvm.insertvalue %[[DIV0]], %{{.*}}[0] : !llvm.struct<(f128, f128)>647// CHECK: %{{.*}} = llvm.insertvalue %[[DIV1]], %{{.*}}[1] : !llvm.struct<(f128, f128)>648// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>649 650// -----651 652// Test FIR complex negation conversion653// given: -(x + iy)654// result: -x - iy655 656func.func @fir_complex_neg(%a: complex<f128>) -> complex<f128> {657 %c = fir.negc %a : complex<f128>658 return %c : complex<f128>659}660 661// CHECK-LABEL: llvm.func @fir_complex_neg(662// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f128, f128)> {663// CHECK: %[[X:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>664// CHECK: %[[Y:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>665// CHECK: %[[NEGX:.*]] = llvm.fneg %[[X]] : f128666// CHECK: %[[NEGY:.*]] = llvm.fneg %[[Y]] : f128667// CHECK: %{{.*}} = llvm.insertvalue %[[NEGX]], %{{.*}}[0] : !llvm.struct<(f128, f128)>668// CHECK: %{{.*}} = llvm.insertvalue %[[NEGY]], %{{.*}}[1] : !llvm.struct<(f128, f128)>669// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>670 671// -----672 673// Test FIR complex compare conversion674 675func.func @compare_complex_eq(%a : complex<f64>, %b : complex<f64>) -> i1 {676 %r = fir.cmpc "oeq", %a, %b : complex<f64>677 return %r : i1678}679 680// CHECK-LABEL: llvm.func @compare_complex_eq681// CHECK-SAME: [[A:%.*]]: !llvm.struct<(f64, f64)>,682// CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>683// CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>684// CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>685// CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>686// CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>687// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] : f64688// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] : f64689// CHECK: [[RES:%.*]] = llvm.and [[RESR]], [[RESI]] : i1690// CHECK: return [[RES]] : i1691 692func.func @compare_complex_ne(%a : complex<f64>, %b : complex<f64>) -> i1 {693 %r = fir.cmpc "une", %a, %b {fastmath = #arith.fastmath<fast>} : complex<f64>694 return %r : i1695}696 697// CHECK-LABEL: llvm.func @compare_complex_ne698// CHECK-SAME: [[A:%.*]]: !llvm.struct<(f64, f64)>,699// CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>700// CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>701// CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>702// CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>703// CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>704// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] {fastmathFlags = #llvm.fastmath<fast>} : f64705// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] {fastmathFlags = #llvm.fastmath<fast>} : f64706// CHECK: [[RES:%.*]] = llvm.or [[RESR]], [[RESI]] : i1707// CHECK: return [[RES]] : i1708 709func.func @compare_complex_other(%a : complex<f64>, %b : complex<f64>) -> i1 {710 %r = fir.cmpc "ogt", %a, %b {fastmath = #arith.fastmath<fast>} : complex<f64>711 return %r : i1712}713 714// CHECK-LABEL: llvm.func @compare_complex_other715// CHECK-SAME: [[A:%.*]]: !llvm.struct<(f64, f64)>,716// CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>717// CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>718// CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>719// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] {fastmathFlags = #llvm.fastmath<fast>} : f64720// CHECK: return [[RESR]] : i1721 722// -----723 724// Test `fir.convert` operation conversion from Float type.725 726func.func @convert_from_float(%arg0 : f32) {727 %0 = fir.convert %arg0 : (f32) -> f16728 %1 = fir.convert %arg0 : (f32) -> f32729 %2 = fir.convert %arg0 : (f32) -> f64730 %3 = fir.convert %arg0 : (f32) -> f80731 %4 = fir.convert %arg0 : (f32) -> f128732 %5 = fir.convert %arg0 : (f32) -> i1733 %6 = fir.convert %arg0 : (f32) -> i8734 %7 = fir.convert %arg0 : (f32) -> i16735 %8 = fir.convert %arg0 : (f32) -> i32736 %9 = fir.convert %arg0 : (f32) -> i64737 %10 = fir.convert %arg0 : (f32) -> ui8738 %11 = fir.convert %arg0 : (f32) -> ui16739 %12 = fir.convert %arg0 : (f32) -> ui32740 %13 = fir.convert %arg0 : (f32) -> ui64741 return742}743 744// CHECK-LABEL: convert_from_float(745// CHECK-SAME: %[[ARG0:.*]]: f32746// CHECK: %{{.*}} = llvm.fptrunc %[[ARG0]] : f32 to f16747// CHECK-NOT: f32 to f32748// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f64749// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f80750// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f128751// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i1752// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i8753// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i16754// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i32755// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptosi.sat"(%[[ARG0]]) : (f32) -> i64756// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i8757// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i16758// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i32759// CHECK: %{{.*}} = llvm.call_intrinsic "llvm.fptoui.sat"(%[[ARG0]]) : (f32) -> i64760 761// -----762 763// Test `fir.convert` operation conversion from Integer type.764 765func.func @convert_from_int(%arg0 : i32) {766 %0 = fir.convert %arg0 : (i32) -> f16767 %1 = fir.convert %arg0 : (i32) -> f32768 %2 = fir.convert %arg0 : (i32) -> f64769 %3 = fir.convert %arg0 : (i32) -> f80770 %4 = fir.convert %arg0 : (i32) -> f128771 %5 = fir.convert %arg0 : (i32) -> i1772 %6 = fir.convert %arg0 : (i32) -> i8773 %7 = fir.convert %arg0 : (i32) -> i16774 %8 = fir.convert %arg0 : (i32) -> i32775 %9 = fir.convert %arg0 : (i32) -> i64776 %10 = fir.convert %arg0 : (i32) -> i64777 %ptr = fir.convert %10 : (i64) -> !fir.ref<i64>778 return779}780 781// CHECK-LABEL: convert_from_int(782// CHECK-SAME: %[[ARG0:.*]]: i32783// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f16784// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f32785// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f64786// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f80787// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f128788// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i1789// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i8790// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i16791// CHECK-NOT: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i32792// CHECK: %{{.*}} = llvm.sext %[[ARG0]] : i32 to i64793// CHECK: %{{.*}} = llvm.inttoptr %{{.*}} : i64 to !llvm.ptr794 795 796func.func @convert_from_i1(%arg0 : i1) {797 %0 = fir.convert %arg0 : (i1) -> i32798 return799}800 801// CHECK-LABEL: convert_from_i1(802// CHECK-SAME: %[[ARG0:.*]]: i1803// CHECK: %{{.*}} = llvm.zext %[[ARG0]] : i1 to i32804 805// -----806 807// Test `fir.convert` operation conversion from !fir.ref<> type.808 809func.func @convert_from_ref(%arg0 : !fir.ref<i32>) {810 %0 = fir.convert %arg0 : (!fir.ref<i32>) -> !fir.ref<i8>811 %1 = fir.convert %arg0 : (!fir.ref<i32>) -> i32812 return813}814 815// CHECK-LABEL: convert_from_ref(816// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr817// CHECK-NOT: %{{.*}} = llvm.bitcast %[[ARG0]] : !llvm.ptr to !llvm.ptr818// CHECK: %{{.*}} = llvm.ptrtoint %[[ARG0]] : !llvm.ptr to i32819 820// -----821 822// Test `fir.convert` operation conversion between fir.complex types.823 824func.func @convert_complex4(%arg0 : complex<f32>) -> complex<f64> {825 %0 = fir.convert %arg0 : (complex<f32>) -> complex<f64>826 return %0 : complex<f64>827}828 829// CHECK-LABEL: func @convert_complex4(830// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f32, f32)>) -> !llvm.struct<(f64, f64)>831// CHECK: %[[X:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f32, f32)>832// CHECK: %[[Y:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f32, f32)>833// CHECK: %[[CONVERTX:.*]] = llvm.fpext %[[X]] : f32 to f64834// CHECK: %[[CONVERTY:.*]] = llvm.fpext %[[Y]] : f32 to f64835// CHECK: %[[STRUCT0:.*]] = llvm.mlir.undef : !llvm.struct<(f64, f64)>836// CHECK: %[[STRUCT1:.*]] = llvm.insertvalue %[[CONVERTX]], %[[STRUCT0]][0] : !llvm.struct<(f64, f64)>837// CHECK: %[[STRUCT2:.*]] = llvm.insertvalue %[[CONVERTY]], %[[STRUCT1]][1] : !llvm.struct<(f64, f64)>838// CHECK: llvm.return %[[STRUCT2]] : !llvm.struct<(f64, f64)>839 840// Test `fir.convert` operation conversion between fir.complex types.841 842func.func @convert_complex16(%arg0 : complex<f128>) -> complex<f16> {843 %0 = fir.convert %arg0 : (complex<f128>) -> complex<f16>844 return %0 : complex<f16>845}846 847// CHECK-LABEL: func @convert_complex16(848// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f16, f16)>849// CHECK: %[[X:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(f128, f128)>850// CHECK: %[[Y:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>851// CHECK: %[[CONVERTX:.*]] = llvm.fptrunc %[[X]] : f128 to f16852// CHECK: %[[CONVERTY:.*]] = llvm.fptrunc %[[Y]] : f128 to f16853// CHECK: %[[STRUCT0:.*]] = llvm.mlir.undef : !llvm.struct<(f16, f16)>854// CHECK: %[[STRUCT1:.*]] = llvm.insertvalue %[[CONVERTX]], %[[STRUCT0]][0] : !llvm.struct<(f16, f16)>855// CHECK: %[[STRUCT2:.*]] = llvm.insertvalue %[[CONVERTY]], %[[STRUCT1]][1] : !llvm.struct<(f16, f16)>856// CHECK: llvm.return %[[STRUCT2]] : !llvm.struct<(f16, f16)>857 858// -----859 860// Test `fir.convert` operation conversion between compatible fir.record types.861 862func.func @convert_record(%arg0 : !fir.type<_QMmod1Trec{i:i32,f:f64,c:!llvm.struct<(f32, f32)>,cstr:!fir.array<4x!fir.char<1>>}>) ->863 !fir.type<_QMmod2Trec{i:i32,f:f64,c:!llvm.struct<(f32, f32)>,cstr:!fir.array<4x!fir.char<1>>}> {864 %0 = fir.convert %arg0 : (!fir.type<_QMmod1Trec{i:i32,f:f64,c:!llvm.struct<(f32, f32)>,cstr:!fir.array<4x!fir.char<1>>}>) ->865 !fir.type<_QMmod2Trec{i:i32,f:f64,c:!llvm.struct<(f32, f32)>,cstr:!fir.array<4x!fir.char<1>>}>866 return %0 : !fir.type<_QMmod2Trec{i:i32,f:f64,c:!llvm.struct<(f32, f32)>,cstr:!fir.array<4x!fir.char<1>>}>867}868 869// CHECK-LABEL: func @convert_record(870// CHECK-SAME: %[[ARG0:.*]]: [[MOD1_REC:!llvm.struct<"_QMmod1Trec", \(i32, f64, struct<\(f32, f32\)>, array<4 x array<1 x i8>>\)>]]) ->871// CHECK-SAME: [[MOD2_REC:!llvm.struct<"_QMmod2Trec", \(i32, f64, struct<\(f32, f32\)>, array<4 x array<1 x i8>>\)>]]872// CHECK: %{{.*}} = llvm.mlir.undef : [[MOD2_REC]]873// CHECK-DAG: %[[I:.*]] = llvm.extractvalue %[[ARG0]][0] : [[MOD1_REC]]874// CHECK-DAG: %{{.*}} = llvm.insertvalue %[[I]], %{{.*}}[0] : [[MOD2_REC]]875// CHECK-DAG: %[[F:.*]] = llvm.extractvalue %[[ARG0]][1] : [[MOD1_REC]]876// CHECK-DAG: %{{.*}} = llvm.insertvalue %[[F]], %{{.*}}[1] : [[MOD2_REC]]877// CHECK-DAG: %[[C:.*]] = llvm.extractvalue %[[ARG0]][2] : [[MOD1_REC]]878// CHECK-DAG: %{{.*}} = llvm.insertvalue %[[C]], %{{.*}}[2] : [[MOD2_REC]]879// CHECK-DAG: %[[CSTR:.*]] = llvm.extractvalue %[[ARG0]][3] : [[MOD1_REC]]880// CHECK-DAG: %{{.*}} = llvm.insertvalue %[[CSTR]], %{{.*}}[3] : [[MOD2_REC]]881// CHECK: llvm.return %{{.*}} : [[MOD2_REC]]882 883// -----884 885// Test `fir.store` --> `llvm.store` conversion886 887func.func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) {888 fir.store %val_to_store to %addr : !fir.ref<index>889 return890}891 892// CHECK-LABEL: llvm.func @test_store_index893// CHECK-SAME: (%[[arg0:.*]]: i64, %[[arg1:.*]]: !llvm.ptr) {894// CHECK-NEXT: llvm.store %[[arg0]], %[[arg1]] : i64, !llvm.ptr895// CHECK-NEXT: llvm.return896// CHECK-NEXT: }897 898func.func @test_store_box(%array : !fir.ref<!fir.box<!fir.array<?x?xf32>>>, %box : !fir.box<!fir.array<?x?xf32>>) {899 fir.store %box to %array : !fir.ref<!fir.box<!fir.array<?x?xf32>>>900 return901}902 903// CHECK-LABEL: llvm.func @test_store_box904// CHECK-SAME: (%[[arg0:.*]]: !llvm.ptr,905// CHECK-SAME: %[[arg1:.*]]: !llvm.ptr) {906// CHECK-NEXT: %[[size:.*]] = llvm.mlir.constant(72 : i32) : i32907// CHECK-NEXT: "llvm.intr.memcpy"(%[[arg0]], %[[arg1]], %[[size]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()908// CHECK-NEXT: llvm.return909// CHECK-NEXT: }910 911 912func.func @store_unlimited_polymorphic_box(%arg0 : !fir.class<none>, %arg1 : !fir.class<!fir.array<?xnone>>, %arg2 : !fir.box<none>, %arg3 : !fir.box<!fir.array<?xnone>>, %arg0r : !fir.ref<!fir.class<none>>, %arg1r : !fir.ref<!fir.class<!fir.array<?xnone>>>, %arg2r : !fir.ref<!fir.box<none>>, %arg3r : !fir.ref<!fir.box<!fir.array<?xnone>>>) {913 fir.store %arg0 to %arg0r : !fir.ref<!fir.class<none>>914 fir.store %arg1 to %arg1r : !fir.ref<!fir.class<!fir.array<?xnone>>>915 fir.store %arg2 to %arg2r : !fir.ref<!fir.box<none>>916 fir.store %arg3 to %arg3r : !fir.ref<!fir.box<!fir.array<?xnone>>>917 return918}919// CHECK: llvm.func @store_unlimited_polymorphic_box(%[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: !llvm.ptr, %[[VAL_2:.*]]: !llvm.ptr, %[[VAL_3:.*]]: !llvm.ptr, %[[VAL_4:.*]]: !llvm.ptr, %[[VAL_5:.*]]: !llvm.ptr, %[[VAL_6:.*]]: !llvm.ptr, %[[VAL_7:.*]]: !llvm.ptr) {920// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(40 : i32) : i32921// CHECK: "llvm.intr.memcpy"(%[[VAL_4]], %[[VAL_0]], %[[VAL_8]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()922// CHECK: %[[VAL_9:.*]] = llvm.mlir.constant(64 : i32) : i32923// CHECK: "llvm.intr.memcpy"(%[[VAL_5]], %[[VAL_1]], %[[VAL_9]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()924// CHECK: %[[VAL_10:.*]] = llvm.mlir.constant(40 : i32) : i32925// CHECK: "llvm.intr.memcpy"(%[[VAL_6]], %[[VAL_2]], %[[VAL_10]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()926// CHECK: %[[VAL_11:.*]] = llvm.mlir.constant(64 : i32) : i32927// CHECK: "llvm.intr.memcpy"(%[[VAL_7]], %[[VAL_3]], %[[VAL_11]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()928// CHECK: llvm.return929// CHECK: }930 931 932// -----933 934func.func @store_assumed_rank_box(%box: !fir.box<!fir.array<*:f32>>, %ref: !fir.ref<!fir.box<!fir.array<*:f32>>>) {935 fir.store %box to %ref : !fir.ref<!fir.box<!fir.array<*:f32>>>936 return937}938 939// CHECK-LABEL: llvm.func @store_assumed_rank_box(940// CHECK-SAME: %[[VAL_0:[^:]*]]: !llvm.ptr,941// CHECK-SAME: %[[VAL_1:.*]]: !llvm.ptr) {942// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(24 : i32) : i32943// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)>944// CHECK: %[[VAL_4:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i8945// CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i8 to i32946// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(24 : i32) : i32947// CHECK: %[[VAL_7:.*]] = llvm.mul %[[VAL_6]], %[[VAL_5]] : i32948// CHECK: %[[VAL_8:.*]] = llvm.add %[[VAL_2]], %[[VAL_7]] : i32949// CHECK: "llvm.intr.memcpy"(%[[VAL_1]], %[[VAL_0]], %[[VAL_8]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()950 951// -----952 953// Test `fir.load` --> `llvm.load` conversion954 955func.func @test_load_index(%addr : !fir.ref<index>) {956 %0 = fir.load %addr : !fir.ref<index>957 return958}959 960// CHECK-LABEL: llvm.func @test_load_index(961// CHECK-SAME: %[[arg1:.*]]: !llvm.ptr) {962// CHECK-NEXT: %0 = llvm.load %[[arg1]] : !llvm.ptr -> i64963// CHECK-NEXT: llvm.return964// CHECK-NEXT: }965 966func.func private @takes_box(!fir.box<!fir.array<10xf32>>) -> ()967 968func.func @test_load_box(%addr : !fir.ref<!fir.box<!fir.array<10xf32>>>) {969 %0 = fir.load %addr : !fir.ref<!fir.box<!fir.array<10xf32>>>970 fir.call @takes_box(%0) : (!fir.box<!fir.array<10xf32>>) -> ()971 return972}973 974// Loading a `fir.ref<!fir.box>> is creating a descriptor copy975// CHECK-LABEL: llvm.func @test_load_box(976// CHECK-SAME: %[[arg0:.*]]: !llvm.ptr) {977// CHECK-NEXT: %[[c1:.*]] = llvm.mlir.constant(1 : i32) : i32978// GENERIC-NEXT: %[[box_copy:.*]] = llvm.alloca %[[c1]] x !llvm.struct<([[DESC_TYPE:.*]])>979// AMDGPU-NEXT: %[[alloca_box_copy:.*]] = llvm.alloca %[[c1]] x !llvm.struct<([[DESC_TYPE:.*]])>{{.*}} : (i32) -> !llvm.ptr<5>980// AMDGPU-NEXT: %[[box_copy:.*]] = llvm.addrspacecast %[[alloca_box_copy]] : !llvm.ptr<5> to !llvm.ptr981// CHECK-NEXT: %[[size:.*]] = llvm.mlir.constant(48 : i32) : i32982// CHECK-NEXT: "llvm.intr.memcpy"(%[[box_copy]], %[[arg0]], %[[size]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()983// CHECK-NEXT: llvm.call @takes_box(%[[box_copy]]) : (!llvm.ptr) -> ()984// CHECK-NEXT: llvm.return985// CHECK-NEXT: }986 987// -----988 989func.func @test_assumed_rank_load(%arg0: !fir.ref<!fir.box<!fir.array<*:f64>>>) -> () {990 %0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.array<*:f64>>>991 fir.call @some_assumed_rank_func(%0) : (!fir.box<!fir.array<*:f64>>) -> ()992 return993}994func.func private @some_assumed_rank_func(!fir.box<!fir.array<*:f64>>) -> ()995 996// CHECK-LABEL: llvm.func @test_assumed_rank_load(997// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr) {998// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i32) : i32999// GENERIC: %[[VAL_2:.*]] = llvm.alloca %[[VAL_1]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr1000// AMDGPU: %[[VAL_2A:.*]] = llvm.alloca %[[VAL_1]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>1001// AMDGPU: %[[VAL_2:.*]] = llvm.addrspacecast %[[VAL_2A]] : !llvm.ptr<5> to !llvm.ptr1002// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(24 : i32) : i321003// CHECK: %[[VAL_4:.*]] = llvm.getelementptr %[[VAL_0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)>1004// CHECK: %[[VAL_5:.*]] = llvm.load %[[VAL_4]] : !llvm.ptr -> i81005// CHECK: %[[VAL_6:.*]] = llvm.sext %[[VAL_5]] : i8 to i321006// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(24 : i32) : i321007// CHECK: %[[VAL_8:.*]] = llvm.mul %[[VAL_7]], %[[VAL_6]] : i321008// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_3]], %[[VAL_8]] : i321009// CHECK: "llvm.intr.memcpy"(%[[VAL_2]], %[[VAL_0]], %[[VAL_9]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()1010// CHECK: llvm.call @some_assumed_rank_func(%[[VAL_2]]) : (!llvm.ptr) -> ()1011 1012// -----1013 1014// Test `fir.box_rank` conversion.1015 1016func.func @extract_rank(%arg0: !fir.box<!fir.array<*:f64>>) -> i32 {1017 %0 = fir.box_rank %arg0 : (!fir.box<!fir.array<*:f64>>) -> i321018 return %0 : i321019}1020 1021// CHECK-LABEL: llvm.func @extract_rank(1022// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i321023// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1024// CHECK: %[[RAW_RANK:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i81025// CHECK: %[[RANK:.*]] = llvm.sext %[[RAW_RANK]] : i8 to i321026// CHECK: llvm.return %[[RANK]] : i321027 1028func.func @extract_rank2(%arg0: !fir.ref<!fir.box<!fir.array<*:f64>>>) -> i32 {1029 %0 = fir.box_rank %arg0 : (!fir.ref<!fir.box<!fir.array<*:f64>>>) -> i321030 return %0 : i321031}1032 1033// CHECK-LABEL: llvm.func @extract_rank2(1034// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i321035// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1036// CHECK: %[[RAW_RANK:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i81037// CHECK: %[[RANK:.*]] = llvm.sext %[[RAW_RANK]] : i8 to i321038// CHECK: llvm.return %[[RANK]] : i321039 1040// -----1041 1042// Test `fir.box_addr` conversion.1043 1044func.func @extract_addr(%arg0: !fir.box<!fir.array<*:f64>>) -> !fir.ref<f64> {1045 %0 = fir.box_addr %arg0 : (!fir.box<!fir.array<*:f64>>) -> !fir.ref<f64>1046 return %0 : !fir.ref<f64>1047}1048 1049// CHECK-LABEL: llvm.func @extract_addr(1050// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> !llvm.ptr1051// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1052// CHECK: %[[ADDR:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr1053// CHECK: llvm.return %[[ADDR]] : !llvm.ptr1054 1055// -----1056 1057// Test `fir.box_dims` conversion.1058 1059func.func @extract_dims(%arg0: !fir.box<!fir.array<*:f64>>) -> index {1060 %c1 = arith.constant 0 : i321061 %cast = fir.convert %arg0 : (!fir.box<!fir.array<*:f64>>) -> !fir.box<!fir.array<?xf64>>1062 %0:3 = fir.box_dims %cast, %c1 : (!fir.box<!fir.array<?xf64>>, i32) -> (index, index, index)1063 return %0 : index1064}1065 1066// CHECK-LABEL: llvm.func @extract_dims(1067// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i641068// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i32) : i321069// CHECK: %[[GEP0:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[C0]], 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1070// CHECK: %[[LOAD0:.*]] = llvm.load %[[GEP0]] : !llvm.ptr -> i641071// CHECK: %[[GEP1:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[C0]], 1] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1072// CHECK: %[[LOAD1:.*]] = llvm.load %[[GEP1]] : !llvm.ptr -> i641073// CHECK: %[[GEP2:.*]] = llvm.getelementptr %[[ARG0]][0, 7, %[[C0]], 2] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1074// CHECK: %[[LOAD2:.*]] = llvm.load %[[GEP2]] : !llvm.ptr -> i641075// CHECK: llvm.return %[[LOAD0]] : i641076 1077// -----1078 1079// Test `fir.box_elesize` conversion.1080 1081func.func @extract_elesize(%arg0: !fir.box<f32>) -> i32 {1082 %0 = fir.box_elesize %arg0 : (!fir.box<f32>) -> i321083 return %0 : i321084}1085 1086// CHECK-LABEL: llvm.func @extract_elesize(1087// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i321088// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1089// CHECK: %[[ELE_SIZE:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i641090// CHECK: %[[ELE_SIZE_CONV:.*]] = llvm.trunc %[[ELE_SIZE]] : i64 to i321091// CHECK: llvm.return %[[ELE_SIZE_CONV]] : i321092 1093// -----1094 1095// Test `fir.box_isarray` conversion.1096// `rank` is extracted from `fir.box` and compare to 0.1097 1098func.func @box_isarray(%arg0: !fir.box<!fir.array<*:f64>>) -> i1 {1099 %0 = fir.box_isarray %arg0 : (!fir.box<!fir.array<*:f64>>) -> i11100 return %0 : i11101}1102 1103// CHECK-LABEL: llvm.func @box_isarray(1104// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i11105// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1106// CHECK: %[[RANK:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i81107// CHECK: %[[C0_ISARRAY:.*]] = llvm.mlir.constant(0 : i64) : i81108// CHECK: %[[IS_ARRAY:.*]] = llvm.icmp "ne" %[[RANK]], %[[C0_ISARRAY]] : i81109// CHECK: llvm.return %[[IS_ARRAY]] : i11110 1111// -----1112 1113// Test `fir.box_isalloc` conversion.1114// `attribute` is extracted from `fir.box` and checked against a mask equal to1115// the value of `CFI_attribute_allocatable`.1116 1117func.func @box_isalloc(%arg0: !fir.box<!fir.array<*:f64>>) -> i1 {1118 %0 = fir.box_isalloc %arg0 : (!fir.box<!fir.array<*:f64>>) -> i11119 return %0 : i11120}1121 1122// CHECK-LABEL: llvm.func @box_isalloc(1123// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i11124// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 5] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1125// CHECK: %[[ATTR:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i81126// CHECK: %[[ATTR_CONV:.*]] = llvm.sext %[[ATTR]] : i8 to i321127// CHECK: %[[ATTR_ISALLOC:.*]] = llvm.mlir.constant(2 : i32) : i321128// CHECK: %[[AND:.*]] = llvm.and %[[ATTR_CONV]], %[[ATTR_ISALLOC]] : i321129// CHECK: %[[CMP_C0:.*]] = llvm.mlir.constant(0 : i32) : i321130// CHECK: %[[IS_ALLOC:.*]] = llvm.icmp "ne" %[[AND]], %[[CMP_C0]] : i321131// CHECK: llvm.return %[[IS_ALLOC]] : i11132 1133// -----1134 1135// Test `fir.box_isptr` conversion.1136// `attribute` is extracted from `fir.box` and checked against a mask equal to1137// the value of `CFI_attribute_pointer`.1138 1139func.func @box_isptr(%arg0: !fir.box<!fir.array<*:f64>>) -> i1 {1140 %0 = fir.box_isptr %arg0 : (!fir.box<!fir.array<*:f64>>) -> i11141 return %0 : i11142}1143 1144// CHECK-LABEL: llvm.func @box_isptr(1145// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i11146// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 5] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1147// CHECK: %[[ATTR:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> i81148// CHECK: %[[ATTR_CONV:.*]] = llvm.sext %[[ATTR]] : i8 to i321149// CHECK: %[[ATTR_ISALLOC:.*]] = llvm.mlir.constant(1 : i32) : i321150// CHECK: %[[AND:.*]] = llvm.and %[[ATTR_CONV]], %[[ATTR_ISALLOC]] : i321151// CHECK: %[[CMP_C0:.*]] = llvm.mlir.constant(0 : i32) : i321152// CHECK: %[[IS_ALLOC:.*]] = llvm.icmp "ne" %[[AND]], %[[CMP_C0]] : i321153// CHECK: llvm.return %[[IS_ALLOC]] : i11154 1155// -----1156 1157// Test fir.alloca of one element1158 1159func.func @alloca_one() -> !fir.ref<i32> {1160 %1 = fir.alloca i321161 return %1 : !fir.ref<i32>1162}1163 1164// CHECK-LABEL: llvm.func @alloca_one() -> !llvm.ptr1165// CHECK: [[N:%.*]] = llvm.mlir.constant(1 : i64) : i641166// GENERIC: [[A:%.*]] = llvm.alloca [[N]] x i321167// AMDGPU: [[AA:%.*]] = llvm.alloca [[N]] x i32 : (i64) -> !llvm.ptr<5>1168// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1169// CHECK: llvm.return [[A]] : !llvm.ptr1170 1171 1172// -----1173 1174// Test fir.alloca of several elements1175 1176func.func @alloca_several() -> !fir.ref<i32> {1177 %0 = arith.constant 100 : index1178 %1 = fir.alloca i32, %01179 return %1 : !fir.ref<i32>1180}1181 1182// CHECK-LABEL: llvm.func @alloca_several() -> !llvm.ptr1183// CHECK: [[N:%.*]] = llvm.mlir.constant(100 : index) : i641184// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641185// CHECK: [[TOTAL:%.*]] = llvm.mul [[ONE]], [[N]] : i641186// GENERIC: [[A:%.*]] = llvm.alloca [[TOTAL]] x i321187// AMDGPU: [[AA:%.*]] = llvm.alloca [[TOTAL]] x i32 : (i64) -> !llvm.ptr<5>1188// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1189// CHECK: llvm.return [[A]] : !llvm.ptr1190 1191// -----1192 1193// Test fir.alloca of pointer to array1194 1195func.func @alloca_ptr_to_array() -> !fir.ref<!fir.ptr<!fir.array<?xi32>>> {1196 %1 = fir.alloca !fir.ptr<!fir.array<?xi32>>1197 return %1 : !fir.ref<!fir.ptr<!fir.array<?xi32>>>1198}1199 1200// CHECK-LABEL: llvm.func @alloca_ptr_to_array() -> !llvm.ptr1201// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641202// GENERIC: [[A:%.*]] = llvm.alloca [[ONE]] x !llvm.ptr1203// AMDGPU: [[AA:%.*]] = llvm.alloca [[ONE]] x !llvm.ptr : (i64) -> !llvm.ptr<5>1204// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1205// CHECK: llvm.return [[A]] : !llvm.ptr1206 1207// -----1208 1209// Test fir.alloca of array of unknown-length chars1210 1211func.func @alloca_char_array(%l: i32, %e : index) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>> {1212 %a = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%l : i32), %e, %e1213 return %a : !fir.ref<!fir.array<?x?x!fir.char<1,?>>>1214}1215 1216// CHECK-LABEL: llvm.func @alloca_char_array1217// CHECK-SAME: ([[L:%.*]]: i32, [[E:%.*]]: i64) -> !llvm.ptr1218// CHECK-DAG: [[UNUSEDONE:%.*]] = llvm.mlir.constant(1 : i64) : i641219// CHECK-DAG: [[LCAST:%.*]] = llvm.sext [[L]] : i32 to i641220// CHECK: [[PROD1:%.*]] = llvm.mul [[LCAST]], [[E]] : i641221// CHECK: [[PROD2:%.*]] = llvm.mul [[PROD1]], [[E]] : i641222// GENERIC: [[A:%.*]] = llvm.alloca [[PROD2]] x i81223// AMDGPU: [[AA:%.*]] = llvm.alloca [[PROD2]] x i8 : (i64) -> !llvm.ptr<5>1224// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1225// CHECK: return [[A]] : !llvm.ptr1226 1227// -----1228 1229// Test fir.alloca of array of known-length chars1230 1231func.func @alloca_fixed_char_array(%e : index) -> !fir.ref<!fir.array<?x?x!fir.char<1,8>>> {1232 %a = fir.alloca !fir.array<?x?x!fir.char<1,8>>, %e, %e1233 return %a : !fir.ref<!fir.array<?x?x!fir.char<1,8>>>1234}1235 1236// CHECK-LABEL: llvm.func @alloca_fixed_char_array1237// CHECK-SAME: ([[E:%.*]]: i64) -> !llvm.ptr1238// CHECK-DAG: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641239// CHECK: [[PROD1:%.*]] = llvm.mul [[E]], [[ONE]] : i641240// CHECK: [[PROD2:%.*]] = llvm.mul [[PROD1]], [[E]] : i641241// GENERIC: [[A:%.*]] = llvm.alloca [[PROD2]] x !llvm.array<8 x i8>1242// AMDGPU: [[AA:%.*]] = llvm.alloca [[PROD2]] x !llvm.array<8 x i8> : (i64) -> !llvm.ptr<5>1243// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1244// CHECK: return [[A]] : !llvm.ptr1245 1246// -----1247 1248// Test fir.alloca of record type with LEN parameters1249// type t(p1,p2)1250// integer, len :: p11251// integer(kind=2), len :: p21252// integer f11253// real f21254// end type t1255 1256func.func private @_QTtP.mem.size(%0 : i32, %1 : i16) -> index1257 1258func.func @alloca_record(%arg0 : i32, %arg1 : i16) -> !fir.ref<!fir.type<_QTt(p1:i32,p2:i16){f1:i32,f2:f32}>> {1259 %0 = fir.alloca !fir.type<_QTt(p1:i32,p2:i16){f1:i32,f2:f32}>(%arg0, %arg1 : i32, i16) {name = "_QEvar"}1260 return %0 : !fir.ref<!fir.type<_QTt(p1:i32,p2:i16){f1:i32,f2:f32}>>1261}1262 1263// CHECK-LABEL: llvm.func @alloca_record1264// CHECK-SAME: ([[ARG0:%.*]]: i32, [[ARG1:%.*]]: i16)1265// CHECK-SAME: -> !llvm.ptr1266// CHECK: [[SIZE:%.*]] = llvm.call @_QTtP.mem.size([[ARG0]], [[ARG1]]) : (i32, i16) -> i641267// GENERIC: [[ALLOC:%.*]] = llvm.alloca [[SIZE]] x i81268// AMDGPU: [[A:%.*]] = llvm.alloca [[SIZE]] x i8 : (i64) -> !llvm.ptr<5>1269// AMDGPU: [[ALLOC:%.*]] = llvm.addrspacecast [[A]] : !llvm.ptr<5> to !llvm.ptr1270// CHECK: llvm.return [[ALLOC]] : !llvm.ptr1271 1272// -----1273 1274// Test fir.alloca of a multidimensional array, with operands1275 1276func.func @alloca_multidim_array(%0 : index) -> !fir.ref<!fir.array<8x16x32xf32>> {1277 %1 = arith.constant 24 : index1278 %2 = fir.alloca !fir.array<8x16x32xf32>, %0, %11279 return %2 : !fir.ref<!fir.array<8x16x32xf32>>1280}1281 1282// CHECK-LABEL: llvm.func @alloca_multidim_array1283// CHECK-SAME: ([[OP1:%.*]]: i64) -> !llvm.ptr1284// CHECK: [[OP2:%.*]] = llvm.mlir.constant(24 : index) : i641285// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641286// CHECK: [[MUL1:%.*]] = llvm.mul [[OP1]], [[ONE]] : i641287// CHECK: [[TOTAL:%.*]] = llvm.mul [[MUL1]], [[OP2]] : i641288// GENERIC: [[A:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<32 x array<16 x array<8 x f32>>>1289// AMDGPU: [[AA:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<32 x array<16 x array<8 x f32>>> : (i64) -> !llvm.ptr<5>1290// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1291// CHECK: llvm.return [[A]] : !llvm.ptr1292 1293// -----1294 1295// Test fir.alloca of a multidimensional array with constant interior1296 1297func.func @alloca_const_interior_array(%0 : index) -> !fir.ref<!fir.array<8x9x?x?xf32>> {1298 %1 = arith.constant 64 : index1299 %2 = fir.alloca !fir.array<8x9x?x?xf32>, %0, %11300 return %2 : !fir.ref<!fir.array<8x9x?x?xf32>>1301}1302 1303// CHECK-LABEL: llvm.func @alloca_const_interior_array1304// CHECK-SAME: ([[OP1:%.*]]: i64) -> !llvm.ptr1305// CHECK: [[OP2:%.*]] = llvm.mlir.constant(64 : index) : i641306// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641307// CHECK: [[MUL1:%.*]] = llvm.mul [[OP1]], [[ONE]] : i641308// CHECK: [[TOTAL:%.*]] = llvm.mul [[MUL1]], [[OP2]] : i641309// GENERIC: [[A:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<9 x array<8 x f32>>1310// AMDGPU: [[AA:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<9 x array<8 x f32>> : (i64) -> !llvm.ptr<5>1311// AMDGPU: [[A:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1312// CHECK: llvm.return [[A]] : !llvm.ptr1313 1314// -----1315 1316// Test alloca with an array with holes.1317// Constant factor of 60 (4*3*5) must be included.1318 1319func.func @alloca_array_with_holes(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?x3x?x5xi32>> {1320 %a = fir.alloca !fir.array<4x?x3x?x5xi32>, %0, %11321 return %a : !fir.ref<!fir.array<4x?x3x?x5xi32>>1322}1323 1324// CHECK-LABEL: llvm.func @alloca_array_with_holes1325// CHECK-SAME: ([[A:%.*]]: i64, [[B:%.*]]: i64) -> !llvm.ptr1326// CHECK-DAG: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i641327// CHECK-DAG: [[FIXED:%.*]] = llvm.mlir.constant(15 : i64) : i641328// CHECK: [[PROD1:%.*]] = llvm.mul [[ONE]], [[FIXED]] : i641329// CHECK: [[PROD2:%.*]] = llvm.mul [[PROD1]], [[A]] : i641330// CHECK: [[PROD3:%.*]] = llvm.mul [[PROD2]], [[B]] : i641331// GENERIC: [[RES:%.*]] = llvm.alloca [[PROD3]] x !llvm.array<4 x i32>1332// AMDGPU: [[AA:%.*]] = llvm.alloca [[PROD3]] x !llvm.array<4 x i32> : (i64) -> !llvm.ptr<5>1333// AMDGPU: [[RES:%.*]] = llvm.addrspacecast [[AA]] : !llvm.ptr<5> to !llvm.ptr1334// CHECK: llvm.return [[RES]] : !llvm.ptr1335 1336// -----1337 1338// Test alloca of assumed-rank box1339 1340func.func @alloca_assumed_rank_box() -> !fir.ref<!fir.box<!fir.array<*:f32>>> {1341 %a = fir.alloca !fir.box<!fir.array<*:f32>>1342 return %a : !fir.ref<!fir.box<!fir.array<*:f32>>>1343}1344// CHECK-LABEL: llvm.func @alloca_assumed_rank_box1345// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i641346// GENERIC: llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> : (i64) -> !llvm.ptr1347// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> : (i64) -> !llvm.ptr<5>1348// AMDGPU: llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr1349 1350// -----1351 1352// Test `fir.select_case` operation conversion with INTEGER.1353 1354func.func @select_case_integer(%arg0: !fir.ref<i32>) -> i32 {1355 %2 = fir.load %arg0 : !fir.ref<i32>1356 %c1_i32 = arith.constant 1 : i321357 %c2_i32 = arith.constant 2 : i321358 %c4_i32 = arith.constant 4 : i321359 %c5_i32 = arith.constant 5 : i321360 %c7_i32 = arith.constant 7 : i321361 %c8_i32 = arith.constant 8 : i321362 %c15_i32 = arith.constant 15 : i321363 %c21_i32 = arith.constant 21 : i321364 fir.select_case %2 : i32 [#fir.upper, %c1_i32, ^bb1,1365 #fir.point, %c2_i32, ^bb2,1366 #fir.interval, %c4_i32, %c5_i32, ^bb4,1367 #fir.point, %c7_i32, ^bb5,1368 #fir.interval, %c8_i32, %c15_i32, ^bb5,1369 #fir.lower, %c21_i32, ^bb5,1370 unit, ^bb3]1371^bb1: // pred: ^bb01372 %c1_i32_0 = arith.constant 1 : i321373 fir.store %c1_i32_0 to %arg0 : !fir.ref<i32>1374 cf.br ^bb61375^bb2: // pred: ^bb01376 %c2_i32_1 = arith.constant 2 : i321377 fir.store %c2_i32_1 to %arg0 : !fir.ref<i32>1378 cf.br ^bb61379^bb3: // pred: ^bb01380 %c0_i32 = arith.constant 0 : i321381 fir.store %c0_i32 to %arg0 : !fir.ref<i32>1382 cf.br ^bb61383^bb4: // pred: ^bb01384 %c4_i32_2 = arith.constant 4 : i321385 fir.store %c4_i32_2 to %arg0 : !fir.ref<i32>1386 cf.br ^bb61387^bb5: // 3 preds: ^bb0, ^bb0, ^bb01388 %c7_i32_3 = arith.constant 7 : i321389 fir.store %c7_i32_3 to %arg0 : !fir.ref<i32>1390 cf.br ^bb61391^bb6: // 5 preds: ^bb1, ^bb2, ^bb3, ^bb4, ^bb51392 %3 = fir.load %arg0 : !fir.ref<i32>1393 return %3 : i321394}1395 1396// CHECK-LABEL: llvm.func @select_case_integer(1397// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) -> i32 {1398// CHECK: %[[SELECT_VALUE:.*]] = llvm.load %[[ARG0]] : !llvm.ptr -> i321399// CHECK: %[[CST1:.*]] = llvm.mlir.constant(1 : i32) : i321400// CHECK: %[[CST2:.*]] = llvm.mlir.constant(2 : i32) : i321401// CHECK: %[[CST4:.*]] = llvm.mlir.constant(4 : i32) : i321402// CHECK: %[[CST5:.*]] = llvm.mlir.constant(5 : i32) : i321403// CHECK: %[[CST7:.*]] = llvm.mlir.constant(7 : i32) : i321404// CHECK: %[[CST8:.*]] = llvm.mlir.constant(8 : i32) : i321405// CHECK: %[[CST15:.*]] = llvm.mlir.constant(15 : i32) : i321406// CHECK: %[[CST21:.*]] = llvm.mlir.constant(21 : i32) : i321407// Check for upper bound `case (:1)`1408// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST1]] : i321409// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb2, ^bb11410// CHECK-LABEL: ^bb1:1411// Check for point value `case (2)`1412// CHECK: %[[CMP_EQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST2]] : i321413// CHECK: llvm.cond_br %[[CMP_EQ]], ^bb4, ^bb31414// Block ^bb1 in original FIR code.1415// CHECK-LABEL: ^bb2:1416// CHECK: llvm.br ^bb{{.*}}1417// CHECK-LABEL: ^bb3:1418// Check for the lower bound for the interval `case (4:5)`1419// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[CST4]], %[[SELECT_VALUE]] : i321420// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb[[UPPERBOUND5:.*]], ^bb71421// Block ^bb2 in original FIR code.1422// CHECK-LABEL: ^bb4:1423// CHECK: llvm.br ^bb{{.*}}1424// Block ^bb3 in original FIR code.1425// CHECK-LABEL: ^bb5:1426// CHECK: llvm.br ^bb{{.*}}1427// CHECK: ^bb[[UPPERBOUND5]]:1428// Check for the upper bound for the interval `case (4:5)`1429// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST5]] : i321430// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb8, ^bb71431// CHECK-LABEL: ^bb7:1432// Check for the point value 7 in `case (7,8:15,21:)`1433// CHECK: %[[CMP_EQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST7]] : i321434// CHECK: llvm.cond_br %[[CMP_EQ]], ^bb13, ^bb91435// Block ^bb4 in original FIR code.1436// CHECK-LABEL: ^bb8:1437// CHECK: llvm.br ^bb{{.*}}1438// CHECK-LABEL: ^bb9:1439// Check for lower bound 8 in `case (7,8:15,21:)`1440// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[CST8]], %[[SELECT_VALUE]] : i321441// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb[[INTERVAL8_15:.*]], ^bb111442// CHECK: ^bb[[INTERVAL8_15]]:1443// Check for upper bound 15 in `case (7,8:15,21:)`1444// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST15]] : i321445// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb13, ^bb111446// CHECK-LABEL: ^bb11:1447// Check for lower bound 21 in `case (7,8:15,21:)`1448// CHECK: %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[CST21]], %[[SELECT_VALUE]] : i321449// CHECK: llvm.cond_br %[[CMP_SLE]], ^bb13, ^bb121450// CHECK-LABEL: ^bb12:1451// CHECK: llvm.br ^bb51452// Block ^bb5 in original FIR code.1453// CHECK-LABEL: ^bb13:1454// CHECK: llvm.br ^bb141455// Block ^bb6 in original FIR code.1456// CHECK-LABEL: ^bb14:1457// CHECK: %[[RET:.*]] = llvm.load %[[ARG0:.*]] : !llvm.ptr -> i321458// CHECK: llvm.return %[[RET]] : i321459 1460// -----1461 1462// Test `fir.select_case` operation conversion with LOGICAL.1463 1464func.func @select_case_logical(%arg0: !fir.ref<!fir.logical<4>>) {1465 %1 = fir.load %arg0 : !fir.ref<!fir.logical<4>>1466 %2 = fir.convert %1 : (!fir.logical<4>) -> i11467 %false = arith.constant false1468 %true = arith.constant true1469 fir.select_case %2 : i1 [#fir.point, %false, ^bb1,1470 #fir.point, %true, ^bb2,1471 unit, ^bb3]1472^bb1:1473 %c1_i32 = arith.constant 1 : i321474 cf.br ^bb31475^bb2:1476 %c2_i32 = arith.constant 2 : i321477 cf.br ^bb31478^bb3:1479 return1480}1481 1482// CHECK-LABEL: llvm.func @select_case_logical(1483// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr1484// CHECK: %[[LOAD_ARG0:.*]] = llvm.load %[[ARG0]] : !llvm.ptr -> i321485// CHECK: %[[CST_ZERO:.*]] = llvm.mlir.constant(0 : i64) : i321486// CHECK: %[[SELECT_VALUE:.*]] = llvm.icmp "ne" %[[LOAD_ARG0]], %[[CST_ZERO]] : i321487// CHECK: %[[CST_FALSE:.*]] = llvm.mlir.constant(false) : i11488// CHECK: %[[CST_TRUE:.*]] = llvm.mlir.constant(true) : i11489// CHECK: %[[CMPEQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST_FALSE]] : i11490// CHECK: llvm.cond_br %[[CMPEQ]], ^bb2, ^bb11491// CHECK-LABEL: ^bb1:1492// CHECK: %[[CMPEQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST_TRUE]] : i11493// CHECK: llvm.cond_br %[[CMPEQ]], ^bb4, ^bb31494// CHECK-LABEL: ^bb2:1495// CHECK: llvm.br ^bb51496// CHECK-LABEL: ^bb3:1497// CHECK: llvm.br ^bb51498// CHECK-LABEL: ^bb4:1499// CHECK: llvm.br ^bb51500// CHECK-LABEL: ^bb5:1501// CHECK: llvm.return1502 1503// -----1504 1505// Test `fir.is_present`1506 1507func.func @test_is_present_i64(%arg0: !fir.ref<i64>) -> () {1508 %0 = fir.is_present %arg0 : (!fir.ref<i64>) -> i11509 return1510}1511 1512// CHECK-LABEL: @test_is_present_i641513// CHECK-SAME: (%[[arg:.*]]: !llvm.ptr)1514// CHECK-NEXT: %[[constant:.*]] = llvm.mlir.constant(0 : i64) : i641515// CHECK-NEXT: %[[ptr:.*]] = llvm.ptrtoint %[[arg]] : !llvm.ptr to i641516// CHECK-NEXT: %{{.*}} = llvm.icmp "ne" %[[ptr]], %[[constant]] : i641517// CHECK-NEXT: llvm.return1518// CHECK-NEXT: }1519 1520func.func @test_is_present_box(%arg0: !fir.box<!fir.ref<i64>>) -> () {1521 %0 = fir.is_present %arg0 : (!fir.box<!fir.ref<i64>>) -> i11522 return1523}1524 1525// CHECK-LABEL: @test_is_present_box1526// CHECK-SAME: (%[[arg:.*]]: !llvm.ptr)1527// CHECK-NEXT: %[[constant:.*]] = llvm.mlir.constant(0 : i64) : i641528// CHECK-NEXT: %[[ptr:.*]] = llvm.ptrtoint %[[arg]] : !llvm.ptr to i641529// CHECK-NEXT: %{{.*}} = llvm.icmp "ne" %[[ptr]], %[[constant]] : i641530// CHECK-NEXT: llvm.return1531// CHECK-NEXT: }1532 1533 1534// -----1535 1536// Test `fir.absent`1537 1538func.func @test_absent_i64() -> () {1539 %0 = fir.absent !fir.ref<i64>1540 return1541}1542 1543// CHECK-LABEL: @test_absent_i641544// CHECK-NEXT: %{{.*}} = llvm.mlir.zero : !llvm.ptr1545// CHECK-NEXT: llvm.return1546// CHECK-NEXT: }1547 1548func.func @test_absent_box() -> () {1549 %0 = fir.absent !fir.box<!fir.array<?xf32>>1550 return1551}1552// CHECK-LABEL: @test_absent_box1553// CHECK-NEXT: %{{.*}} = llvm.mlir.zero : !llvm.ptr1554// CHECK-NEXT: llvm.return1555// CHECK-NEXT: }1556 1557// -----1558 1559// This is a bit more comprehensive test for `fir.is_present` and `fir.absent`1560// when used together1561 1562func.func @is_present(%arg0: !fir.ref<i64>) -> i1 {1563 %0 = fir.is_present %arg0 : (!fir.ref<i64>) -> i11564 return %0 : i11565}1566 1567// CHECK-LABEL: @is_present1568// CHECK-SAME: (%[[arg:.*]]: !llvm.ptr) -> i11569// CHECK-NEXT: %[[constant:.*]] = llvm.mlir.constant(0 : i64) : i641570// CHECK-NEXT: %[[ptr:.*]] = llvm.ptrtoint %[[arg]] : !llvm.ptr to i641571// CHECK-NEXT: %[[ret_val:.*]] = llvm.icmp "ne" %[[ptr]], %[[constant]] : i641572// CHECK-NEXT: llvm.return %[[ret_val]] : i11573// CHECK-NEXT: }1574 1575func.func @absent() -> i1 {1576 %0 = fir.absent !fir.ref<i64>1577 %1 = fir.call @is_present(%0) : (!fir.ref<i64>) -> i11578 return %1 : i11579}1580 1581// CHECK-LABEL: @absent1582// CHECK-SAME: () -> i11583// CHECK-NEXT: %[[ptr:.*]] = llvm.mlir.zero : !llvm.ptr1584// CHECK-NEXT: %[[ret_val:.*]] = llvm.call @is_present(%[[ptr]]) : (!llvm.ptr) -> i11585// CHECK-NEXT: llvm.return %[[ret_val]] : i11586 1587// -----1588 1589// Test `fir.string_lit` conversion.1590 1591func.func @string_lit0() {1592 %1 = fir.string_lit "Hello, World!"(13) : !fir.char<1>1593 return1594}1595 1596// CHECK-LABEL: llvm.func @string_lit01597// CHECK: %{{.*}} = llvm.mlir.constant("Hello, World!") : !llvm.array<13 x i8>1598 1599func.func @string_lit1() {1600 %2 = fir.string_lit [158, 2345](2) : !fir.char<2>1601 return1602}1603 1604// CHECK-LABEL: llvm.func @string_lit11605// %{{.*}} = llvm.mlir.constant(dense<[158, 2345]> : vector<2xi16>) : !llvm.array<2 x i16>1606 1607// -----1608 1609// Test must be dead conversion.1610 1611func.func @dead_shift() {1612 %c0 = arith.constant 0 : index1613 %0 = fir.shift %c0 : (index) -> !fir.shift<1>1614 return1615}1616 1617// CHECK-LABEL: llvm.func @dead_shift1618// CHECK-NOT: fir.shift1619// CHECK: %{{.*}} = llvm.mlir.constant(0 : index) : i{{.*}}1620// CHECK-NEXT: llvm.return1621 1622func.func @dead_shape() {1623 %c0 = arith.constant 0 : index1624 %0 = fir.shape %c0 : (index) -> !fir.shape<1>1625 return1626}1627 1628// CHECK-LABEL: llvm.func @dead_shape1629// CHECK-NOT: fir.shape1630// CHECK: %{{.*}} = llvm.mlir.constant(0 : index) : i{{.*}}1631// CHECK-NEXT: llvm.return1632 1633func.func @dead_shapeshift() {1634 %c0 = arith.constant 0 : index1635 %0 = fir.shape_shift %c0, %c0 : (index, index) -> !fir.shapeshift<1>1636 return1637}1638 1639// CHECK-LABEL: llvm.func @dead_shapeshift1640// CHECK-NOT: fir.shape_shift1641// CHECK: %{{.*}} = llvm.mlir.constant(0 : index) : i{{.*}}1642// CHECK-NEXT: llvm.return1643 1644func.func @dead_slice() {1645 %c0 = arith.constant 0 : index1646 %0 = fir.slice %c0, %c0, %c0 : (index, index, index) -> !fir.slice<1>1647 return1648}1649 1650// CHECK-LABEL: llvm.func @dead_slice1651// CHECK-NOT: fir.slice1652// CHECK: %{{.*}} = llvm.mlir.constant(0 : index) : i{{.*}}1653// CHECK-NEXT: llvm.return1654 1655// -----1656 1657// Test `fir.box_tdesc` conversion.1658 1659func.func @box_tdesc(%arg0: !fir.box<!fir.type<dtdesc{a:i32}>>) {1660 %0 = fir.box_tdesc %arg0 : (!fir.box<!fir.type<dtdesc{a:i32}>>) -> !fir.tdesc<!fir.type<dtdesc{a:i32}>>1661 return1662}1663 1664// CHECK-LABEL: llvm.func @box_tdesc(1665// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) {1666// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 7] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>1667// CHECK: %[[LOAD:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr1668 1669// -----1670 1671// Test `fir.embox` conversion.1672 1673// Check basic creation of a descriptor and insertion of values.1674// The indices used to insert values into the descriptor correspond the1675// position of the fields in the descriptor as defined in `CFI_cdesc_t` in1676// flang/ISO_Fortran_binding.h.1677 1678func.func @embox0(%arg0: !fir.ref<!fir.array<100xi32>>) {1679 %0 = fir.embox %arg0() : (!fir.ref<!fir.array<100xi32>>) -> !fir.box<!fir.array<100xi32>>1680 return1681}1682 1683// CHECK-LABEL: func @embox0(1684// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr1685// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i321686// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[C1]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})> {alignment = 8 : i64} : (i32) -> !llvm.ptr1687// AMDGPU: %[[AA:.*]] = llvm.alloca %[[C1]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>1688// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr1689// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i321690// CHECK: %[[I64_ELEM_SIZE:.*]] = llvm.mlir.constant(4 : i64) : i641691// CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1692// CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[I64_ELEM_SIZE]], %[[DESC]][1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1693// CHECK: %[[CFI_VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i321694// CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[CFI_VERSION]], %[[DESC0]][2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1695// CHECK: %[[RANK:.*]] = llvm.mlir.constant(0 : i32) : i321696// CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i81697// CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[RANK_I8]], %[[DESC1]][3] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1698// CHECK: %[[TYPE_CODE_I8:.*]] = llvm.trunc %[[TYPE_CODE]] : i32 to i81699// CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[TYPE_CODE_I8]], %[[DESC2]][4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1700// CHECK: %[[ATTR:.*]] = llvm.mlir.constant(0 : i32) : i321701// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[ATTR]] : i32 to i81702// CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[ATTR_I8]], %[[DESC3]][5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1703// CHECK: %[[F18ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i321704// CHECK: %[[F18ADDENDUM_I8:.*]] = llvm.trunc %[[F18ADDENDUM]] : i32 to i81705// CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[DESC4]][6] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1706// CHECK: %[[DESC6:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC5]][0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1707// CHECK: llvm.store %[[DESC6]], %[[ALLOCA]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>, !llvm.ptr1708 1709// Check `fir.embox` in a `fir.global`. Descriptors created by `fir.embox`1710// conversion are not generating `alloca` instructions. This test make sure of1711// that.1712 1713fir.global @box_global : !fir.ref<!fir.array<?xi32>> {1714 %arr = fir.zero_bits !fir.ref<!fir.array<?xi32>>1715 %0 = arith.constant 0 : index1716 %3 = fir.embox %arr: (!fir.ref<!fir.array<?xi32>>) -> !fir.box<!fir.array<?xi32>>1717 fir.has_value %arr : !fir.ref<!fir.array<?xi32>>1718}1719 1720// CHECK-LABEL: llvm.mlir.global external @box_global1721// CHECK-NOT: llvm.alloca1722 1723// Check `fir.embox` conversion of a POINTER entity. Make sure that the1724// attribute in the descriptor is set to 1 (value of CFI_attribute_pointer1725// in flang/ISO_Fortran_binding.h).1726 1727func.func @embox_pointer(%arg0: !fir.ref<i32>) {1728 %0 = fir.embox %arg0 : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>1729 return1730}1731 1732// CHECK-LABEL: llvm.func @embox_pointer1733// Check 1st 1 constant to skip it.1734// CHECK: %{{.*}} = llvm.mlir.constant(1 : i32) : i321735// CHECK: %[[CFI_ATTR_POINTER:.*]] = llvm.mlir.constant(1 : i32) : i321736// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[CFI_ATTR_POINTER]] : i32 to i81737// CHECK: %{{.*}} = llvm.insertvalue %[[ATTR_I8]], %{{.*}}[5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1738 1739// Check `fir.embox` conversion of an ALLOCATABLE entity. Make sure that the1740// attribute in the descriptor is set to 2 (value of CFI_attribute_allocatable1741// in flang/ISO_Fortran_binding.h).1742 1743func.func @embox_allocatable(%arg0: !fir.heap<!fir.array<?x!fir.char<1,10>>>) {1744 %0 = fir.embox %arg0 : (!fir.heap<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>1745 return1746}1747 1748// CHECK-LABEL: llvm.func @embox_allocatable1749// CHECK: %[[CFI_ATTR_ALLOCATABLE:.*]] = llvm.mlir.constant(2 : i32) : i321750// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[CFI_ATTR_ALLOCATABLE]] : i32 to i81751// CHECK: %{{.*}} = llvm.insertvalue %[[ATTR_I8]], %{{.*}}[5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1752 1753// Check `fir.embox` conversion of a type code.1754 1755func.func @embox_typecode0(%arg0: !fir.ref<i64>) {1756 %0 = fir.embox %arg0 : (!fir.ref<i64>) -> !fir.box<!fir.ptr<i64>>1757 return1758}1759 1760// CHECK-LABEL: llvm.func @embox_typecode01761// CHECK: %[[TYPE_CODE_I64:.*]] = llvm.mlir.constant(10 : i32) : i321762// CHECK: %[[TYPE_CODE_I64_I8:.*]] = llvm.trunc %[[TYPE_CODE_I64]] : i32 to i81763// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_I64_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1764 1765func.func @embox_typecode1(%arg0: !fir.ref<f32>) {1766 %0 = fir.embox %arg0 : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>1767 return1768}1769 1770// CHECK-LABEL: llvm.func @embox_typecode11771// CHECK: %[[TYPE_CODE_F32:.*]] = llvm.mlir.constant(27 : i32) : i321772// CHECK: %[[TYPE_CODE_F32_I8:.*]] = llvm.trunc %[[TYPE_CODE_I64]] : i32 to i81773// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_F32_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1774 1775func.func @embox_typecode2(%arg0: !fir.ref<f128>) {1776 %0 = fir.embox %arg0 : (!fir.ref<f128>) -> !fir.box<!fir.ptr<f128>>1777 return1778}1779 1780// CHECK-LABEL: llvm.func @embox_typecode21781// CHECK: %[[TYPE_CODE_F128:.*]] = llvm.mlir.constant(31 : i32) : i321782// CHECK: %[[TYPE_CODE_F128_I8:.*]] = llvm.trunc %[[TYPE_CODE_F128]] : i32 to i81783// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_F128_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1784 1785func.func @embox_typecode3(%arg0: !fir.ref<complex<f32>>) {1786 %0 = fir.embox %arg0 : (!fir.ref<complex<f32>>) -> !fir.box<!fir.ptr<complex<f32>>>1787 return1788}1789 1790// CHECK-LABEL: llvm.func @embox_typecode31791// CHECK: %[[TYPE_CODE_CPLX4:.*]] = llvm.mlir.constant(34 : i32) : i321792// CHECK: %[[TYPE_CODE_CPLX4_I8:.*]] = llvm.trunc %[[TYPE_CODE_F128]] : i32 to i81793// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_CPLX4_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1794 1795func.func @embox_typecode4(%arg0: !fir.ref<!fir.logical<1>>) {1796 %0 = fir.embox %arg0 : (!fir.ref<!fir.logical<1>>) -> !fir.box<!fir.ptr<!fir.logical<1>>>1797 return1798}1799 1800// CHECK-LABEL: llvm.func @embox_typecode41801// CHECK: %[[TYPE_CODE_I64:.*]] = llvm.mlir.constant(39 : i32) : i321802// CHECK: %[[TYPE_CODE_I64_I8:.*]] = llvm.trunc %[[TYPE_CODE_I64]] : i32 to i81803// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_I64_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>1804 1805// -----1806 1807// Test `fir.embox` conversion. This test creates a global so it needs to be1808// split from others.1809 1810// Check descriptor for a derived type. Check that the f18Addendum flag is set1811// to 1 meaning the addendum is present (true) and the addendum values are1812// inserted.1813 1814fir.global linkonce @_QMtest_dinitE.dt.tseq constant : i81815 1816func.func @embox1(%arg0: !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>) {1817 %0 = fir.embox %arg0() : (!fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTtseq{i:i32}>>1818 return1819}1820 1821// CHECK-COMDAT: llvm.mlir.global linkonce constant @_QMtest_dinitE.dt.tseq() comdat(@__llvm_comdat::@_QMtest_dinitE.dt.tseq) {addr_space = 0 : i32} : i81822// CHECK-NO-COMDAT: llvm.mlir.global linkonce constant @_QMtest_dinitE.dt.tseq() {addr_space = 0 : i32} : i81823// CHECK-LABEL: llvm.func @embox11824// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(42 : i32) : i321825// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i321826// CHECK: %{{.*}} = llvm.insertvalue %[[VERSION]], %{{.*}}[2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, ptr, array<1 x i64>)> 1827// CHECK: %[[TYPE_CODE_I8:.*]] = llvm.trunc %[[TYPE_CODE]] : i32 to i81828// CHECK: %{{.*}} = llvm.insertvalue %[[TYPE_CODE_I8]], %{{.*}}[4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>1829// GENERIC: %[[TDESC:.*]] = llvm.mlir.addressof @_QMtest_dinitE.dt.tseq : !llvm.ptr1830// AMDGPU: %[[ADDROF:.*]] = llvm.mlir.addressof @_QMtest_dinitE.dt.tseq : !llvm.ptr<1>1831// AMDGPU: %[[TDESC:.*]] = llvm.addrspacecast %[[ADDROF]] : !llvm.ptr<1> to !llvm.ptr1832// CHECK: %{{.*}} = llvm.insertvalue %[[TDESC]], %{{.*}}[7] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>1833 1834// -----1835 1836// Test `fir.field_index`1837 1838func.func @field_index_static_size_1_elem() -> () {1839 %1 = fir.field_index i, !fir.type<t1{i:i32}>1840 return1841}1842 1843// CHECK-LABEL: @field_index_static_size_1_elem1844// CHECK-NEXT: %{{.*}} = llvm.mlir.constant(0 : i32) : i321845// CHECK-NEXT: llvm.return1846 1847func.func @field_index_static_size_3_elems() -> () {1848 %1 = fir.field_index k, !fir.type<t2{i:i32, j:f32, k:i8}>1849 return1850}1851 1852// CHECK-LABEL: @field_index_static_size_3_elems1853// CHECK-NEXT: %{{.*}} = llvm.mlir.constant(2 : i32) : i321854// CHECK-NEXT: llvm.return1855 1856// When converting `fir.field_index` for a dynamically sized record, the1857// offset will be calculated at runtime by calling methods like the ones1858// below. Note that these methods would normally be generated by the compiler.1859func.func private @custom_typeP.field_1.offset() -> i321860func.func private @custom_typeP.field_2.offset() -> i321861 1862func.func @field_index_dynamic_size() -> () {1863 %1 = fir.field_index field_1, !fir.type<custom_type(l:i32){field_1:i32, field_2:!fir.array<?xf32>}>1864 %2 = fir.field_index field_2, !fir.type<custom_type(l:i32){field_1:i32, field_2:!fir.array<?xf32>}>1865 return1866}1867 1868// CHECK-LABEL: @field_index_dynamic_size1869// CHECK-NEXT: %{{.*}} = llvm.call @custom_typeP.field_1.offset() {field = 0 : i64} : () -> i321870// CHECK-NEXT: %{{.*}} = llvm.call @custom_typeP.field_2.offset() {field = 1 : i64} : () -> i321871// CHECK-NEXT: llvm.return1872 1873// -----1874 1875// Check `fir.no_reassoc` conversion to LLVM IR dialect1876 1877func.func @no_reassoc(%arg0: !fir.ref<i32>) {1878 %0 = fir.alloca i321879 %1 = fir.load %arg0 : !fir.ref<i32>1880 %2 = fir.no_reassoc %1 : i321881 fir.store %2 to %0 : !fir.ref<i32>1882 return1883}1884 1885// CHECK-LABEL: llvm.func @no_reassoc(1886// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) {1887// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i641888// GENERIC: %[[ALLOC:.*]] = llvm.alloca %[[C1]] x i32 : (i64) -> !llvm.ptr1889// AMDGPU: %[[AA:.*]] = llvm.alloca %[[C1]] x i32 : (i64) -> !llvm.ptr<5>1890// AMDGPU: %[[ALLOC:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr1891// CHECK: %[[LOAD:.*]] = llvm.load %[[ARG0]] : !llvm.ptr -> i321892// CHECK: llvm.store %[[LOAD]], %[[ALLOC]] : i32, !llvm.ptr1893// CHECK: llvm.return1894 1895// -----1896 1897// Test `fircg.ext_embox` conversion.1898 1899// Check complete `fircg.ext_embox`.1900 1901func.func @xembox0(%arg0: !fir.ref<!fir.array<?xi32>>) {1902 %c0 = arith.constant 0 : i641903 %0 = fircg.ext_embox %arg0(%c0) origin %c0[%c0, %c0, %c0] : (!fir.ref<!fir.array<?xi32>>, i64, i64, i64, i64, i64) -> !fir.box<!fir.array<?xi32>>1904 return1905}1906 1907// CHECK-LABEL: llvm.func @xembox0(1908// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr1909// CHECK: %[[ALLOCA_SIZE:.*]] = llvm.mlir.constant(1 : i32) : i321910// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr1911// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>1912// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr1913// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i641914// CHECK: %[[TYPE:.*]] = llvm.mlir.constant(9 : i32) : i321915// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.mlir.constant(4 : i64) : i641916// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1917// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1918// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i321919// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1920// CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i321921// CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i81922// CHECK: %[[BOX3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[BOX2]][3] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1923// CHECK: %[[TYPE_I8:.*]] = llvm.trunc %[[TYPE]] : i32 to i81924// CHECK: %[[BOX4:.*]] = llvm.insertvalue %[[TYPE_I8]], %[[BOX3]][4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1925// CHECK: %[[ATTR:.*]] = llvm.mlir.constant(0 : i32) : i321926// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[ATTR]] : i32 to i81927// CHECK: %[[BOX5:.*]] = llvm.insertvalue %[[ATTR_I8]], %[[BOX4]][5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1928// CHECK: %[[F18ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i321929// CHECK: %[[F18ADDENDUM_I8:.*]] = llvm.trunc %[[F18ADDENDUM]] : i32 to i81930// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1931// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i641932// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i641933// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C0]], %[[C0]] : i641934// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[ONE]] : i641935// CHECK: %[[PTR_OFFSET:.*]] = llvm.add %[[DIM_OFFSET]], %[[ZERO]] : i641936// CHECK: %[[EXTENT0:.*]] = llvm.sub %[[C0]], %[[C0]] : i641937// CHECK: %[[EXTENT1:.*]] = llvm.add %[[EXTENT0]], %[[C0]] : i641938// CHECK: %[[EXTENT2:.*]] = llvm.sdiv %[[EXTENT1]], %[[C0]] : i641939// CHECK: %[[EXTENT_CMP:.*]] = llvm.icmp "sgt" %[[EXTENT2]], %[[ZERO]] : i641940// CHECK: %[[EXTENT:.*]] = llvm.select %[[EXTENT_CMP]], %[[EXTENT2]], %[[ZERO]] : i1, i641941// CHECK: %[[BOX7:.*]] = llvm.insertvalue %[[ONE]], %[[BOX6]][7, 0, 0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1942// CHECK: %[[BOX8:.*]] = llvm.insertvalue %[[EXTENT]], %[[BOX7]][7, 0, 1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1943// CHECK: %[[STRIDE:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0]] : i641944// CHECK: %[[BOX9:.*]] = llvm.insertvalue %[[STRIDE]], %[[BOX8]][7, 0, 2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1945// CHECK: %[[PREV_DIM:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0]] : i641946// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[ONE]], %[[C0]] : i641947// CHECK: %[[BASE_PTR:.*]] = llvm.getelementptr %[[ARG0]][%[[PTR_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i321948// CHECK: %[[BOX10:.*]] = llvm.insertvalue %[[BASE_PTR]], %[[BOX9]][0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1949// CHECK: llvm.store %[[BOX10]], %[[ALLOCA]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>, !llvm.ptr1950 1951// Test i32 shape/shift/slice:1952func.func @xembox0_i32(%arg0: !fir.ref<!fir.array<?xi32>>) {1953 %c0 = arith.constant 0 : i321954 %c0_i64 = arith.constant 0 : i641955 %0 = fircg.ext_embox %arg0(%c0) origin %c0[%c0, %c0, %c0] : (!fir.ref<!fir.array<?xi32>>, i32, i32, i32, i32, i32) -> !fir.box<!fir.array<?xi32>>1956 return1957}1958// CHECK-LABEL: llvm.func @xembox0_i32(1959// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr1960// CHECK: %[[ALLOCA_SIZE:.*]] = llvm.mlir.constant(1 : i32) : i321961// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr1962// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>1963// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr1964// CHECK: %[[C0_I32:.*]] = llvm.mlir.constant(0 : i32) : i321965// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i641966// CHECK: %[[TYPE:.*]] = llvm.mlir.constant(9 : i32) : i321967// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.mlir.constant(4 : i64) : i641968// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1969// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1970// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i321971// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1972// CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i321973// CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i81974// CHECK: %[[BOX3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[BOX2]][3] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1975// CHECK: %[[TYPE_I8:.*]] = llvm.trunc %[[TYPE]] : i32 to i81976// CHECK: %[[BOX4:.*]] = llvm.insertvalue %[[TYPE_I8]], %[[BOX3]][4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1977// CHECK: %[[ATTR:.*]] = llvm.mlir.constant(0 : i32) : i321978// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[ATTR]] : i32 to i81979// CHECK: %[[BOX5:.*]] = llvm.insertvalue %[[ATTR_I8]], %[[BOX4]][5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1980// CHECK: %[[F18ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i321981// CHECK: %[[F18ADDENDUM_I8:.*]] = llvm.trunc %[[F18ADDENDUM]] : i32 to i81982// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>1983// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i641984// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i641985// CHECK: %[[C0_1:.*]] = llvm.sext %[[C0_I32]] : i32 to i641986// CHECK: %[[C0_2:.*]] = llvm.sext %[[C0_I32]] : i32 to i641987// CHECK: %[[C0_3:.*]] = llvm.sext %[[C0_I32]] : i32 to i641988// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C0_2]], %[[C0_3]] : i641989// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[ONE]] : i641990// CHECK: %[[PTR_OFFSET:.*]] = llvm.add %[[DIM_OFFSET]], %[[ZERO]] : i641991// CHECK: %[[C0_4:.*]] = llvm.sext %[[C0_I32]] : i32 to i641992// CHECK: %[[C0_5:.*]] = llvm.sext %[[C0_I32]] : i32 to i641993// CHECK: %[[C0_6:.*]] = llvm.sext %[[C0_I32]] : i32 to i641994// CHECK: %[[EXTENT0:.*]] = llvm.sub %[[C0_5]], %[[C0_4]] : i641995// CHECK: %[[EXTENT1:.*]] = llvm.add %[[EXTENT0]], %[[C0_6]] : i641996// CHECK: %[[EXTENT2:.*]] = llvm.sdiv %[[EXTENT1]], %[[C0_6]] : i641997// CHECK: %[[EXTENT_CMP:.*]] = llvm.icmp "sgt" %[[EXTENT2]], %[[ZERO]] : i641998// CHECK: %[[EXTENT:.*]] = llvm.select %[[EXTENT_CMP]], %[[EXTENT2]], %[[ZERO]] : i1, i641999// CHECK: %[[BOX7:.*]] = llvm.insertvalue %[[ONE]], %[[BOX6]][7, 0, 0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2000// CHECK: %[[BOX8:.*]] = llvm.insertvalue %[[EXTENT]], %[[BOX7]][7, 0, 1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2001// CHECK: %[[C0_7:.*]] = llvm.sext %[[C0_I32]] : i32 to i642002// CHECK: %[[STRIDE:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0_7]] : i642003// CHECK: %[[BOX9:.*]] = llvm.insertvalue %[[STRIDE]], %[[BOX8]][7, 0, 2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2004// CHECK: %[[PREV_DIM:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0_1]] : i642005// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[ONE]], %[[C0_1]] : i642006// CHECK: %[[BASE_PTR:.*]] = llvm.getelementptr %[[ARG0]][%[[PTR_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322007// CHECK: %[[BOX10:.*]] = llvm.insertvalue %[[BASE_PTR]], %[[BOX9]][0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2008// CHECK: llvm.store %[[BOX10]], %[[ALLOCA]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>, !llvm.ptr2009 2010// Check adjustment of element scaling factor.2011 2012func.func @xembox1(%arg0: !fir.ref<!fir.array<?x!fir.char<1, 10>>>) {2013 %c0 = arith.constant 0 : i642014 %0 = fircg.ext_embox %arg0(%c0) origin %c0[%c0, %c0, %c0] : (!fir.ref<!fir.array<?x!fir.char<1, 10>>>, i64, i64, i64, i64, i64) -> !fir.box<!fir.array<?x!fir.char<1, 10>>>2015 return2016}2017 2018// CHECK-LABEL: llvm.func @xembox1(%{{.*}}: !llvm.ptr) {2019// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642020// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.mlir.constant(10 : i64) : i642021// CHECK: %{{.*}} = llvm.insertvalue %[[ELEM_LEN_I64]], %{{.*}}[1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2022// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C0]] : i642023 2024// Fortran realistic use case extracted from the following snippet:2025//2026// ```2027// subroutine sb(n,sh1,sh2)2028// integer::n,sh1,sh22029// double precision::arr(sh1:n,sh2:n)2030// call xb(arr(2:n,4:n))2031// end subroutine2032// ```2033 2034// N is the upperbound, sh1 and sh2 are the shifts or lowerbounds2035func.func @_QPsb(%N: index, %sh1: index, %sh2: index) {2036 %c4 = arith.constant 4 : index2037 %c1 = arith.constant 1 : index2038 %c2 = arith.constant 2 : index2039 // Calculate nelems in dim12040 %n1_tmp = arith.subi %N, %sh1 : index2041 %n1 = arith.addi %n1_tmp, %c1 : index2042 // Calculate nelems in dim22043 %n2_tmp = arith.subi %N, %sh2 : index2044 %n2 = arith.addi %n2_tmp, %c1 : index2045 %arr = fir.alloca !fir.array<?x?xf64>, %n1, %n2 {bindc_name = "arr", uniq_name = "_QFsbEarr"}2046 %box = fircg.ext_embox %arr(%n1, %n2) origin %sh1, %sh2[%c2, %N, %c1, %c4, %N, %c1] : (!fir.ref<!fir.array<?x?xf64>>, index, index, index, index, index, index, index, index, index, index) -> !fir.box<!fir.array<?x?xf64>>2047 fir.call @_QPxb(%box) : (!fir.box<!fir.array<?x?xf64>>) -> ()2048 return2049}2050func.func private @_QPxb(!fir.box<!fir.array<?x?xf64>>)2051 2052// CHECK-LABEL: llvm.func @_QPsb(2053// CHECK-SAME: %[[N:.*]]: i64, %[[SH1:.*]]: i64, %[[SH2:.*]]: i64) {2054// CHECK: %[[ALLOCA_SIZE:.*]] = llvm.mlir.constant(1 : i32) : i322055// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr2056// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>2057// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr2058// CHECK: %[[C4:.*]] = llvm.mlir.constant(4 : index) : i642059// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i642060// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i642061// CHECK: %[[N1_TMP:.*]] = llvm.sub %[[N]], %[[SH1]] : i642062// CHECK: %[[N1:.*]] = llvm.add %[[N1_TMP]], %[[C1]] : i642063// CHECK: %[[N2_TMP:.*]] = llvm.sub %[[N]], %[[SH2]] : i642064// CHECK: %[[N2:.*]] = llvm.add %[[N2_TMP]], %[[C1]] : i642065// CHECK: %[[C1_0:.*]] = llvm.mlir.constant(1 : i64) : i642066// CHECK: %[[ARR_SIZE_TMP1:.*]] = llvm.mul %[[N1]], %[[C1_0]] : i642067// CHECK: %[[ARR_SIZE:.*]] = llvm.mul %[[ARR_SIZE_TMP1]], %[[N2]] : i642068// GENERIC: %[[ARR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr"} : (i64) -> !llvm.ptr2069// AMDGPU: %[[AR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr"} : (i64) -> !llvm.ptr<5>2070// AMDGPU: %[[ARR:.*]] = llvm.addrspacecast %[[AR]] : !llvm.ptr<5> to !llvm.ptr2071// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(28 : i32) : i322072// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.mlir.constant(8 : i64) : i642073// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2074// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2075// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i322076// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2077// CHECK: %[[RANK:.*]] = llvm.mlir.constant(2 : i32) : i322078// CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i82079// CHECK: %[[BOX3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[BOX2]][3] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2080// CHECK: %[[TYPE_I8:.*]] = llvm.trunc %[[TYPE_CODE]] : i32 to i82081// CHECK: %[[BOX4:.*]] = llvm.insertvalue %[[TYPE_I8]], %[[BOX3]][4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2082// CHECK: %[[ATTR:.*]] = llvm.mlir.constant(0 : i32) : i322083// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[ATTR]] : i32 to i82084// CHECK: %[[BOX5:.*]] = llvm.insertvalue %[[ATTR_I8]], %[[BOX4]][5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2085// CHECK: %[[F18ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i322086// CHECK: %[[F18ADDENDUM_I8:.*]] = llvm.trunc %[[F18ADDENDUM]] : i32 to i82087// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2088// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i642089// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i642090// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C2]], %[[SH1]] : i642091// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[ONE]] : i642092// CHECK: %[[PTR_OFFSET:.*]] = llvm.add %[[DIM_OFFSET]], %[[ZERO]] : i642093// CHECK: %[[EXTENT0:.*]] = llvm.sub %[[ARG0]], %[[C2]] : i642094// CHECK: %[[EXTENT1:.*]] = llvm.add %[[EXTENT0]], %[[C1]] : i642095// CHECK: %[[EXTENT2:.*]] = llvm.sdiv %[[EXTENT1]], %[[C1]] : i642096// CHECK: %[[EXTENT_CMP:.*]] = llvm.icmp "sgt" %[[EXTENT2]], %[[ZERO]] : i642097// CHECK: %[[EXTENT:.*]] = llvm.select %[[EXTENT_CMP]], %[[EXTENT2]], %[[ZERO]] : i1, i642098// CHECK: %[[BOX7:.*]] = llvm.insertvalue %[[ONE]], %[[BOX6]][7, 0, 0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2099// CHECK: %[[BOX8:.*]] = llvm.insertvalue %[[EXTENT]], %[[BOX7]][7, 0, 1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2100// CHECK: %[[STRIDE:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[C1]] : i642101// CHECK: %[[BOX9:.*]] = llvm.insertvalue %[[STRIDE]], %[[BOX8]][7, 0, 2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2102// CHECK: %[[PREV_DIM:.*]] = llvm.mul %[[ELEM_LEN_I64]], %[[N1]] : i642103// CHECK: %[[PREV_PTROFF:.*]] = llvm.mul %[[ONE]], %[[N1]] : i642104// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C4]], %[[SH2]] : i642105// CHECK: %[[DIM_OFFSET:.*]] = llvm.mul %[[ADJUSTED_OFFSET]], %[[PREV_PTROFF]] : i642106// CHECK: %[[PTR_OFFSET0:.*]] = llvm.add %[[DIM_OFFSET]], %[[PTR_OFFSET]] : i642107// CHECK: %[[EXT_SUB:.*]] = llvm.sub %[[N]], %[[C4]] : i642108// CHECK: %[[EXT_ADD:.*]] = llvm.add %[[EXT_SUB]], %[[C1]] : i642109// CHECK: %[[EXT_SDIV:.*]] = llvm.sdiv %[[EXT_ADD]], %[[C1]] : i642110// CHECK: %[[EXT_ICMP:.*]] = llvm.icmp "sgt" %[[EXT_SDIV]], %[[ZERO]] : i642111// CHECK: %[[EXT_SELECT:.*]] = llvm.select %[[EXT_ICMP]], %[[EXT_SDIV]], %[[ZERO]] : i1, i642112// CHECK: %[[BOX10:.*]] = llvm.insertvalue %[[ONE]], %[[BOX9]][7, 1, 0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2113// CHECK: %[[BOX11:.*]] = llvm.insertvalue %[[EXT_SELECT]], %[[BOX10]][7, 1, 1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2114// CHECK: %[[STRIDE_MUL:.*]] = llvm.mul %[[PREV_DIM]], %[[C1]] : i642115// CHECK: %[[BOX12:.*]] = llvm.insertvalue %[[STRIDE_MUL]], %[[BOX11]][7, 1, 2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2116// CHECK: %[[BASE_PTR:.*]] = llvm.getelementptr %[[ARR]][%[[PTR_OFFSET0]]] : (!llvm.ptr, i64) -> !llvm.ptr, f642117// CHECK: %[[BOX13:.*]] = llvm.insertvalue %[[BASE_PTR]], %[[BOX12]][0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2118// CHECK: llvm.store %[[BOX13]], %[[ALLOCA]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>, !llvm.ptr2119 2120// Conversion with a subcomponent.2121 2122func.func @_QPtest_dt_slice() {2123 %c20 = arith.constant 20 : index2124 %c1_i64 = arith.constant 1 : i642125 %c10_i64 = arith.constant 10 : i642126 %c2_i64 = arith.constant 2 : i642127 %0 = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFtest_dt_sliceEv"}2128 %1 = fir.alloca !fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>> {bindc_name = "x", uniq_name = "_QFtest_dt_sliceEx"}2129 %2 = fir.field_index i, !fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>2130 %5 = fircg.ext_embox %1(%c20)[%c1_i64, %c10_i64, %c2_i64] path %2 : (!fir.ref<!fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>>, index, i64, i64, i64, !fir.field) -> !fir.box<!fir.array<?xi32>>2131 fir.call @_QPtest_dt_callee(%5) : (!fir.box<!fir.array<?xi32>>) -> ()2132 return2133}2134func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)2135 2136// CHECK-LABEL: llvm.func @_QPtest_dt_slice2137// CHECK: %[[ALLOCA_SIZE:.*]] = llvm.mlir.constant(1 : i32) : i322138// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr2139// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>2140// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr2141// CHECK: %[[ALLOCA_SIZE_X:.*]] = llvm.mlir.constant(1 : i64) : i642142// GENERIC: %[[X:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x"} : (i64) -> !llvm.ptr2143// AMDGPU: %[[AC:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x"} : (i64) -> !llvm.ptr<5>2144// AMDGPU: %[[X:.*]] = llvm.addrspacecast %[[AC]] : !llvm.ptr<5> to !llvm.ptr2145// CHECK: %[[ALLOCA_SIZE_V:.*]] = llvm.mlir.constant(1 : i64) : i642146// GENERIC: %[[V:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr2147// AMDGPU: %[[AB:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr<5>2148// AMDGPU: %[[V:.*]] = llvm.addrspacecast %[[AB]] : !llvm.ptr<5> to !llvm.ptr2149// CHECK: %[[C20:.*]] = llvm.mlir.constant(20 : index) : i642150// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642151// CHECK: %[[C10:.*]] = llvm.mlir.constant(10 : i64) : i642152// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : i64) : i642153// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i322154// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.mlir.constant(4 : i64) : i642155// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2156// CHECK: %[[BOX1:.*]] = llvm.insertvalue %[[ELEM_LEN_I64]], %[[BOX0]][1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2157// CHECK: %[[VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i322158// CHECK: %[[BOX2:.*]] = llvm.insertvalue %[[VERSION]], %[[BOX1]][2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2159// CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i322160// CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i82161// CHECK: %[[BOX3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[BOX2]][3] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2162// CHECK: %[[TYPE_CODE_I8:.*]] = llvm.trunc %[[TYPE_CODE]] : i32 to i82163// CHECK: %[[BOX4:.*]] = llvm.insertvalue %[[TYPE_CODE_I8]], %[[BOX3]][4] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2164// CHECK: %[[ATTR:.*]] = llvm.mlir.constant(0 : i32) : i322165// CHECK: %[[ATTR_I8:.*]] = llvm.trunc %[[ATTR]] : i32 to i82166// CHECK: %[[BOX5:.*]] = llvm.insertvalue %[[ATTR_I8]], %[[BOX4]][5] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2167// CHECK: %[[F18ADDENDUM:.*]] = llvm.mlir.constant(0 : i32) : i322168// CHECK: %[[F18ADDENDUM_I8:.*]] = llvm.trunc %[[F18ADDENDUM]] : i32 to i82169// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2170// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i642171// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i642172// CHECK: %[[PTRTOINT_DTYPE_SIZE:.*]] = llvm.mlir.constant(8 : i64) : i642173// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C1]], %[[ONE]] : i642174// CHECK: %[[EXT_SUB:.*]] = llvm.sub %[[C10]], %[[C1]] : i642175// CHECK: %[[EXT_ADD:.*]] = llvm.add %[[EXT_SUB]], %[[C2]] : i642176// CHECK: %[[EXT_SDIV:.*]] = llvm.sdiv %[[EXT_ADD]], %[[C2]] : i642177// CHECK: %[[EXT_ICMP:.*]] = llvm.icmp "sgt" %[[EXT_SDIV]], %[[ZERO]] : i642178// CHECK: %[[EXT_SELECT:.*]] = llvm.select %[[EXT_ICMP]], %[[EXT_SDIV]], %[[ZERO]] : i1, i642179// CHECK: %[[BOX7:.*]] = llvm.insertvalue %[[ONE]], %[[BOX6]][7, 0, 0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2180// CHECK: %[[BOX8:.*]] = llvm.insertvalue %[[EXT_SELECT]], %[[BOX7]][7, 0, 1] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2181// CHECK: %[[STRIDE_MUL:.*]] = llvm.mul %[[PTRTOINT_DTYPE_SIZE]], %[[C2]] : i642182// CHECK: %[[BOX9:.*]] = llvm.insertvalue %[[STRIDE_MUL]], %[[BOX8]][7, 0, 2] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2183// CHECK: %[[BASE_PTR:.*]] = llvm.getelementptr %[[X]][%[[ZERO]], %[[ADJUSTED_OFFSET]], 0] : (!llvm.ptr, i64, i64) -> !llvm.ptr, !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>>2184// CHECK: %[[BOX10:.*]] = llvm.insertvalue %[[BASE_PTR]], %[[BOX9]][0] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2185// CHECK: llvm.store %[[BOX10]], %[[ALLOCA]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>, !llvm.ptr2186// CHECK: llvm.call @_QPtest_dt_callee(%[[ALLOCA]]) : (!llvm.ptr) -> ()2187 2188// Conversion with a subcomponent that indexes a 2d array field in a derived type.2189 2190func.func @_QPtest_dt_slice2(%arg0: !fir.ref<!fir.array<2x!fir.type<_QPtest_dt_slice2Tt{a:!fir.array<2x3xi32>}>>>) {2191 %c0 = arith.constant 0 : index2192 %c1 = arith.constant 1 : index2193 %c2 = arith.constant 2 : index2194 %1 = fir.field_index a, !fir.type<_QPtest_dt_slice2Tt{a:!fir.array<2x3xi32>}>2195 %2 = fircg.ext_embox %arg0(%c2)[%c1, %c2, %c1] path %1, %c0, %c1 : (!fir.ref<!fir.array<2x!fir.type<_QPtest_dt_slice2Tt{a:!fir.array<2x3xi32>}>>>, index, index, index, index, !fir.field, index, index) -> !fir.box<!fir.array<2xi32>>2196 return2197}2198 2199// CHECK-LABEL: llvm.func @_QPtest_dt_slice2(2200// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) {2201// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i642202// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i642203// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i642204// CHECK: %[[C0_2:.*]] = llvm.mlir.constant(0 : i64) : i642205// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[C0_2]], {{.*}}, 0, %[[C1]], %[[C0]]] : (!llvm.ptr, i64, i64, i64, i64) -> !llvm.ptr, !llvm.array<2 x struct<"_QPtest_dt_slice2Tt", (array<3 x array<2 x i32>>)>>2206// CHECK: return2207// CHECK: }2208 2209// -----2210 2211// Test `fircg.ext_array_coor` conversion.2212 2213// Conversion with only shape and indice.2214 2215func.func @ext_array_coor0(%arg0: !fir.ref<!fir.array<?xi32>>) {2216 %c0 = arith.constant 0 : i642217 %1 = fircg.ext_array_coor %arg0(%c0) <%c0> : (!fir.ref<!fir.array<?xi32>>, i64, i64) -> !fir.ref<i32>2218 return2219}2220 2221// CHECK-LABEL: llvm.func @ext_array_coor0(2222// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr)2223// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642224// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642225// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i642226// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i642227// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i642228// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw> : i642229// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i642230// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322231 2232// Conversion with shift and slice.2233 2234func.func @ext_array_coor1(%arg0: !fir.ref<!fir.array<?xi32>>) {2235 %c0 = arith.constant 0 : i642236 %1 = fircg.ext_array_coor %arg0(%c0) origin %c0[%c0, %c0, %c0]<%c0> : (!fir.ref<!fir.array<?xi32>>, i64, i64, i64, i64, i64, i64) -> !fir.ref<i32>2237 return2238}2239 2240// CHECK-LABEL: llvm.func @ext_array_coor1(2241// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr)2242// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642243// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642244// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i642245// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C0]] overflow<nsw> : i642246// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C0]] overflow<nsw> : i642247// CHECK: %[[ADJ:.*]] = llvm.sub %[[C0]], %[[C0]] overflow<nsw> : i642248// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw> : i642249// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1]] overflow<nsw> : i642250// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw> : i642251// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322252 2253// Conversion for a dynamic length char.2254 2255func.func @ext_array_coor2(%arg0: !fir.ref<!fir.array<?x!fir.char<1,?>>>) {2256 %c0 = arith.constant 0 : i642257 %1 = fircg.ext_array_coor %arg0(%c0) <%c0> : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, i64, i64) -> !fir.ref<i32>2258 return2259}2260 2261// CHECK-LABEL: llvm.func @ext_array_coor2(2262// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr)2263// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642264// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642265// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i642266// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i642267// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i642268// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw> : i642269// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i642270// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82271 2272// Conversion for a `fir.box`.2273 2274func.func @ext_array_coor3(%arg0: !fir.box<!fir.array<?xi32>>) {2275 %c0 = arith.constant 0 : i642276 %1 = fircg.ext_array_coor %arg0(%c0) <%c0> : (!fir.box<!fir.array<?xi32>>, i64, i64) -> !fir.ref<i32>2277 return2278}2279 2280// CHECK-LABEL: llvm.func @ext_array_coor3(2281// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr) {2282// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642283// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642284// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i642285// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i642286// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i642287// CHECK: %[[GEPSTRIDE:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2288// CHECK: %[[LOADEDSTRIDE:.*]] = llvm.load %[[GEPSTRIDE]] : !llvm.ptr -> i642289// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] overflow<nsw> : i642290// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i642291// CHECK: %[[GEPADDR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2292// CHECK: %[[LOADEDADDR:.*]] = llvm.load %[[GEPADDR]] : !llvm.ptr -> !llvm.ptr2293// CHECK: %[[GEPADDROFFSET:.*]] = llvm.getelementptr %[[LOADEDADDR]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82294 2295// Conversion with non zero shift and slice.2296 2297func.func @ext_array_coor4(%arg0: !fir.ref<!fir.array<100xi32>>) {2298 %c0 = arith.constant 0 : i642299 %c10 = arith.constant 10 : i642300 %c20 = arith.constant 20 : i642301 %c1 = arith.constant 1 : i642302 %1 = fircg.ext_array_coor %arg0(%c0) origin %c0[%c10, %c20, %c1]<%c1> : (!fir.ref<!fir.array<100xi32>>, i64, i64, i64, i64, i64, i64) -> !fir.ref<i32>2303 return2304}2305 2306// CHECK-LABEL: llvm.func @ext_array_coor4(2307// CHECK: %[[ARG0:.*]]: !llvm.ptr) {2308// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i642309// CHECK: %[[C10:.*]] = llvm.mlir.constant(10 : i64) : i642310// CHECK: %[[C20:.*]] = llvm.mlir.constant(20 : i64) : i642311// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i642312// CHECK: %[[C1_1:.*]] = llvm.mlir.constant(1 : i64) : i642313// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i642314// CHECK: %[[IDX:.*]] = llvm.sub %[[C1]], %[[C0]] overflow<nsw> : i642315// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i642316// CHECK: %[[ADJ:.*]] = llvm.sub %[[C10]], %[[C0]] overflow<nsw> : i642317// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw> : i642318// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1_1]] overflow<nsw> : i642319// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw> : i642320// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322321 2322// Conversion with index type shape and slice2323 2324func.func @ext_array_coor5(%arg0: !fir.ref<!fir.array<?xi32>>, %idx1 : index, %idx2 : index, %idx3 : index, %idx4 : index, %idx5 : index) {2325 %1 = fircg.ext_array_coor %arg0(%idx1)[%idx2, %idx3, %idx4]<%idx5> : (!fir.ref<!fir.array<?xi32>>, index, index, index, index, index) -> !fir.ref<i32>2326 return2327}2328 2329// CHECK-LABEL: llvm.func @ext_array_coor5(2330// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: i64, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64, %[[VAL_5:.*]]: i64) {2331// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i642332// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(0 : i64) : i642333// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i642334// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw> : i642335// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i642336// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw> : i642337// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw> : i642338// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i642339// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw> : i642340// CHECK: %[[VAL_16:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_13]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322341// CHECK: }2342 2343// Conversion for 3-d array2344 2345func.func @ext_array_coor6(%arg0: !fir.ref<!fir.array<?x?x?xi32>>, %idx1 : index, %idx2 : index, %idx3 : index, %idx4 : index, %idx5 : index) {2346 %1 = fircg.ext_array_coor %arg0(%idx1, %idx1, %idx1)[%idx2, %idx3, %idx4, %idx2, %idx3, %idx4, %idx2, %idx3, %idx4]<%idx5, %idx5, %idx5> : (!fir.ref<!fir.array<?x?x?xi32>>, index, index, index, index, index, index, index, index, index, index, index, index, index, index, index) -> !fir.ref<i32>2347 return2348}2349 2350// CHECK-LABEL: llvm.func @ext_array_coor6(2351// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: i64, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64, %[[VAL_5:.*]]: i64) {2352// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i642353// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(0 : i64) : i642354// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i642355// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw> : i642356// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i642357// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw> : i642358// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw> : i642359// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i642360// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw> : i642361// CHECK: %[[VAL_15:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i642362// CHECK: %[[VAL_16:.*]] = llvm.mul %[[VAL_15]], %[[VAL_4]] overflow<nsw> : i642363// CHECK: %[[VAL_17:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i642364// CHECK: %[[VAL_18:.*]] = llvm.add %[[VAL_16]], %[[VAL_17]] overflow<nsw> : i642365// CHECK: %[[VAL_19:.*]] = llvm.mul %[[VAL_18]], %[[VAL_14]] overflow<nsw> : i642366// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_19]], %[[VAL_13]] overflow<nsw> : i642367// CHECK: %[[VAL_21:.*]] = llvm.mul %[[VAL_14]], %[[VAL_1]] overflow<nsw> : i642368// CHECK: %[[VAL_22:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i642369// CHECK: %[[VAL_23:.*]] = llvm.mul %[[VAL_22]], %[[VAL_4]] overflow<nsw> : i642370// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i642371// CHECK: %[[VAL_25:.*]] = llvm.add %[[VAL_23]], %[[VAL_24]] overflow<nsw> : i642372// CHECK: %[[VAL_26:.*]] = llvm.mul %[[VAL_25]], %[[VAL_21]] overflow<nsw> : i642373// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_26]], %[[VAL_20]] overflow<nsw> : i642374// CHECK: %[[VAL_28:.*]] = llvm.mul %[[VAL_21]], %[[VAL_1]] overflow<nsw> : i642375// CHECK: %[[VAL_30:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_27]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322376// CHECK: llvm.return2377// CHECK: }2378 2379// Conversion for derived type with type param2380 2381func.func @ext_array_coor_dt_slice(%arg0: !fir.ref<!fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>>, %idx1 : index, %idx2 : index, %idx3 : index, %idx4 : index, %idx5 : index) {2382 %1 = fir.field_index i, !fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>2383 %2 = fircg.ext_array_coor %arg0(%idx1)[%idx2, %idx3, %idx4] path %1 <%idx5>: (!fir.ref<!fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>>, index, index, index, index, !fir.field, index) -> !fir.ref<!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>2384 return2385}2386 2387// CHECK-LABEL: llvm.func @ext_array_coor_dt_slice(2388// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: i64, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64, %[[VAL_5:.*]]: i64) {2389// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i32) : i322390// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(1 : i64) : i642391// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(0 : i64) : i642392// CHECK: %[[VAL_9:.*]] = llvm.sub %[[VAL_5]], %[[VAL_7]] overflow<nsw> : i642393// CHECK: %[[VAL_10:.*]] = llvm.mul %[[VAL_9]], %[[VAL_4]] overflow<nsw> : i642394// CHECK: %[[VAL_11:.*]] = llvm.sub %[[VAL_2]], %[[VAL_7]] overflow<nsw> : i642395// CHECK: %[[VAL_12:.*]] = llvm.add %[[VAL_10]], %[[VAL_11]] overflow<nsw> : i642396// CHECK: %[[VAL_13:.*]] = llvm.mul %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i642397// CHECK: %[[VAL_14:.*]] = llvm.add %[[VAL_13]], %[[VAL_8]] overflow<nsw> : i642398// CHECK: %[[VAL_15:.*]] = llvm.mul %[[VAL_7]], %[[VAL_1]] overflow<nsw> : i642399// CHECK: %[[VAL_17:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_14]], 0] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_sliceTt", (i32, i32)>2400// CHECK: llvm.return2401// CHECK: }2402 2403// Conversion for derived type with an array field2404 2405func.func @ext_array_coor_dt_slice2(%arg0: !fir.ref<!fir.array<2x!fir.type<_QFtest_dt_slice2Tt{a:!fir.array<2x3xi32>}>>>, %idx1 : index, %idx2 : index, %idx3 : index, %idx4 : index, %idx5 : index, %idx6 : index, %idx7 : index) {2406 %1 = fir.field_index a, !fir.type<_QFtest_dt_sliceT2t{a:!fir.array<2x3xi32>}>2407 %2 = fircg.ext_array_coor %arg0(%idx1)[%idx2, %idx3, %idx4] path %1, %idx5, %idx6 <%idx7> : (!fir.ref<!fir.array<2x!fir.type<_QFtest_dt_slice2Tt{a:!fir.array<2x3xi32>}>>>, index, index, index, index, !fir.field, index, index, index) -> !fir.ref<i32>2408 return2409}2410 2411// CHECK-LABEL: llvm.func @ext_array_coor_dt_slice2(2412// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr, %[[IDX1:.*]]: i64, %[[IDX2:.*]]: i64, %[[IDX3:.*]]: i64, %[[IDX4:.*]]: i64, %[[IDX5:.*]]: i64, %[[IDX6:.*]]: i64, %[[IDX7:.*]]: i64) {2413// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%{{.*}}, 0, %[[IDX6]], %[[IDX5]]] : (!llvm.ptr, i64, i64, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_slice2Tt", (array<3 x array<2 x i32>>)>2414// CHECK: llvm.return2415// CHECK: }2416 2417// -----2418 2419// Check `fircg.ext_rebox` conversion to LLVM IR dialect2420 2421// Test applying slice on fir.box. Note that the slice is 1D where as the array is 2D.2422// subroutine foo(x)2423// real :: x(3:, 4:)2424// call bar(x(5, 6:80:3))2425// end subroutine2426 2427func.func private @bar1(!fir.box<!fir.array<?xf32>>)2428func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {2429 %c2 = arith.constant 2 : index2430 %c3 = arith.constant 3 : index2431 %c4 = arith.constant 4 : index2432 %c5 = arith.constant 5 : index2433 %c6 = arith.constant 6 : index2434 %c80 = arith.constant 80 : index2435 %0 = fir.undefined index2436 %3 = fircg.ext_rebox %arg0 origin %c3, %c4[%c5, %0, %0, %c6, %c80, %c3] : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, index, index, index, index) -> !fir.box<!fir.array<?xf32>>2437 fir.call @bar1(%3) : (!fir.box<!fir.array<?xf32>>) -> ()2438 return2439}2440//CHECK-LABEL: llvm.func @bar12441//CHECK-LABEL: llvm.func @test_rebox_12442//CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr2443//CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i32) : i322444//GENERIC: %[[RESULT_BOX_REF:.*]] = llvm.alloca %[[ONE_1]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr2445//AMDGPU: %[[AA:.*]] = llvm.alloca %[[ONE_1]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>2446//AMDGPU: %[[RESULT_BOX_REF:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr2447//CHECK: %[[THREE:.*]] = llvm.mlir.constant(3 : index) : i642448//CHECK: %[[FOUR:.*]] = llvm.mlir.constant(4 : index) : i642449//CHECK: %[[FIVE:.*]] = llvm.mlir.constant(5 : index) : i642450//CHECK: %[[SIX:.*]] = llvm.mlir.constant(6 : index) : i642451//CHECK: %[[EIGHTY:.*]] = llvm.mlir.constant(80 : index) : i642452//CHECK: %[[FLOAT_TYPE:.*]] = llvm.mlir.constant(27 : i32) : i322453//CHECK: %[[ELEM_SIZE_I64:.*]] = llvm.mlir.constant(4 : i64) : i642454//CHECK: %[[EXTRA_GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 6] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>2455//CHECK: %[[EXTRA:.*]] = llvm.load %[[EXTRA_GEP]] : !llvm.ptr -> i82456//CHECK: %[[RBOX:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2457//CHECK: %[[RBOX_TMP1:.*]] = llvm.insertvalue %[[ELEM_SIZE_I64]], %[[RBOX]][1] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2458//CHECK: %[[CFI_VERSION:.*]] = llvm.mlir.constant(20240719 : i32) : i322459//CHECK: %[[RBOX_TMP2:.*]] = llvm.insertvalue %[[CFI_VERSION]], %[[RBOX_TMP1]][2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2460//CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i322461//CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i82462//CHECK: %[[RBOX_TMP3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[RBOX_TMP2]][3] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2463//CHECK: %[[FLOAT_TYPE_I8:.*]] = llvm.trunc %[[FLOAT_TYPE]] : i32 to i82464//CHECK: %[[RBOX_TMP4:.*]] = llvm.insertvalue %[[FLOAT_TYPE_I8]], %[[RBOX_TMP3]][4] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2465//CHECK: %[[OTHER_ATTR:.*]] = llvm.mlir.constant(0 : i32) : i322466//CHECK: %[[OTHER_ATTR_I8:.*]] = llvm.trunc %[[OTHER_ATTR]] : i32 to i82467//CHECK: %[[RBOX_TMP5:.*]] = llvm.insertvalue %[[OTHER_ATTR_I8]], %[[RBOX_TMP4]][5] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2468//CHECK: %[[MASK:.*]] = llvm.mlir.constant(254 : ui8) : i82469//CHECK: %[[EXTRA_WITH_ADDENDUM_CORRECTION:.*]] = llvm.and %[[EXTRA]], %[[MASK]] : i82470//CHECK: %[[RBOX_TMP6:.*]] = llvm.insertvalue %[[EXTRA_WITH_ADDENDUM_CORRECTION]], %[[RBOX_TMP5]][6] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2471//CHECK: %[[DIM1_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>2472//CHECK: %[[DIM1_STRIDE:.*]] = llvm.load %[[DIM1_STRIDE_REF]] : !llvm.ptr -> i642473//CHECK: %[[DIM2_STRIDE_REF:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 1, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>2474//CHECK: %[[DIM2_STRIDE:.*]] = llvm.load %[[DIM2_STRIDE_REF]] : !llvm.ptr -> i642475//CHECK: %[[SOURCE_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>2476//CHECK: %[[SOURCE_ARRAY:.*]] = llvm.load %[[SOURCE_ARRAY_PTR]] : !llvm.ptr -> !llvm.ptr2477//CHECK: %[[ZERO_ELEMS:.*]] = llvm.mlir.constant(0 : i64) : i642478//CHECK: %[[DIM1_LB_DIFF:.*]] = llvm.sub %[[FIVE]], %[[THREE]] : i642479//CHECK: %[[DIM1_LB_OFFSET:.*]] = llvm.mul %[[DIM1_LB_DIFF]], %[[DIM1_STRIDE]] : i642480//CHECK: %[[RESULT_PTR_DIM1:.*]] = llvm.getelementptr %[[SOURCE_ARRAY]][%[[DIM1_LB_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82481//CHECK: %[[DIM2_LB_DIFF:.*]] = llvm.sub %[[SIX]], %[[FOUR]] : i642482//CHECK: %[[DIM2_LB_OFFSET:.*]] = llvm.mul %[[DIM2_LB_DIFF]], %[[DIM2_STRIDE]] : i642483//CHECK: %[[RESULT_PTR:.*]] = llvm.getelementptr %[[RESULT_PTR_DIM1]][%[[DIM2_LB_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82484//CHECK: %[[RESULT_UB_LB_DIFF:.*]] = llvm.sub %[[EIGHTY]], %[[SIX]] : i642485//CHECK: %[[RESULT_UB_LB_DIFF_PLUS_STRIDE:.*]] = llvm.add %[[RESULT_UB_LB_DIFF]], %[[THREE]] : i642486//CHECK: %[[RESULT_NELEMS_TMP:.*]] = llvm.sdiv %[[RESULT_UB_LB_DIFF_PLUS_STRIDE]], %[[THREE]] : i642487//CHECK: %[[RESULT_IF_NON_ZERO:.*]] = llvm.icmp "sgt" %[[RESULT_NELEMS_TMP]], %[[ZERO_ELEMS]] : i642488//CHECK: %[[RESULT_NELEMS:.*]] = llvm.select %[[RESULT_IF_NON_ZERO]], %[[RESULT_NELEMS_TMP]], %[[ZERO_ELEMS]] : i1, i642489//CHECK: %[[RESULT_STRIDE:.*]] = llvm.mul %[[THREE]], %[[DIM2_STRIDE]] : i642490//CHECK: %[[RESULT_LB:.*]] = llvm.mlir.constant(1 : i64) : i642491//CHECK: %[[RBOX_TMP7_1:.*]] = llvm.insertvalue %[[RESULT_LB]], %[[RBOX_TMP6]][7, 0, 0] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2492//CHECK: %[[RBOX_TMP7_2:.*]] = llvm.insertvalue %[[RESULT_NELEMS]], %[[RBOX_TMP7_1]][7, 0, 1] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2493//CHECK: %[[RBOX_TMP7_3:.*]] = llvm.insertvalue %[[RESULT_STRIDE]], %[[RBOX_TMP7_2]][7, 0, 2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2494//CHECK: %[[RESULT_BOX:.*]] = llvm.insertvalue %[[RESULT_PTR]], %[[RBOX_TMP7_3]][0] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2495//CHECK: llvm.store %[[RESULT_BOX]], %[[RESULT_BOX_REF]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>, !llvm.ptr2496//CHECK: llvm.call @bar1(%[[RESULT_BOX_REF]]) : (!llvm.ptr) -> ()2497 2498 2499// Test a rebox of an array section like x(3:60:9)%c(2:8) with both a triplet, a component and a substring where x is a fir.box.2500func.func private @bar(!fir.box<!fir.array<?x!fir.char<1,?>>>)2501func.func @foo(%arg0: !fir.box<!fir.array<?x!fir.type<t{i:i32,c:!fir.char<1,10>}>>>) {2502 %c3_i64 = arith.constant 3 : i642503 %c60_i64 = arith.constant 60 : i642504 %c9_i64 = arith.constant 9 : i642505 %c1_i64 = arith.constant 1 : i642506 %c7_i64 = arith.constant 7 : i642507 %0 = fir.field_index c, !fir.type<t{i:i32,c:!fir.char<1,10>}>2508 %1 = fircg.ext_rebox %arg0[%c3_i64, %c60_i64, %c9_i64] path %0 substr %c1_i64, %c7_i64 : (!fir.box<!fir.array<?x!fir.type<t{i:i32,c:!fir.char<1,10>}>>>, i64, i64, i64, !fir.field, i64, i64) -> !fir.box<!fir.array<?x!fir.char<1,?>>>2509 fir.call @bar(%1) : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> ()2510 return2511}2512 2513//CHECK: llvm.func @bar(!llvm.ptr) attributes {sym_visibility = "private"}2514//CHECK-LABEL: llvm.func @foo2515//CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr2516//CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i322517//GENERIC: %[[RESULT_BOX_REF:.*]] = llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr2518//AMDGPU: %[[AA:.*]] = llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>2519//AMDGPU: %[[RESULT_BOX_REF:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr2520//CHECK: %[[RESULT_LB:.*]] = llvm.mlir.constant(3 : i64) : i642521//CHECK: %[[RESULT_UB:.*]] = llvm.mlir.constant(60 : i64) : i642522//CHECK: %[[RESULT_STRIDE:.*]] = llvm.mlir.constant(9 : i64) : i642523//CHECK: %[[COMPONENT_OFFSET_1:.*]] = llvm.mlir.constant(1 : i64) : i642524//CHECK: %[[ELEM_COUNT:.*]] = llvm.mlir.constant(7 : i64) : i642525//CHECK: %[[TYPE_CHAR:.*]] = llvm.mlir.constant(40 : i32) : i322526//CHECK: %[[CHAR_SIZE:.*]] = llvm.mlir.constant(1 : i64) : i642527//CHECK: %[[ELEM_SIZE:.*]] = llvm.mul %[[CHAR_SIZE]], %[[ELEM_COUNT]]2528//CHECK: %[[EXTRA_GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 6] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>2529//CHECK: %[[EXTRA:.*]] = llvm.load %[[EXTRA_GEP]] : !llvm.ptr -> i82530//CHECK: %[[RBOX_TMP1:.*]] = llvm.insertvalue %[[ELEM_SIZE]], %{{.*}}[1] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2531//CHECK: %[[RBOX_TMP2:.*]] = llvm.insertvalue %{{.*}}, %[[RBOX_TMP1]][2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2532//CHECK: %[[RANK:.*]] = llvm.mlir.constant(1 : i32) : i322533//CHECK: %[[RANK_I8:.*]] = llvm.trunc %[[RANK]] : i32 to i82534//CHECK: %[[RBOX_TMP3:.*]] = llvm.insertvalue %[[RANK_I8]], %[[RBOX_TMP2]][3] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2535//CHECK: %[[TYPE_CHAR_I8:.*]] = llvm.trunc %[[TYPE_CHAR]] : i32 to i82536//CHECK: %[[RBOX_TMP4:.*]] = llvm.insertvalue %[[TYPE_CHAR_I8]], %[[RBOX_TMP3]][4] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2537//CHECK: %[[RBOX_TMP5:.*]] = llvm.insertvalue %{{.*}}, %[[RBOX_TMP4]][5] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2538//CHECK: %[[MASK:.*]] = llvm.mlir.constant(254 : ui8) : i82539//CHECK: %[[EXTRA_WITH_ADDENDUM_CORRECTION:.*]] = llvm.and %[[EXTRA]], %[[MASK]] : i82540//CHECK: %[[RBOX_TMP6:.*]] = llvm.insertvalue %[[EXTRA_WITH_ADDENDUM_CORRECTION]], %[[RBOX_TMP5]][6] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2541//CHECK: %[[SRC_STRIDE_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>2542//CHECK: %[[SRC_STRIDE:.*]] = llvm.load %[[SRC_STRIDE_PTR]] : !llvm.ptr -> i642543//CHECK: %[[SRC_ARRAY_PTR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>2544//CHECK: %[[SRC_ARRAY:.*]] = llvm.load %[[SRC_ARRAY_PTR]] : !llvm.ptr -> !llvm.ptr2545//CHECK: %[[ZERO_6:.*]] = llvm.mlir.constant(0 : i64) : i642546//CHECK: %[[COMPONENT:.*]] = llvm.getelementptr %[[SRC_ARRAY]][%[[ZERO_6]], 1, %[[COMPONENT_OFFSET_1]]] : (!llvm.ptr, i64, i64) -> !llvm.ptr, !llvm.struct<"t", (i32, array<10 x i8>)>2547//CHECK: %[[SRC_LB:.*]] = llvm.mlir.constant(1 : i64) : i642548//CHECK: %[[RESULT_TMP0:.*]] = llvm.sub %[[RESULT_LB]], %[[SRC_LB]] : i642549//CHECK: %[[RESULT_OFFSET_START:.*]] = llvm.mul %[[RESULT_TMP0]], %[[SRC_STRIDE]] : i642550//CHECK: %[[RESULT_PTR:.*]] = llvm.getelementptr %[[COMPONENT]][%[[RESULT_OFFSET_START]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82551//CHECK: %[[RESULT_TMP1:.*]] = llvm.sub %[[RESULT_UB]], %[[RESULT_LB]] : i642552//CHECK: %[[RESULT_TMP2:.*]] = llvm.add %[[RESULT_TMP1]], %[[RESULT_STRIDE]] : i642553//CHECK: %[[RESULT_TMP3:.*]] = llvm.sdiv %[[RESULT_TMP2]], %[[RESULT_STRIDE]] : i642554//CHECK: %[[RESULT_TMP_PRED:.*]] = llvm.icmp "sgt" %[[RESULT_TMP3]], %[[ZERO_6]] : i642555//CHECK: %[[RESULT_NELEMS:.*]] = llvm.select %[[RESULT_TMP_PRED]], %[[RESULT_TMP3]], %[[ZERO_6]] : i1, i642556//CHECK: %[[RESULT_TOTAL_STRIDE:.*]] = llvm.mul %[[RESULT_STRIDE]], %[[SRC_STRIDE]] : i642557//CHECK: %[[RESULT_LB:.*]] = llvm.mlir.constant(1 : i64) : i642558//CHECK: %[[RBOX_TMP7_1:.*]] = llvm.insertvalue %[[RESULT_LB]], %[[RBOX_TMP6]][7, 0, 0] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2559//CHECK: %[[RBOX_TMP7_2:.*]] = llvm.insertvalue %[[RESULT_NELEMS]], %[[RBOX_TMP7_1]][7, 0, 1] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2560//CHECK: %[[RBOX_TMP7_3:.*]] = llvm.insertvalue %[[RESULT_TOTAL_STRIDE]], %[[RBOX_TMP7_2]][7, 0, 2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2561//CHECK: %[[RESULT_BOX:.*]] = llvm.insertvalue %[[RESULT_PTR]], %[[RBOX_TMP7_3]][0] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>2562//CHECK: llvm.store %[[RESULT_BOX]], %[[RESULT_BOX_REF]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>, !llvm.ptr2563//CHECK: llvm.call @bar(%[[RESULT_BOX_REF]]) : (!llvm.ptr) -> ()2564//CHECK: llvm.return2565//CHECK: }2566 2567// -----2568 2569// Test `fir.coordinate_of` conversion (items inside `!fir.box`)2570 2571// 1. COMPLEX TYPE (`fir.complex` is a special case)2572// Complex type wrapped in `fir.ref`2573func.func @coordinate_ref_complex(%arg0: !fir.ref<complex<f128>>) {2574 %arg1 = llvm.mlir.constant(0 : i32) : i322575 %p = fir.coordinate_of %arg0, %arg1 : (!fir.ref<complex<f128>>, i32) -> !fir.ref<f32>2576 return2577}2578// CHECK-LABEL: llvm.func @coordinate_ref_complex2579// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr2580// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(f128, f128)>2581// CHECK-NEXT: llvm.return2582 2583// -----2584 2585// Complex type wrapped in `fir.box`2586func.func @coordinate_box_complex(%arg0: !fir.box<complex<f128>>) {2587 %arg1 = llvm.mlir.constant(0 : i32) : i322588 %p = fir.coordinate_of %arg0, %arg1 : (!fir.box<complex<f128>>, i32) -> !fir.ref<f32>2589 return2590}2591// CHECK-LABEL: llvm.func @coordinate_box_complex2592// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr2593// CHECK: %{{.*}} = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(f128, f128)>2594// CHECK-NEXT: llvm.return2595 2596// -----2597 2598// Test `fir.coordinate_of` conversion (items inside `!fir.box`)2599 2600// 2. BOX TYPE (objects wrapped in `fir.box`)2601// Derived type - basic case (1 index)2602func.func @coordinate_box_derived_1(%arg0: !fir.box<!fir.type<derived_1{field_1:i32, field_2:i32}>>) {2603 %q = fir.coordinate_of %arg0, field_2 : (!fir.box<!fir.type<derived_1{field_1:i32, field_2:i32}>>) -> !fir.ref<i32>2604 return2605}2606// CHECK-LABEL: llvm.func @coordinate_box_derived_12607// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr)2608// CHECK: %[[DERIVED_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i64>)>2609// CHECK: %[[DERIVED_VAL:.*]] = llvm.load %[[DERIVED_ADDR]] : !llvm.ptr -> !llvm.ptr2610// CHECK: %[[SUBOBJECT_ADDR:.*]] = llvm.getelementptr %[[DERIVED_VAL]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"derived_1", (i32, i32)>2611// CHECK-NEXT: llvm.return2612 2613// Derived type - basic case (2 indices)2614func.func @coordinate_box_derived_2(%arg0: !fir.box<!fir.type<derived_2{field_1:!fir.type<another_derived{inner1:i32, inner2:f32}>, field_2:i32}>>) {2615 %q = fir.coordinate_of %arg0, field_1, inner2 : (!fir.box<!fir.type<derived_2{field_1:!fir.type<another_derived{inner1:i32, inner2:f32}>, field_2:i32}>>) -> !fir.ref<i32>2616 return2617}2618 2619// CHECK-LABEL: llvm.func @coordinate_box_derived_22620// CHECK-SAME: (%[[BOX:.*]]: !llvm.ptr)2621// CHECK: %[[DERIVED_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}32, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i64>)>2622// CHECK-NEXT: %[[DERIVED_VAL:.*]] = llvm.load %[[DERIVED_ADDR]] : !llvm.ptr -> !llvm.ptr2623// CHECK-NEXT: %[[ANOTHER_DERIVED_ADDR:.*]] = llvm.getelementptr %[[DERIVED_VAL]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"derived_2", (struct<"another_derived", (i32, f32)>, i32)>2624// CHECK-NEXT: %[[SUBOBJECT_ADDR:.*]] = llvm.getelementptr %[[ANOTHER_DERIVED_ADDR]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"another_derived", (i32, f32)>2625// CHECK-NEXT: llvm.return2626 2627// TODO: Derived type - special case with `fir.len_param_index`2628 2629// -----2630 2631// Test `fir.coordinate_of` conversion (items inside `!fir.box`)2632 2633// 3. BOX TYPE - `fir.array` wrapped in `fir.box`2634// `fir.array` inside a `fir.box` (1d)2635func.func @coordinate_box_array_1d(%arg0: !fir.box<!fir.array<10 x f32>>, %arg1: index) {2636 %p = fir.coordinate_of %arg0, %arg1 : (!fir.box<!fir.array<10 x f32>>, index) -> !fir.ref<f32>2637 return2638}2639// CHECK-LABEL: llvm.func @coordinate_box_array_1d2640// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr2641// CHECK-SAME: %[[COORDINATE:.*]]: i642642// There's only one box here. Its index is `0`. Generate it.2643// CHECK: %[[ARRAY_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2644// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr -> !llvm.ptr2645// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i642646// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)2647// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2648// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr -> i642649// CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] overflow<nsw> : i642650// CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] overflow<nsw> : i642651// CHECK-NEXT: %[[SUBOBJECT_ADDR:.*]] = llvm.getelementptr %[[ARRAY_OBJECT]][%[[SUBOJECT_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82652// CHECK-NEXT: llvm.return2653 2654// `fir.array` inside a `fir.box` (1d) - dynamic size2655func.func @coordinate_of_box_dynamic_array_1d(%arg0: !fir.box<!fir.array<? x f32>>, %arg1: index) {2656 %p = fir.coordinate_of %arg0, %arg1 : (!fir.box<!fir.array<? x f32>>, index) -> !fir.ref<f32>2657 return2658}2659// CHECK-LABEL: llvm.func @coordinate_of_box_dynamic_array_1d2660// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr2661// CHECK-SAME: %[[COORDINATE:.*]]: i642662// CHECK-NEXT: %[[ARRAY_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2663// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr -> !llvm.ptr2664// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i642665// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)2666// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>2667// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr -> i642668// CHECK-NEXT: %[[BYTE_OFFSET:.*]] = llvm.mul %[[COORDINATE]], %[[DIM_1_MEM_STRIDE_VAL]] overflow<nsw> : i642669// CHECK-NEXT: %[[SUBOJECT_OFFSET:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] overflow<nsw> : i642670// CHECK-NEXT: %[[SUBOBJECT_ADDR:.*]] = llvm.getelementptr %[[ARRAY_OBJECT]][%[[SUBOJECT_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82671// CHECK-NEXT: llvm.return2672 2673// -----2674 2675// `fir.array` inside a `fir.box` (2d)2676func.func @coordinate_box_array_2d(%arg0: !fir.box<!fir.array<10 x 10 x f32>>, %arg1: index, %arg2: index) {2677 %p = fir.coordinate_of %arg0, %arg1, %arg2 : (!fir.box<!fir.array<10 x 10 x f32>>, index, index) -> !fir.ref<f32>2678 return2679}2680// CHECK-LABEL: llvm.func @coordinate_box_array_2d2681// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr2682// CHECK-SAME: %[[COORDINATE_1:.*]]: i64, %[[COORDINATE_2:.*]]: i64)2683// CHECK-NEXT: %[[ARRAY_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2684// CHECK-NEXT: %[[ARRAY_OBJECT:.*]] = llvm.load %[[ARRAY_ADDR]] : !llvm.ptr -> !llvm.ptr2685// CHECK-NEXT: %[[OFFSET_INIT:.*]] = llvm.mlir.constant(0 : i64) : i642686// Index of the 1st CFI_dim_t object (corresonds the the 1st dimension)2687// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2688// CHECK-NEXT: %[[DIM_1_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_1_MEM_STRIDE_ADDR]] : !llvm.ptr -> i642689// CHECK-NEXT: %[[BYTE_OFFSET_1:.*]] = llvm.mul %[[COORDINATE_1]], %[[DIM_1_MEM_STRIDE_VAL]] overflow<nsw> : i642690// CHECK-NEXT: %[[SUBOBJECT_OFFSET_1:.*]] = llvm.add %[[BYTE_OFFSET]], %[[OFFSET_INIT]] overflow<nsw> : i642691// Index of the 1st CFI_dim_t object (corresonds the the 2nd dimension)2692// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_ADDR:.*]] = llvm.getelementptr %[[BOX]][0, 7, 1, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>2693// CHECK-NEXT: %[[DIM_2_MEM_STRIDE_VAL:.*]] = llvm.load %[[DIM_2_MEM_STRIDE_ADDR]] : !llvm.ptr -> i642694// CHECK-NEXT: %[[BYTE_OFFSET_2:.*]] = llvm.mul %[[COORDINATE_2]], %[[DIM_2_MEM_STRIDE_VAL]] overflow<nsw> : i642695// CHECK-NEXT: %[[SUBOBJECT_OFFSET_2:.*]] = llvm.add %[[BYTE_OFFSET_2]], %[[SUBOBJECT_OFFSET_1]] overflow<nsw> : i642696// CHECK-NEXT: %[[SUBOBJECT_ADDR:.*]] = llvm.getelementptr %[[ARRAY_OBJECT]][%[[SUBOBJECT_OFFSET_2]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82697// CHECK-NEXT: llvm.return2698 2699// -----2700 2701// Test `fir.coordinate_of` conversion (items inside `!fir.box`)2702 2703// 4. BOX TYPE - `fir.derived` inside `fir.array`2704func.func @coordinate_box_derived_inside_array(%arg0: !fir.box<!fir.array<10 x !fir.type<derived_3{field_1:f32, field_2:f32}>>>, %arg1 : index) {2705 %q = fir.coordinate_of %arg0, %arg1, field_2 : (!fir.box<!fir.array<10 x !fir.type<derived_3{field_1:f32, field_2:f32}>>>, index) -> !fir.ref<f32>2706 return2707}2708// CHECK-LABEL: llvm.func @coordinate_box_derived_inside_array(2709// CHECK-SAME: %[[BOX:.*]]: !llvm.ptr,2710// CHECK-SAME: %[[COORDINATE_1:.*]]: i64) {2711// CHECK: %[[VAL_6:.*]] = llvm.getelementptr %[[BOX]]{{\[}}0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>2712// CHECK: %[[ARRAY:.*]] = llvm.load %[[VAL_6]] : !llvm.ptr -> !llvm.ptr2713// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(0 : i64) : i642714// CHECK: %[[VAL_13:.*]] = llvm.getelementptr %[[BOX]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>2715// CHECK: %[[VAL_14:.*]] = llvm.load %[[VAL_13]] : !llvm.ptr -> i642716// CHECK: %[[VAL_15:.*]] = llvm.mul %[[COORDINATE_1]], %[[VAL_14]] overflow<nsw> : i642717// CHECK: %[[OFFSET:.*]] = llvm.add %[[VAL_15]], %[[VAL_8]] overflow<nsw> : i642718// CHECK: %[[DERIVED:.*]] = llvm.getelementptr %[[ARRAY]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i82719// CHECK: %[[VAL_20:.*]] = llvm.getelementptr %[[DERIVED]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"derived_3", (f32, f32)>2720// CHECK: llvm.return2721 2722// -----2723 2724// Test `fir.coordinate_of` conversion (items inside `!fir.ref`)2725 2726// 5.1. `fir.array`2727func.func @coordinate_array_unknown_size_1d(%arg0: !fir.ref<!fir.array<? x i32>>, %arg1 : index) {2728 %q = fir.coordinate_of %arg0, %arg1 : (!fir.ref<!fir.array<? x i32>>, index) -> !fir.ref<i32>2729 return2730}2731// CHECK-LABEL: llvm.func @coordinate_array_unknown_size_1d(2732// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr,2733// CHECK-SAME: %[[VAL_1:.*]]: i64) {2734// CHECK: %[[VAL_2:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}%[[VAL_1]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322735// CHECK: llvm.return2736// CHECK: }2737 2738// -----2739 2740func.func @coordinate_array_known_size_1d(%arg0: !fir.ref<!fir.array<10 x i32>>, %arg1 : index) {2741 %q = fir.coordinate_of %arg0, %arg1 : (!fir.ref<!fir.array<10 x i32>>, index) -> !fir.ref<i32>2742 return2743}2744// CHECK-LABEL: llvm.func @coordinate_array_known_size_1d(2745// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr,2746// CHECK-SAME: %[[VAL_1:.*]]: i64) {2747// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, %[[VAL_1]]] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<10 x i32>2748// CHECK: llvm.return2749// CHECK: }2750 2751// -----2752 2753func.func @coordinate_array_known_size_2d_get_i32(%arg0: !fir.ref<!fir.array<10 x 10 x i32>>, %arg1 : index, %arg2 : index) {2754 %q = fir.coordinate_of %arg0, %arg1, %arg2 : (!fir.ref<!fir.array<10 x 10 x i32>>, index, index) -> !fir.ref<i32>2755 return2756}2757// CHECK-LABEL: llvm.func @coordinate_array_known_size_2d_get_i32(2758// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr,2759// CHECK-SAME: %[[VAL_1:.*]]: i64,2760// CHECK-SAME: %[[VAL_2:.*]]: i64) {2761// CHECK: %[[VAL_4:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, %[[VAL_2]], %[[VAL_1]]] : (!llvm.ptr, i64, i64) -> !llvm.ptr, !llvm.array<10 x array<10 x i32>2762// CHECK: llvm.return2763// CHECK: }2764 2765// -----2766 2767func.func @coordinate_array_known_size_2d_get_array(%arg0: !fir.ref<!fir.array<10 x 10 x i32>>, %arg1 : index) {2768 %q = fir.coordinate_of %arg0, %arg1 : (!fir.ref<!fir.array<10 x 10 x i32>>, index) -> !fir.ref<!fir.array<10 x i32>>2769 return2770}2771// CHECK-LABEL: llvm.func @coordinate_array_known_size_2d_get_array(2772// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr,2773// CHECK-SAME: %[[VAL_1:.*]]: i64) {2774// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]][0, %[[VAL_1]]] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<10 x array<10 x i32>>2775// CHECK: llvm.return2776// CHECK: }2777 2778// -----2779 2780// 5.2. `fir.derived`2781func.func @coordinate_ref_derived(%arg0: !fir.ref<!fir.type<dervied_4{field_1:i32, field_2:i32}>>) {2782 %q = fir.coordinate_of %arg0, field_2 : (!fir.ref<!fir.type<dervied_4{field_1:i32, field_2:i32}>>) -> !fir.ref<i32>2783 return2784}2785// CHECK-LABEL: llvm.func @coordinate_ref_derived(2786// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr) {2787// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"dervied_4", (i32, i32)>2788// CHECK: llvm.return2789// CHECK: }2790 2791// -----2792 2793func.func @coordinate_ref_derived_nested(%arg0: !fir.ref<!fir.type<derived_5{field_1:!fir.type<nested_derived{inner1:i32, inner2:f32}>, field_2:i32}>>) {2794 %q = fir.coordinate_of %arg0, field_1, inner2 : (!fir.ref<!fir.type<derived_5{field_1:!fir.type<nested_derived{inner1:i32, inner2:f32}>, field_2:i32}>>) -> !fir.ref<i32>2795 return2796}2797// CHECK-LABEL: llvm.func @coordinate_ref_derived_nested(2798// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr) {2799// CHECK: %[[VAL_4:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, 0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"derived_5", (struct<"nested_derived", (i32, f32)>, i32)>2800// CHECK: llvm.return2801// CHECK: }2802 2803// -----2804 2805// 5.3 `fir.char`2806func.func @test_coordinate_of_char(%arr : !fir.ref<!fir.char<2, 10>>) {2807 %1 = arith.constant 10 : i322808 %2 = fir.coordinate_of %arr, %1 : (!fir.ref<!fir.char<2, 10>>, i32) -> !fir.ref<!fir.char<2>>2809 return2810}2811// CHECK-LABEL: llvm.func @test_coordinate_of_char(2812// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr) {2813// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i322814// CHECK: %[[VAL_2:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, %[[VAL_1]]] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.array<10 x i16>2815// CHECK: llvm.return2816// CHECK: }2817 2818// -----2819 2820// 5.4 `mlir.tuple`2821func.func @test_coordinate_of_tuple(%tup : !fir.ref<tuple<!fir.ref<i32>>>) {2822 %1 = arith.constant 0 : i322823 %2 = fir.coordinate_of %tup, %1 : (!fir.ref<tuple<!fir.ref<i32>>>, i32) -> !fir.ref<i32>2824 return2825}2826// CHECK-LABEL: llvm.func @test_coordinate_of_tuple(2827// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr) {2828// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr)>2829// CHECK: llvm.return2830// CHECK: }2831 2832// -----2833 2834// Test `fir.coordinate_of` conversion - items inside `!fir.ptr`. This should2835// be almost identical to `!fir.ref` (i.e. it's the same code path in the code2836// gen). Instead of duplicating the tests, only one for sanity-checking is added.2837 2838// 6.1. `fir.array`2839func.func @coordinate_array_unknown_size_1d(%arg0: !fir.ptr<!fir.array<? x i32>>, %arg1 : index) {2840 %q = fir.coordinate_of %arg0, %arg1 : (!fir.ptr<!fir.array<? x i32>>, index) -> !fir.ref<i32>2841 return2842}2843// CHECK-LABEL: llvm.func @coordinate_array_unknown_size_1d(2844// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr,2845// CHECK-SAME: %[[VAL_1:.*]]: i64) {2846// CHECK: %[[VAL_2:.*]] = llvm.getelementptr %[[VAL_0]]{{\[}}%[[VAL_1]]] : (!llvm.ptr, i64) -> !llvm.ptr, i322847// CHECK: llvm.return2848// CHECK: }2849 2850// -----2851 2852fir.global common @c_(dense<0> : vector<4294967296xi8>) : !fir.array<4294967296xi8>2853 2854// CHECK: llvm.mlir.global common @c_(dense<0> : vector<4294967296xi8>) 2855// GENERIC-SAME: {addr_space = 0 : i32}2856// AMDGPU-SAME: {addr_space = 1 : i32}2857// CHECK-SAME: !llvm.array<4294967296 x i8>2858 2859// -----2860 2861gpu.module @cuda_device_mod {2862 gpu.func @test_alloc_and_freemem_one() {2863 %z0 = fir.allocmem i322864 fir.freemem %z0 : !fir.heap<i32>2865 gpu.return2866 }2867}2868 2869// CHECK: gpu.module @cuda_device_mod {2870// CHECK: llvm.func @free(!llvm.ptr)2871// CHECK: llvm.func @malloc(i64) -> !llvm.ptr2872// CHECK: llvm.call @malloc2873// CHECK: lvm.call @free2874 2875// -----2876 2877func.func private @somefunc(i32, !fir.ref<i64>)2878 2879// CHECK-LABEL: @test_call_arg_attrs_direct2880func.func @test_call_arg_attrs_direct(%arg0: i32, %arg1: !fir.ref<i64>) {2881 // CHECK: llvm.call @somefunc(%{{.*}}, %{{.*}}) : (i32, !llvm.ptr {llvm.byval = i64}) -> ()2882 fir.call @somefunc(%arg0, %arg1) : (i32, !fir.ref<i64> {llvm.byval = i64}) -> ()2883 return2884}2885 2886// -----2887 2888// CHECK-LABEL: @test_call_arg_attrs_indirect2889func.func @test_call_arg_attrs_indirect(%arg0: i16, %arg1: (i16)-> i16) -> i16 {2890 // CHECK: llvm.call %arg1(%{{.*}}) : !llvm.ptr, (i16 {llvm.noundef, llvm.signext}) -> (i16 {llvm.signext})2891 %0 = fir.call %arg1(%arg0) : (i16 {llvm.noundef, llvm.signext}) -> (i16 {llvm.signext})2892 return %0 : i162893}2894 2895// -----2896 2897// CHECK-LABEL: @test_byval2898func.func @test_byval(%arg0: (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>>, f64) -> (), %arg1: !fir.ref<!fir.type<t{a:!fir.array<5xf64>}>>, %arg2: f64) {2899 // llvm.call %{{.*}}(%{{.*}}, %{{.*}}) : !llvm.ptr, (!llvm.ptr {llvm.byval = !llvm.struct<"t", (array<5 x f64>)>}, f64) -> ()2900 fir.call %arg0(%arg1, %arg2) : (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>> {llvm.byval = !fir.type<t{a:!fir.array<5xf64>}>}, f64) -> ()2901 return2902}2903 2904// -----2905 2906// CHECK-LABEL: @test_sret2907func.func @test_sret(%arg0: (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>>, f64) -> (), %arg1: !fir.ref<!fir.type<t{a:!fir.array<5xf64>}>>, %arg2: f64) {2908 // llvm.call %{{.*}}(%{{.*}}, %{{.*}}) : !llvm.ptr, (!llvm.ptr {llvm.sret = !llvm.struct<"t", (array<5 x f64>)>}, f64) -> ()2909 fir.call %arg0(%arg1, %arg2) : (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>> {llvm.sret = !fir.type<t{a:!fir.array<5xf64>}>}, f64) -> ()2910 return2911}2912 2913// -----2914 2915func.func @select_with_cast(%arg1 : i8, %arg2 : i16, %arg3: i64, %arg4: index) -> () {2916 fir.select %arg1 : i8 [ 1, ^bb1, unit, ^bb1 ]2917 ^bb1:2918 fir.select %arg2 : i16 [ 1, ^bb2, unit, ^bb2 ]2919 ^bb2:2920 fir.select %arg3 : i64 [ 1, ^bb3, unit, ^bb3 ]2921 ^bb3:2922 fir.select %arg4 : index [ 1, ^bb4, unit, ^bb4 ]2923 ^bb4:2924 fir.select %arg3 : i64 [ 4294967296, ^bb5, unit, ^bb5 ]2925 ^bb5:2926 return2927}2928// CHECK-LABEL: llvm.func @select_with_cast(2929// CHECK-SAME: %[[ARG0:.*]]: i8,2930// CHECK-SAME: %[[ARG1:.*]]: i16,2931// CHECK-SAME: %[[ARG2:.*]]: i64,2932// CHECK-SAME: %[[ARG3:.*]]: i64) {2933// CHECK: %[[VAL_0:.*]] = llvm.sext %[[ARG0]] : i8 to i642934// CHECK: llvm.switch %[[VAL_0]] : i64, ^bb1 [2935// CHECK: 1: ^bb12936// CHECK: ]2937// CHECK: ^bb1:2938// CHECK: %[[VAL_1:.*]] = llvm.sext %[[ARG1]] : i16 to i642939// CHECK: llvm.switch %[[VAL_1]] : i64, ^bb2 [2940// CHECK: 1: ^bb22941// CHECK: ]2942// CHECK: ^bb2:2943// CHECK: llvm.switch %[[ARG2]] : i64, ^bb3 [2944// CHECK: 1: ^bb32945// CHECK: ]2946// CHECK: ^bb3:2947// CHECK: llvm.switch %[[ARG3]] : i64, ^bb4 [2948// CHECK: 1: ^bb42949// CHECK: ]2950// CHECK: ^bb4:2951// CHECK: llvm.switch %[[ARG2]] : i64, ^bb5 [2952// CHECK: 4294967296: ^bb52953// CHECK: ]2954// CHECK: ^bb5:2955// CHECK: llvm.return2956// CHECK: }2957