// RUN: fir-opt %s | tco | FileCheck %s // tests on coordinate_of op // CHECK-LABEL: @foo1 func.func @foo1(%i : i32, %j : i32, %k : i32) -> !fir.ref { %1 = fir.alloca !fir.array<10 x 20 x 30 x f32> // CHECK: %[[alloca:.*]] = alloca [30 x [20 x [10 x float]]] %2 = fir.convert %1 : (!fir.ref>) -> !fir.ref> // CHECK: getelementptr [20 x [10 x float]], ptr %[[alloca]] %3 = fir.coordinate_of %2, %i, %j, %k : (!fir.ref>, i32, i32, i32) -> !fir.ref return %3 : !fir.ref } // CHECK-LABEL: @foo2 func.func @foo2(%i : i32, %j : i32, %k : i32) -> !fir.ref { %1 = fir.alloca !fir.array<10 x 20 x 30 x f32> // CHECK: %[[alloca:.*]] = alloca [30 x [20 x [10 x float]]] %2 = fir.convert %1 : (!fir.ref>) -> !fir.ref> // CHECK: getelementptr float, ptr %[[alloca]] %3 = fir.coordinate_of %2, %i : (!fir.ref>, i32) -> !fir.ref return %3 : !fir.ref } // CHECK-LABEL: @foo3 func.func @foo3(%box : !fir.box>, %i : i32) -> i32 { // CHECK: %[[cvt:.*]] = sext i32 % %ii = fir.convert %i : (i32) -> index // CHECK: %[[gep0:.*]] = getelementptr { ptr // CHECK: %[[boxptr:.*]] = load ptr, ptr %[[gep0]] // CHECK: %[[gep1:.*]] = getelementptr { ptr, i64, {{.*}} i32 7 // CHECK: %[[stride:.*]] = load i64, ptr %[[gep1]] // CHECK: %[[dimoffset:.*]] = mul nsw i64 %[[cvt]], %[[stride]] // CHECK: %[[offset:.*]] = add nsw i64 %[[dimoffset]], 0 // CHECK: %[[gep2:.*]] = getelementptr i8, ptr %[[boxptr]], i64 %[[offset]] %1 = fir.coordinate_of %box, %ii : (!fir.box>, index) -> !fir.ref // CHECK: load i32, ptr %[[gep2]] %rv = fir.load %1 : !fir.ref return %rv : i32 } // CHECK-LABEL: @foo4 func.func @foo4(%a : !fir.ptr>, %i : i32, %j : i64, %k : index) -> i32 { // CHECK: getelementptr [25 x [15 x [5 x %1 = fir.coordinate_of %a, %k : (!fir.ptr>, index) -> !fir.ref> // CHECK: getelementptr [15 x [5 x %2 = fir.coordinate_of %1, %j : (!fir.ref>, i64) -> !fir.ref> // CHECK: %[[ref:.*]] = getelementptr [5 x %3 = fir.coordinate_of %2, %i : (!fir.ref>, i32) -> !fir.ref // CHECK: load i32, ptr %[[ref]] %4 = fir.load %3 : !fir.ref return %4 : i32 } // CHECK-LABEL: @foo5 func.func @foo5(%box : !fir.box>>, %i : index) -> i32 { // similar to foo3 test. Just check that the ptr type is not disturbing codegen. %1 = fir.coordinate_of %box, %i : (!fir.box>>, index) -> !fir.ref // CHECK: load i32, ptr %{{.*}} %rv = fir.load %1 : !fir.ref return %rv : i32 } // CHECK-LABEL: @foo6 // CHECK-SAME: (ptr %[[box:.*]], i64 %{{.*}}, ptr %{{.*}}) func.func @foo6(%box : !fir.box>>>, %i : i64 , %res : !fir.ref>) { // CHECK: %[[addr_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 0 // CHECK: %[[addr:.*]] = load ptr, ptr %[[addr_gep]] // CHECK: %[[stride_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 7, i32 0, i32 2 // CHECK: %[[stride:.*]] = load i64, ptr %[[stride_gep]] // CHECK: %[[mul:.*]] = mul nsw i64 %{{.*}}, %[[stride]] // CHECK: %[[offset:.*]] = add nsw i64 %[[mul]], 0 // CHECK: %[[gep:.*]] = getelementptr i8, ptr %[[addr]], i64 %[[offset]] %coor = fir.coordinate_of %box, %i : (!fir.box>>>, i64) -> !fir.ref> // CHECK: load [1 x i8], ptr %[[gep]] %load = fir.load %coor : !fir.ref> fir.store %load to %res : !fir.ref> return }