Skip to content

Commit 4840e75

Browse files
clementvalvdonaldsonjeanPerierpsteinfeldAlexisPerry
committed
[flang] Lower shift intrinsics
This patch adds lowering for shift intrinsics: - `ishft` - `eoshift` - `ishftc` - `cshift` This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D121808 Co-authored-by: V Donaldson <[email protected]> Co-authored-by: Jean Perier <[email protected]> Co-authored-by: Peter Steinfeld <[email protected]> Co-authored-by: AlexisPerry <[email protected]>
1 parent 9aeb7f0 commit 4840e75

File tree

4 files changed

+460
-3
lines changed

4 files changed

+460
-3
lines changed

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 204 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "flang/Optimizer/Builder/Runtime/Numeric.h"
3030
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
3131
#include "flang/Optimizer/Builder/Runtime/Reduction.h"
32+
#include "flang/Optimizer/Builder/Runtime/Transformational.h"
3233
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
3334
#include "flang/Optimizer/Support/FatalError.h"
3435
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
@@ -441,21 +442,25 @@ struct IntrinsicLibrary {
441442
llvm::ArrayRef<fir::ExtendedValue>);
442443
fir::ExtendedValue genChar(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
443444
fir::ExtendedValue genCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
444-
mlir::Value genDim(mlir::Type, llvm::ArrayRef<mlir::Value>);
445-
fir::ExtendedValue genDotProduct(mlir::Type,
446-
llvm::ArrayRef<fir::ExtendedValue>);
447445
template <mlir::arith::CmpIPredicate pred>
448446
fir::ExtendedValue genCharacterCompare(mlir::Type,
449447
llvm::ArrayRef<fir::ExtendedValue>);
450448
void genCpuTime(llvm::ArrayRef<fir::ExtendedValue>);
449+
fir::ExtendedValue genCshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
451450
void genDateAndTime(llvm::ArrayRef<fir::ExtendedValue>);
451+
mlir::Value genDim(mlir::Type, llvm::ArrayRef<mlir::Value>);
452+
fir::ExtendedValue genDotProduct(mlir::Type,
453+
llvm::ArrayRef<fir::ExtendedValue>);
454+
fir::ExtendedValue genEoshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
452455
template <Extremum, ExtremumBehavior>
453456
mlir::Value genExtremum(mlir::Type, llvm::ArrayRef<mlir::Value>);
454457
/// Lowering for the IAND intrinsic. The IAND intrinsic expects two arguments
455458
/// in the llvm::ArrayRef.
456459
mlir::Value genIand(mlir::Type, llvm::ArrayRef<mlir::Value>);
457460
mlir::Value genIbits(mlir::Type, llvm::ArrayRef<mlir::Value>);
458461
mlir::Value genIbset(mlir::Type, llvm::ArrayRef<mlir::Value>);
462+
mlir::Value genIshft(mlir::Type, llvm::ArrayRef<mlir::Value>);
463+
mlir::Value genIshftc(mlir::Type, llvm::ArrayRef<mlir::Value>);
459464
fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
460465
fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
461466
fir::ExtendedValue genLen(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -604,6 +609,10 @@ static constexpr IntrinsicHandler handlers[]{
604609
&I::genCpuTime,
605610
{{{"time", asAddr}}},
606611
/*isElemental=*/false},
612+
{"cshift",
613+
&I::genCshift,
614+
{{{"array", asAddr}, {"shift", asAddr}, {"dim", asValue}}},
615+
/*isElemental=*/false},
607616
{"date_and_time",
608617
&I::genDateAndTime,
609618
{{{"date", asAddr, handleDynamicOptional},
@@ -616,9 +625,18 @@ static constexpr IntrinsicHandler handlers[]{
616625
&I::genDotProduct,
617626
{{{"vector_a", asBox}, {"vector_b", asBox}}},
618627
/*isElemental=*/false},
628+
{"eoshift",
629+
&I::genEoshift,
630+
{{{"array", asBox},
631+
{"shift", asAddr},
632+
{"boundary", asBox, handleDynamicOptional},
633+
{"dim", asValue}}},
634+
/*isElemental=*/false},
619635
{"iand", &I::genIand},
620636
{"ibits", &I::genIbits},
621637
{"ibset", &I::genIbset},
638+
{"ishft", &I::genIshft},
639+
{"ishftc", &I::genIshftc},
622640
{"len",
623641
&I::genLen,
624642
{{{"string", asInquired}, {"kind", asValue}}},
@@ -1724,6 +1742,47 @@ void IntrinsicLibrary::genCpuTime(llvm::ArrayRef<fir::ExtendedValue> args) {
17241742
builder.create<fir::StoreOp>(loc, res2, *arg);
17251743
}
17261744

1745+
// CSHIFT
1746+
fir::ExtendedValue
1747+
IntrinsicLibrary::genCshift(mlir::Type resultType,
1748+
llvm::ArrayRef<fir::ExtendedValue> args) {
1749+
assert(args.size() == 3);
1750+
1751+
// Handle required ARRAY argument
1752+
fir::BoxValue arrayBox = builder.createBox(loc, args[0]);
1753+
mlir::Value array = fir::getBase(arrayBox);
1754+
unsigned arrayRank = arrayBox.rank();
1755+
1756+
// Create mutable fir.box to be passed to the runtime for the result.
1757+
mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, arrayRank);
1758+
fir::MutableBoxValue resultMutableBox =
1759+
fir::factory::createTempMutableBox(builder, loc, resultArrayType);
1760+
mlir::Value resultIrBox =
1761+
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
1762+
1763+
if (arrayRank == 1) {
1764+
// Vector case
1765+
// Handle required SHIFT argument as a scalar
1766+
const mlir::Value *shiftAddr = args[1].getUnboxed();
1767+
assert(shiftAddr && "nonscalar CSHIFT argument");
1768+
auto shift = builder.create<fir::LoadOp>(loc, *shiftAddr);
1769+
1770+
fir::runtime::genCshiftVector(builder, loc, resultIrBox, array, shift);
1771+
} else {
1772+
// Non-vector case
1773+
// Handle required SHIFT argument as an array
1774+
mlir::Value shift = builder.createBox(loc, args[1]);
1775+
1776+
// Handle optional DIM argument
1777+
mlir::Value dim =
1778+
isAbsent(args[2])
1779+
? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
1780+
: fir::getBase(args[2]);
1781+
fir::runtime::genCshift(builder, loc, resultIrBox, array, shift, dim);
1782+
}
1783+
return readAndAddCleanUp(resultMutableBox, resultType, "CSHIFT");
1784+
}
1785+
17271786
// DATE_AND_TIME
17281787
void IntrinsicLibrary::genDateAndTime(llvm::ArrayRef<fir::ExtendedValue> args) {
17291788
assert(args.size() == 4 && "date_and_time has 4 args");
@@ -1768,6 +1827,55 @@ IntrinsicLibrary::genDotProduct(mlir::Type resultType,
17681827
stmtCtx, args);
17691828
}
17701829

1830+
// EOSHIFT
1831+
fir::ExtendedValue
1832+
IntrinsicLibrary::genEoshift(mlir::Type resultType,
1833+
llvm::ArrayRef<fir::ExtendedValue> args) {
1834+
assert(args.size() == 4);
1835+
1836+
// Handle required ARRAY argument
1837+
fir::BoxValue arrayBox = builder.createBox(loc, args[0]);
1838+
mlir::Value array = fir::getBase(arrayBox);
1839+
unsigned arrayRank = arrayBox.rank();
1840+
1841+
// Create mutable fir.box to be passed to the runtime for the result.
1842+
mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, arrayRank);
1843+
fir::MutableBoxValue resultMutableBox =
1844+
fir::factory::createTempMutableBox(builder, loc, resultArrayType);
1845+
mlir::Value resultIrBox =
1846+
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
1847+
1848+
// Handle optional BOUNDARY argument
1849+
mlir::Value boundary =
1850+
isAbsent(args[2]) ? builder.create<fir::AbsentOp>(
1851+
loc, fir::BoxType::get(builder.getNoneType()))
1852+
: builder.createBox(loc, args[2]);
1853+
1854+
if (arrayRank == 1) {
1855+
// Vector case
1856+
// Handle required SHIFT argument as a scalar
1857+
const mlir::Value *shiftAddr = args[1].getUnboxed();
1858+
assert(shiftAddr && "nonscalar EOSHIFT SHIFT argument");
1859+
auto shift = builder.create<fir::LoadOp>(loc, *shiftAddr);
1860+
fir::runtime::genEoshiftVector(builder, loc, resultIrBox, array, shift,
1861+
boundary);
1862+
} else {
1863+
// Non-vector case
1864+
// Handle required SHIFT argument as an array
1865+
mlir::Value shift = builder.createBox(loc, args[1]);
1866+
1867+
// Handle optional DIM argument
1868+
mlir::Value dim =
1869+
isAbsent(args[3])
1870+
? builder.createIntegerConstant(loc, builder.getIndexType(), 1)
1871+
: fir::getBase(args[3]);
1872+
fir::runtime::genEoshift(builder, loc, resultIrBox, array, shift, boundary,
1873+
dim);
1874+
}
1875+
return readAndAddCleanUp(resultMutableBox, resultType,
1876+
"unexpected result for EOSHIFT");
1877+
}
1878+
17711879
// IAND
17721880
mlir::Value IntrinsicLibrary::genIand(mlir::Type resultType,
17731881
llvm::ArrayRef<mlir::Value> args) {
@@ -1816,6 +1924,99 @@ mlir::Value IntrinsicLibrary::genIbset(mlir::Type resultType,
18161924
return builder.create<mlir::arith::OrIOp>(loc, args[0], mask);
18171925
}
18181926

1927+
// ISHFT
1928+
mlir::Value IntrinsicLibrary::genIshft(mlir::Type resultType,
1929+
llvm::ArrayRef<mlir::Value> args) {
1930+
// A conformant ISHFT(I,SHIFT) call satisfies:
1931+
// abs(SHIFT) <= BIT_SIZE(I)
1932+
// Return: abs(SHIFT) >= BIT_SIZE(I)
1933+
// ? 0
1934+
// : SHIFT < 0
1935+
// ? I >> abs(SHIFT)
1936+
// : I << abs(SHIFT)
1937+
assert(args.size() == 2);
1938+
mlir::Value bitSize = builder.createIntegerConstant(
1939+
loc, resultType, resultType.cast<mlir::IntegerType>().getWidth());
1940+
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
1941+
mlir::Value shift = builder.createConvert(loc, resultType, args[1]);
1942+
mlir::Value absShift = genAbs(resultType, {shift});
1943+
auto left = builder.create<mlir::arith::ShLIOp>(loc, args[0], absShift);
1944+
auto right = builder.create<mlir::arith::ShRUIOp>(loc, args[0], absShift);
1945+
auto shiftIsLarge = builder.create<mlir::arith::CmpIOp>(
1946+
loc, mlir::arith::CmpIPredicate::sge, absShift, bitSize);
1947+
auto shiftIsNegative = builder.create<mlir::arith::CmpIOp>(
1948+
loc, mlir::arith::CmpIPredicate::slt, shift, zero);
1949+
auto sel =
1950+
builder.create<mlir::arith::SelectOp>(loc, shiftIsNegative, right, left);
1951+
return builder.create<mlir::arith::SelectOp>(loc, shiftIsLarge, zero, sel);
1952+
}
1953+
1954+
// ISHFTC
1955+
mlir::Value IntrinsicLibrary::genIshftc(mlir::Type resultType,
1956+
llvm::ArrayRef<mlir::Value> args) {
1957+
// A conformant ISHFTC(I,SHIFT,SIZE) call satisfies:
1958+
// SIZE > 0
1959+
// SIZE <= BIT_SIZE(I)
1960+
// abs(SHIFT) <= SIZE
1961+
// if SHIFT > 0
1962+
// leftSize = abs(SHIFT)
1963+
// rightSize = SIZE - abs(SHIFT)
1964+
// else [if SHIFT < 0]
1965+
// leftSize = SIZE - abs(SHIFT)
1966+
// rightSize = abs(SHIFT)
1967+
// unchanged = SIZE == BIT_SIZE(I) ? 0 : (I >> SIZE) << SIZE
1968+
// leftMaskShift = BIT_SIZE(I) - leftSize
1969+
// rightMaskShift = BIT_SIZE(I) - rightSize
1970+
// left = (I >> rightSize) & (-1 >> leftMaskShift)
1971+
// right = (I & (-1 >> rightMaskShift)) << leftSize
1972+
// Return: SHIFT == 0 || SIZE == abs(SHIFT) ? I : (unchanged | left | right)
1973+
assert(args.size() == 3);
1974+
mlir::Value bitSize = builder.createIntegerConstant(
1975+
loc, resultType, resultType.cast<mlir::IntegerType>().getWidth());
1976+
mlir::Value I = args[0];
1977+
mlir::Value shift = builder.createConvert(loc, resultType, args[1]);
1978+
mlir::Value size =
1979+
args[2] ? builder.createConvert(loc, resultType, args[2]) : bitSize;
1980+
mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
1981+
mlir::Value ones = builder.createIntegerConstant(loc, resultType, -1);
1982+
mlir::Value absShift = genAbs(resultType, {shift});
1983+
auto elseSize = builder.create<mlir::arith::SubIOp>(loc, size, absShift);
1984+
auto shiftIsZero = builder.create<mlir::arith::CmpIOp>(
1985+
loc, mlir::arith::CmpIPredicate::eq, shift, zero);
1986+
auto shiftEqualsSize = builder.create<mlir::arith::CmpIOp>(
1987+
loc, mlir::arith::CmpIPredicate::eq, absShift, size);
1988+
auto shiftIsNop =
1989+
builder.create<mlir::arith::OrIOp>(loc, shiftIsZero, shiftEqualsSize);
1990+
auto shiftIsPositive = builder.create<mlir::arith::CmpIOp>(
1991+
loc, mlir::arith::CmpIPredicate::sgt, shift, zero);
1992+
auto leftSize = builder.create<mlir::arith::SelectOp>(loc, shiftIsPositive,
1993+
absShift, elseSize);
1994+
auto rightSize = builder.create<mlir::arith::SelectOp>(loc, shiftIsPositive,
1995+
elseSize, absShift);
1996+
auto hasUnchanged = builder.create<mlir::arith::CmpIOp>(
1997+
loc, mlir::arith::CmpIPredicate::ne, size, bitSize);
1998+
auto unchangedTmp1 = builder.create<mlir::arith::ShRUIOp>(loc, I, size);
1999+
auto unchangedTmp2 =
2000+
builder.create<mlir::arith::ShLIOp>(loc, unchangedTmp1, size);
2001+
auto unchanged = builder.create<mlir::arith::SelectOp>(loc, hasUnchanged,
2002+
unchangedTmp2, zero);
2003+
auto leftMaskShift =
2004+
builder.create<mlir::arith::SubIOp>(loc, bitSize, leftSize);
2005+
auto leftMask =
2006+
builder.create<mlir::arith::ShRUIOp>(loc, ones, leftMaskShift);
2007+
auto leftTmp = builder.create<mlir::arith::ShRUIOp>(loc, I, rightSize);
2008+
auto left = builder.create<mlir::arith::AndIOp>(loc, leftTmp, leftMask);
2009+
auto rightMaskShift =
2010+
builder.create<mlir::arith::SubIOp>(loc, bitSize, rightSize);
2011+
auto rightMask =
2012+
builder.create<mlir::arith::ShRUIOp>(loc, ones, rightMaskShift);
2013+
auto rightTmp = builder.create<mlir::arith::AndIOp>(loc, I, rightMask);
2014+
auto right = builder.create<mlir::arith::ShLIOp>(loc, rightTmp, leftSize);
2015+
auto resTmp = builder.create<mlir::arith::OrIOp>(loc, unchanged, left);
2016+
auto res = builder.create<mlir::arith::OrIOp>(loc, resTmp, right);
2017+
return builder.create<mlir::arith::SelectOp>(loc, shiftIsNop, I, res);
2018+
}
2019+
18192020
// LEN
18202021
// Note that this is only used for an unrestricted intrinsic LEN call.
18212022
// Other uses of LEN are rewritten as descriptor inquiries by the front-end.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
3+
! CHECK-LABEL: eoshift_test1
4+
subroutine eoshift_test1(arr, shift)
5+
logical, dimension(3) :: arr, res
6+
integer :: shift
7+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>
8+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x!fir.logical<4>> {bindc_name = "res", uniq_name = "_QFeoshift_test1Eres"}
9+
! CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.array<3x!fir.logical<4>>
10+
! CHECK: %[[arr:.*]] = fir.embox %arg0({{.*}}) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<3x!fir.logical<4>>>
11+
! CHECK: %[[bits:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.logical<4>>>
12+
! CHECK: %[[init:.*]] = fir.embox %[[bits]]({{.*}}) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>
13+
! CHECK: fir.store %[[init]] to %[[resBox]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>
14+
! CHECK: %[[boundBox:.*]] = fir.absent !fir.box<none>
15+
! CHECK: %[[shift:.*]] = fir.load %arg1 : !fir.ref<i32>
16+
17+
res = eoshift(arr, shift)
18+
19+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>) -> !fir.ref<!fir.box<none>>
20+
! CHECK: %[[arrBox:.*]] = fir.convert %[[arr]] : (!fir.box<!fir.array<3x!fir.logical<4>>>) -> !fir.box<none>
21+
! CHECK: %[[shiftBox:.*]] = fir.convert %[[shift]] : (i32) -> i64
22+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshiftVector(%[[resIRBox]], %[[arrBox]], %[[shiftBox]], %[[boundBox]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i64, !fir.box<none>, !fir.ref<i8>, i32) -> none
23+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x!fir.logical<4>>, !fir.array<3x!fir.logical<4>>, !fir.ref<!fir.array<3x!fir.logical<4>>>
24+
end subroutine eoshift_test1
25+
26+
! CHECK-LABEL: eoshift_test2
27+
subroutine eoshift_test2(arr, shift, bound, dim)
28+
integer, dimension(3,3) :: arr, res
29+
integer, dimension(3) :: shift
30+
integer :: bound, dim
31+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi32>>>
32+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x3xi32> {bindc_name = "res", uniq_name = "_QFeoshift_test2Eres"}
33+
!CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x3xi32>>, !fir.shape<2>) -> !fir.array<3x3xi32>
34+
35+
res = eoshift(arr, shift, bound, dim)
36+
37+
! CHECK: %[[arr:.*]] = fir.embox %arg0({{.*}}) : (!fir.ref<!fir.array<3x3xi32>>, !fir.shape<2>) -> !fir.box<!fir.array<3x3xi32>>
38+
! CHECK: %[[boundBox:.*]] = fir.embox %arg2 : (!fir.ref<i32>) -> !fir.box<i32>
39+
! CHECK: %[[dim:.*]] = fir.load %arg3 : !fir.ref<i32>
40+
! CHECK: %[[shiftBox:.*]] = fir.embox %arg1({{.*}}) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
41+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> !fir.ref<!fir.box<none>>
42+
! CHECK: %[[arrBox:.*]] = fir.convert %[[arr]] : (!fir.box<!fir.array<3x3xi32>>) -> !fir.box<none>
43+
! CHECK: %[[shiftBoxNone:.*]] = fir.convert %[[shiftBox]] : (!fir.box<!fir.array<3xi32>>) -> !fir.box<none>
44+
! CHECK: %[[boundBoxNone:.*]] = fir.convert %[[boundBox]] : (!fir.box<i32>) -> !fir.box<none>
45+
46+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshift(%[[resIRBox]], %[[arrBox]], %[[shiftBoxNone]], %[[boundBoxNone]], %[[dim]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
47+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x3xi32>, !fir.array<3x3xi32>, !fir.ref<!fir.array<3x3xi32>>
48+
end subroutine eoshift_test2
49+
50+
! CHECK-LABEL: eoshift_test3
51+
subroutine eoshift_test3(arr, shift, dim)
52+
character(4), dimension(3,3) :: arr, res
53+
integer :: shift, dim
54+
55+
! CHECK: %[[resBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,4>>>>
56+
! CHECK: %[[arr:.*]]:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
57+
! CHECK: %[[array:.*]] = fir.convert %[[arr]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<3x3x!fir.char<1,4>>>
58+
! CHECK: %[[res:.*]] = fir.alloca !fir.array<3x3x!fir.char<1,4>> {bindc_name = "res", uniq_name = "_QFeoshift_test3Eres"}
59+
! CHECK: %[[resLoad:.*]] = fir.array_load %[[res]]({{.*}}) : (!fir.ref<!fir.array<3x3x!fir.char<1,4>>>, !fir.shape<2>) -> !fir.array<3x3x!fir.char<1,4>>
60+
! CHECK: %[[arrayBox:.*]] = fir.embox %[[array]]({{.*}}) : (!fir.ref<!fir.array<3x3x!fir.char<1,4>>>, !fir.shape<2>) -> !fir.box<!fir.array<3x3x!fir.char<1,4>>>
61+
! CHECK: %[[dim:.*]] = fir.load %arg2 : !fir.ref<i32>
62+
63+
res = eoshift(arr, SHIFT=shift, DIM=dim)
64+
65+
! CHECK: %[[boundBox:.*]] = fir.absent !fir.box<none>
66+
! CHECK: %[[shiftBox:.*]] = fir.embox %arg1 : (!fir.ref<i32>) -> !fir.box<i32>
67+
! CHECK: %[[resIRBox:.*]] = fir.convert %[[resBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,4>>>>>) -> !fir.ref<!fir.box<none>>
68+
! CHECK: %[[arrayBoxNone:.*]] = fir.convert %[[arrayBox]] : (!fir.box<!fir.array<3x3x!fir.char<1,4>>>) -> !fir.box<none>
69+
! CHECK: %[[shiftBoxNone:.*]] = fir.convert %[[shiftBox]] : (!fir.box<i32>) -> !fir.box<none>
70+
! CHECK: %[[tmp:.*]] = fir.call @_FortranAEoshift(%[[resIRBox]], %[[arrayBoxNone]], %[[shiftBoxNone]], %[[boundBox]], %[[dim]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
71+
! CHECK: fir.array_merge_store %[[resLoad]], {{.*}} to %[[res]] : !fir.array<3x3x!fir.char<1,4>>, !fir.array<3x3x!fir.char<1,4>>, !fir.ref<!fir.array<3x3x!fir.char<1,4>>>
72+
end subroutine eoshift_test3
73+
74+
! CHECK-LABEL: func @_QPeoshift_test_dynamic_optional(
75+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>>
76+
! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>
77+
! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<!fir.array<10xi32>>
78+
subroutine eoshift_test_dynamic_optional(array, shift, boundary)
79+
type t
80+
integer :: i
81+
end type
82+
integer :: array(:, :)
83+
integer :: shift
84+
integer, optional :: boundary(10)
85+
call next(eoshift(array, shift, boundary))
86+
! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
87+
! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_2]] : (!fir.ref<!fir.array<10xi32>>) -> i1
88+
! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
89+
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_2]](%[[VAL_6]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
90+
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<10xi32>>
91+
! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_5]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<10xi32>>
92+
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<10xi32>>) -> !fir.box<none>
93+
! CHECK: fir.call @_FortranAEoshift(%{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_21]], %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
94+
end subroutine

0 commit comments

Comments
 (0)