Reland "[flang] Added noalias attribute to function arguments. (#140803)"
This helps to disambiguate accesses in the caller and the callee after LLVM inlining in some apps. I did not see any performance changes, but this is one step towards enabling other optimizations in the apps that I am looking at. The definition of llvm.noalias says: ``` ... indicates that memory locations accessed via pointer values based on the argument or return value are not also accessed, during the execution of the function, via pointer values not based on the argument or return value. This guarantee only holds for memory locations that are modified, by any means, during the execution of the function. ``` I believe this exactly matches Fortran rules for the dummy arguments that are modified during their subprogram execution. I also set llvm.noalias and llvm.nocapture on the !fir.box<> arguments, because the corresponding descriptors cannot be captured and cannot alias anything (not based on them) during the execution of the subprogram.
This commit is contained in:
parent
55c7d5cdad
commit
a0d699a8e6
@ -431,6 +431,12 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> {
|
|||||||
"Set the unsafe-fp-math attribute on functions in the module.">,
|
"Set the unsafe-fp-math attribute on functions in the module.">,
|
||||||
Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"",
|
Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"",
|
||||||
"Set the tune-cpu attribute on functions in the module.">,
|
"Set the tune-cpu attribute on functions in the module.">,
|
||||||
|
Option<"setNoCapture", "set-nocapture", "bool", /*default=*/"false",
|
||||||
|
"Set LLVM nocapture attribute on function arguments, "
|
||||||
|
"if possible">,
|
||||||
|
Option<"setNoAlias", "set-noalias", "bool", /*default=*/"false",
|
||||||
|
"Set LLVM noalias attribute on function arguments, "
|
||||||
|
"if possible">,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,11 +350,15 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
|
|||||||
else
|
else
|
||||||
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
|
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
|
||||||
|
|
||||||
|
bool setNoCapture = false, setNoAlias = false;
|
||||||
|
if (config.OptLevel.isOptimizingForSpeed())
|
||||||
|
setNoCapture = setNoAlias = true;
|
||||||
|
|
||||||
pm.addPass(fir::createFunctionAttr(
|
pm.addPass(fir::createFunctionAttr(
|
||||||
{framePointerKind, config.InstrumentFunctionEntry,
|
{framePointerKind, config.InstrumentFunctionEntry,
|
||||||
config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath,
|
config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath,
|
||||||
config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath,
|
config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath,
|
||||||
""}));
|
/*tuneCPU=*/"", setNoCapture, setNoAlias}));
|
||||||
|
|
||||||
if (config.EnableOpenMP) {
|
if (config.EnableOpenMP) {
|
||||||
pm.addNestedPass<mlir::func::FuncOp>(
|
pm.addNestedPass<mlir::func::FuncOp>(
|
||||||
|
@ -27,17 +27,8 @@ namespace {
|
|||||||
|
|
||||||
class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
|
class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
|
||||||
public:
|
public:
|
||||||
FunctionAttrPass(const fir::FunctionAttrOptions &options) {
|
FunctionAttrPass(const fir::FunctionAttrOptions &options) : Base{options} {}
|
||||||
instrumentFunctionEntry = options.instrumentFunctionEntry;
|
FunctionAttrPass() = default;
|
||||||
instrumentFunctionExit = options.instrumentFunctionExit;
|
|
||||||
framePointerKind = options.framePointerKind;
|
|
||||||
noInfsFPMath = options.noInfsFPMath;
|
|
||||||
noNaNsFPMath = options.noNaNsFPMath;
|
|
||||||
approxFuncFPMath = options.approxFuncFPMath;
|
|
||||||
noSignedZerosFPMath = options.noSignedZerosFPMath;
|
|
||||||
unsafeFPMath = options.unsafeFPMath;
|
|
||||||
}
|
|
||||||
FunctionAttrPass() {}
|
|
||||||
void runOnOperation() override;
|
void runOnOperation() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,14 +47,28 @@ void FunctionAttrPass::runOnOperation() {
|
|||||||
if ((isFromModule || !func.isDeclaration()) &&
|
if ((isFromModule || !func.isDeclaration()) &&
|
||||||
!fir::hasBindcAttr(func.getOperation())) {
|
!fir::hasBindcAttr(func.getOperation())) {
|
||||||
llvm::StringRef nocapture = mlir::LLVM::LLVMDialect::getNoCaptureAttrName();
|
llvm::StringRef nocapture = mlir::LLVM::LLVMDialect::getNoCaptureAttrName();
|
||||||
|
llvm::StringRef noalias = mlir::LLVM::LLVMDialect::getNoAliasAttrName();
|
||||||
mlir::UnitAttr unitAttr = mlir::UnitAttr::get(func.getContext());
|
mlir::UnitAttr unitAttr = mlir::UnitAttr::get(func.getContext());
|
||||||
|
|
||||||
for (auto [index, argType] : llvm::enumerate(func.getArgumentTypes())) {
|
for (auto [index, argType] : llvm::enumerate(func.getArgumentTypes())) {
|
||||||
|
bool isNoCapture = false;
|
||||||
|
bool isNoAlias = false;
|
||||||
if (mlir::isa<fir::ReferenceType>(argType) &&
|
if (mlir::isa<fir::ReferenceType>(argType) &&
|
||||||
!func.getArgAttr(index, fir::getTargetAttrName()) &&
|
!func.getArgAttr(index, fir::getTargetAttrName()) &&
|
||||||
!func.getArgAttr(index, fir::getAsynchronousAttrName()) &&
|
!func.getArgAttr(index, fir::getAsynchronousAttrName()) &&
|
||||||
!func.getArgAttr(index, fir::getVolatileAttrName()))
|
!func.getArgAttr(index, fir::getVolatileAttrName())) {
|
||||||
|
isNoCapture = true;
|
||||||
|
isNoAlias = !fir::isPointerType(argType);
|
||||||
|
} else if (mlir::isa<fir::BaseBoxType>(argType)) {
|
||||||
|
// !fir.box arguments will be passed as descriptor pointers
|
||||||
|
// at LLVM IR dialect level - they cannot be captured,
|
||||||
|
// and cannot alias with anything within the function.
|
||||||
|
isNoCapture = isNoAlias = true;
|
||||||
|
}
|
||||||
|
if (isNoCapture && setNoCapture)
|
||||||
func.setArgAttr(index, nocapture, unitAttr);
|
func.setArgAttr(index, nocapture, unitAttr);
|
||||||
|
if (isNoAlias && setNoAlias)
|
||||||
|
func.setArgAttr(index, noalias, unitAttr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func.func @test_array_coor_box_component_slice(%arg0: !fir.box<!fir.array<2x!fir
|
|||||||
func.func private @take_int(%arg0: !fir.ref<i32>) -> ()
|
func.func private @take_int(%arg0: !fir.ref<i32>) -> ()
|
||||||
|
|
||||||
// CHECK-LABEL: define void @test_array_coor_box_component_slice(
|
// CHECK-LABEL: define void @test_array_coor_box_component_slice(
|
||||||
// CHECK-SAME: ptr %[[VAL_0:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[VAL_0:.*]])
|
||||||
// CHECK: %[[VAL_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 7, i32 0, i32 2
|
// CHECK: %[[VAL_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 7, i32 0, i32 2
|
||||||
// CHECK: %[[VAL_2:.*]] = load i64, ptr %[[VAL_1]]
|
// CHECK: %[[VAL_2:.*]] = load i64, ptr %[[VAL_1]]
|
||||||
// CHECK: %[[VAL_3:.*]] = mul nsw i64 1, %[[VAL_2]]
|
// CHECK: %[[VAL_3:.*]] = mul nsw i64 1, %[[VAL_2]]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// RUN: tco %s | FileCheck %s
|
// RUN: tco %s | FileCheck %s
|
||||||
// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
|
// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
|
||||||
|
|
||||||
// CHECK-LABEL: define void @x(ptr captures(none) %0)
|
// CHECK-LABEL: define void @x(
|
||||||
func.func @x(%arr : !fir.ref<!fir.array<10xf32>>) {
|
func.func @x(%arr : !fir.ref<!fir.array<10xf32>>) {
|
||||||
%1 = arith.constant 0 : index
|
%1 = arith.constant 0 : index
|
||||||
%2 = arith.constant 9 : index
|
%2 = arith.constant 9 : index
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// RUN: tco %s | FileCheck %s
|
// RUN: tco %s | FileCheck %s
|
||||||
|
|
||||||
// CHECK-LABEL: define void @f1
|
// CHECK-LABEL: define void @f1
|
||||||
// CHECK: (ptr captures(none) %[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
||||||
func.func @f1(%a : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
func.func @f1(%a : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
||||||
@ -23,7 +23,7 @@ func.func @f1(%a : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @f2
|
// CHECK-LABEL: define void @f2
|
||||||
// CHECK: (ptr captures(none) %[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
||||||
func.func @f2(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
func.func @f2(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
||||||
@ -47,7 +47,7 @@ func.func @f2(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @f3
|
// CHECK-LABEL: define void @f3
|
||||||
// CHECK: (ptr captures(none) %[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
||||||
func.func @f3(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
func.func @f3(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
||||||
@ -72,7 +72,7 @@ func.func @f3(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @f4
|
// CHECK-LABEL: define void @f4
|
||||||
// CHECK: (ptr captures(none) %[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], {{.*}}, float %[[F:.*]])
|
||||||
func.func @f4(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
func.func @f4(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : index, %p : index, %f : f32) {
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
%s = fir.shape_shift %o, %n, %p, %m : (index, index, index, index) -> !fir.shapeshift<2>
|
||||||
@ -102,7 +102,7 @@ func.func @f4(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
|
|||||||
// `a = b + f`, with and v assumed shapes.
|
// `a = b + f`, with and v assumed shapes.
|
||||||
// Tests that the stride from the descriptor is used.
|
// Tests that the stride from the descriptor is used.
|
||||||
// CHECK-LABEL: define void @f5
|
// CHECK-LABEL: define void @f5
|
||||||
// CHECK: (ptr %[[A:.*]], ptr %[[B:.*]], float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:.*]], ptr {{[^%]*}}%[[B:.*]], float %[[F:.*]])
|
||||||
func.func @f5(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.box<!fir.array<?xf32>>, %arg2: f32) {
|
func.func @f5(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.box<!fir.array<?xf32>>, %arg2: f32) {
|
||||||
%c0 = arith.constant 0 : index
|
%c0 = arith.constant 0 : index
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
@ -135,7 +135,7 @@ func.func @f5(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.box<!fir.array<?xf
|
|||||||
// contiguous array (e.g. `a(2:10:1) = a(1:9:1) + f`, with a assumed shape).
|
// contiguous array (e.g. `a(2:10:1) = a(1:9:1) + f`, with a assumed shape).
|
||||||
// Test that a temp is created.
|
// Test that a temp is created.
|
||||||
// CHECK-LABEL: define void @f6
|
// CHECK-LABEL: define void @f6
|
||||||
// CHECK: (ptr %[[A:[^,]*]], float %[[F:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[A:[^,]*]], float %[[F:.*]])
|
||||||
func.func @f6(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
|
func.func @f6(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
|
||||||
%c0 = arith.constant 0 : index
|
%c0 = arith.constant 0 : index
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
@ -165,7 +165,7 @@ func.func @f6(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
|
|||||||
// Non contiguous array with lower bounds (x = y(100), with y(4:))
|
// Non contiguous array with lower bounds (x = y(100), with y(4:))
|
||||||
// Test array_coor offset computation.
|
// Test array_coor offset computation.
|
||||||
// CHECK-LABEL: define void @f7(
|
// CHECK-LABEL: define void @f7(
|
||||||
// CHECK: ptr captures(none) %[[X:[^,]*]], ptr %[[Y:.*]])
|
// CHECK: ptr {{[^%]*}}%[[X:[^,]*]], ptr {{[^%]*}}%[[Y:.*]])
|
||||||
func.func @f7(%arg0: !fir.ref<f32>, %arg1: !fir.box<!fir.array<?xf32>>) {
|
func.func @f7(%arg0: !fir.ref<f32>, %arg1: !fir.box<!fir.array<?xf32>>) {
|
||||||
%c4 = arith.constant 4 : index
|
%c4 = arith.constant 4 : index
|
||||||
%c100 = arith.constant 100 : index
|
%c100 = arith.constant 100 : index
|
||||||
@ -181,7 +181,7 @@ func.func @f7(%arg0: !fir.ref<f32>, %arg1: !fir.box<!fir.array<?xf32>>) {
|
|||||||
|
|
||||||
// Test A(:, :)%x reference codegen with A constant shape.
|
// Test A(:, :)%x reference codegen with A constant shape.
|
||||||
// CHECK-LABEL: define void @f8(
|
// CHECK-LABEL: define void @f8(
|
||||||
// CHECK-SAME: ptr captures(none) %[[A:.*]], i32 %[[I:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[A:.*]], i32 %[[I:.*]])
|
||||||
func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {
|
func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {
|
||||||
%c0 = arith.constant 0 : index
|
%c0 = arith.constant 0 : index
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
@ -198,7 +198,7 @@ func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {
|
|||||||
|
|
||||||
// Test casts in in array_coor offset computation when type parameters are not i64
|
// Test casts in in array_coor offset computation when type parameters are not i64
|
||||||
// CHECK-LABEL: define ptr @f9(
|
// CHECK-LABEL: define ptr @f9(
|
||||||
// CHECK-SAME: i32 %[[I:.*]], i64 %{{.*}}, i64 %{{.*}}, ptr captures(none) %[[C:.*]])
|
// CHECK-SAME: i32 %[[I:.*]], i64 %{{.*}}, i64 %{{.*}}, ptr {{[^%]*}}%[[C:.*]])
|
||||||
func.func @f9(%i: i32, %e : i64, %j: i64, %c: !fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>> {
|
func.func @f9(%i: i32, %e : i64, %j: i64, %c: !fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>> {
|
||||||
%s = fir.shape %e, %e : (i64, i64) -> !fir.shape<2>
|
%s = fir.shape %e, %e : (i64, i64) -> !fir.shape<2>
|
||||||
// CHECK: %[[CAST:.*]] = sext i32 %[[I]] to i64
|
// CHECK: %[[CAST:.*]] = sext i32 %[[I]] to i64
|
||||||
|
@ -7,7 +7,7 @@ func.func @scalar_addr(%scalar : !fir.ref<!fir.box<!fir.type<t>>>) -> !fir.llvm_
|
|||||||
return %addr : !fir.llvm_ptr<!fir.ref<!fir.type<t>>>
|
return %addr : !fir.llvm_ptr<!fir.ref<!fir.type<t>>>
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define ptr @scalar_addr(
|
// CHECK-LABEL: define ptr @scalar_addr(
|
||||||
// CHECK-SAME: ptr captures(none) %[[BOX:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[BOX:.*]]){{.*}}{
|
||||||
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0
|
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0
|
||||||
// CHECK: ret ptr %[[VAL_0]]
|
// CHECK: ret ptr %[[VAL_0]]
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ func.func @scalar_tdesc(%scalar : !fir.ref<!fir.box<!fir.type<t>>>) -> !fir.llvm
|
|||||||
return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>>
|
return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>>
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define ptr @scalar_tdesc(
|
// CHECK-LABEL: define ptr @scalar_tdesc(
|
||||||
// CHECK-SAME: ptr captures(none) %[[BOX:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[BOX:.*]]){{.*}}{
|
||||||
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 7
|
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 7
|
||||||
// CHECK: ret ptr %[[VAL_0]]
|
// CHECK: ret ptr %[[VAL_0]]
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ func.func @array_addr(%array : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.ty
|
|||||||
return %addr : !fir.llvm_ptr<!fir.ptr<!fir.array<?x!fir.type<t>>>>
|
return %addr : !fir.llvm_ptr<!fir.ptr<!fir.array<?x!fir.type<t>>>>
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define ptr @array_addr(
|
// CHECK-LABEL: define ptr @array_addr(
|
||||||
// CHECK-SAME: ptr captures(none) %[[BOX:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[BOX:.*]]){{.*}}{
|
||||||
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0
|
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0
|
||||||
// CHECK: ret ptr %[[VAL_0]]
|
// CHECK: ret ptr %[[VAL_0]]
|
||||||
|
|
||||||
@ -34,6 +34,6 @@ func.func @array_tdesc(%array : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.t
|
|||||||
return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>>
|
return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>>
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define ptr @array_tdesc(
|
// CHECK-LABEL: define ptr @array_tdesc(
|
||||||
// CHECK-SAME: ptr captures(none) %[[BOX:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[BOX:.*]]){{.*}}{
|
||||||
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 8
|
// CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 8
|
||||||
// CHECK: ret ptr %[[VAL_0]]
|
// CHECK: ret ptr %[[VAL_0]]
|
||||||
|
@ -6,7 +6,7 @@ func.func @test_box_typecode(%a: !fir.class<none>) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @test_box_typecode(
|
// CHECK-LABEL: @test_box_typecode(
|
||||||
// CHECK-SAME: ptr %[[BOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[BOX:.*]])
|
||||||
// CHECK: %[[GEP:.*]] = getelementptr { ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}} }, ptr %[[BOX]], i32 0, i32 4
|
// CHECK: %[[GEP:.*]] = getelementptr { ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}} }, ptr %[[BOX]], i32 0, i32 4
|
||||||
// CHECK: %[[TYPE_CODE:.*]] = load i8, ptr %[[GEP]]
|
// CHECK: %[[TYPE_CODE:.*]] = load i8, ptr %[[GEP]]
|
||||||
// CHECK: %[[TYPE_CODE_CONV:.*]] = sext i8 %[[TYPE_CODE]] to i32
|
// CHECK: %[[TYPE_CODE_CONV:.*]] = sext i8 %[[TYPE_CODE]] to i32
|
||||||
|
@ -24,7 +24,7 @@ func.func private @g(%b : !fir.box<f32>)
|
|||||||
func.func private @ga(%b : !fir.box<!fir.array<?xf32>>)
|
func.func private @ga(%b : !fir.box<!fir.array<?xf32>>)
|
||||||
|
|
||||||
// CHECK-LABEL: define void @f
|
// CHECK-LABEL: define void @f
|
||||||
// CHECK: (ptr captures(none) %[[ARG:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[ARG:.*]])
|
||||||
func.func @f(%a : !fir.ref<f32>) {
|
func.func @f(%a : !fir.ref<f32>) {
|
||||||
// CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
|
// CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
|
||||||
// CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20240719, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
|
// CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20240719, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
|
||||||
@ -38,7 +38,7 @@ func.func @f(%a : !fir.ref<f32>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @fa
|
// CHECK-LABEL: define void @fa
|
||||||
// CHECK: (ptr captures(none) %[[ARG:.*]])
|
// CHECK: (ptr {{[^%]*}}%[[ARG:.*]])
|
||||||
func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
|
func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
|
||||||
%c = fir.convert %a : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?xf32>>
|
%c = fir.convert %a : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?xf32>>
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
@ -54,7 +54,7 @@ func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
|
|||||||
|
|
||||||
// Boxing of a scalar character of dynamic length
|
// Boxing of a scalar character of dynamic length
|
||||||
// CHECK-LABEL: define void @b1(
|
// CHECK-LABEL: define void @b1(
|
||||||
// CHECK-SAME: ptr captures(none) %[[res:.*]], ptr captures(none) %[[arg0:.*]], i64 %[[arg1:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[res:.*]], ptr {{[^%]*}}%[[arg0:.*]], i64 %[[arg1:.*]])
|
||||||
func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.char<1,?>> {
|
func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.char<1,?>> {
|
||||||
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
|
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
|
||||||
// CHECK: %[[size:.*]] = mul i64 1, %[[arg1]]
|
// CHECK: %[[size:.*]] = mul i64 1, %[[arg1]]
|
||||||
@ -69,8 +69,8 @@ func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.
|
|||||||
|
|
||||||
// Boxing of a dynamic array of character with static length (5)
|
// Boxing of a dynamic array of character with static length (5)
|
||||||
// CHECK-LABEL: define void @b2(
|
// CHECK-LABEL: define void @b2(
|
||||||
// CHECK-SAME: ptr captures(none) %[[res]],
|
// CHECK-SAME: ptr {{[^%]*}}%[[res]],
|
||||||
// CHECK-SAME: ptr captures(none) %[[arg0:.*]], i64 %[[arg1:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[arg0:.*]], i64 %[[arg1:.*]])
|
||||||
func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) -> !fir.box<!fir.array<?x!fir.char<1,5>>> {
|
func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) -> !fir.box<!fir.array<?x!fir.char<1,5>>> {
|
||||||
%1 = fir.shape %arg1 : (index) -> !fir.shape<1>
|
%1 = fir.shape %arg1 : (index) -> !fir.shape<1>
|
||||||
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
@ -85,7 +85,7 @@ func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) ->
|
|||||||
|
|
||||||
// Boxing of a dynamic array of character of dynamic length
|
// Boxing of a dynamic array of character of dynamic length
|
||||||
// CHECK-LABEL: define void @b3(
|
// CHECK-LABEL: define void @b3(
|
||||||
// CHECK-SAME: ptr captures(none) %[[res:.*]], ptr captures(none) %[[arg0:.*]], i64 %[[arg1:.*]], i64 %[[arg2:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[res:.*]], ptr {{[^%]*}}%[[arg0:.*]], i64 %[[arg1:.*]], i64 %[[arg2:.*]])
|
||||||
func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %arg2 : index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> {
|
func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %arg2 : index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> {
|
||||||
%1 = fir.shape %arg2 : (index) -> !fir.shape<1>
|
%1 = fir.shape %arg2 : (index) -> !fir.shape<1>
|
||||||
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[alloca:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
@ -103,7 +103,7 @@ func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %ar
|
|||||||
|
|
||||||
// Boxing of a static array of character of dynamic length
|
// Boxing of a static array of character of dynamic length
|
||||||
// CHECK-LABEL: define void @b4(
|
// CHECK-LABEL: define void @b4(
|
||||||
// CHECK-SAME: ptr captures(none) %[[res:.*]], ptr captures(none) %[[arg0:.*]], i64 %[[arg1:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[res:.*]], ptr {{[^%]*}}%[[arg0:.*]], i64 %[[arg1:.*]])
|
||||||
func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) -> !fir.box<!fir.array<7x!fir.char<1,?>>> {
|
func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) -> !fir.box<!fir.array<7x!fir.char<1,?>>> {
|
||||||
%c_7 = arith.constant 7 : index
|
%c_7 = arith.constant 7 : index
|
||||||
%1 = fir.shape %c_7 : (index) -> !fir.shape<1>
|
%1 = fir.shape %c_7 : (index) -> !fir.shape<1>
|
||||||
@ -122,7 +122,7 @@ func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) ->
|
|||||||
|
|
||||||
// Storing a fir.box into a fir.ref<fir.box> (modifying descriptors).
|
// Storing a fir.box into a fir.ref<fir.box> (modifying descriptors).
|
||||||
// CHECK-LABEL: define void @b5(
|
// CHECK-LABEL: define void @b5(
|
||||||
// CHECK-SAME: ptr captures(none) %[[arg0:.*]], ptr %[[arg1:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[arg0:.*]], ptr {{[^%]*}}%[[arg1:.*]])
|
||||||
func.func @b5(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, %arg1 : !fir.box<!fir.heap<!fir.array<?x?xf32>>>) {
|
func.func @b5(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, %arg1 : !fir.box<!fir.heap<!fir.array<?x?xf32>>>) {
|
||||||
fir.store %arg1 to %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
|
fir.store %arg1 to %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
|
||||||
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr %0, ptr %1, i32 72, i1 false)
|
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr %0, ptr %1, i32 72, i1 false)
|
||||||
@ -132,7 +132,7 @@ func.func @b5(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, %arg1
|
|||||||
func.func private @callee6(!fir.box<none>) -> i32
|
func.func private @callee6(!fir.box<none>) -> i32
|
||||||
|
|
||||||
// CHECK-LABEL: define i32 @box6(
|
// CHECK-LABEL: define i32 @box6(
|
||||||
// CHECK-SAME: ptr captures(none) %[[ARG0:.*]], i64 %[[ARG1:.*]], i64 %[[ARG2:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[ARG0:.*]], i64 %[[ARG1:.*]], i64 %[[ARG2:.*]])
|
||||||
func.func @box6(%0 : !fir.ref<!fir.array<?x?x?x?xf32>>, %1 : index, %2 : index) -> i32 {
|
func.func @box6(%0 : !fir.ref<!fir.array<?x?x?x?xf32>>, %1 : index, %2 : index) -> i32 {
|
||||||
%c100 = arith.constant 100 : index
|
%c100 = arith.constant 100 : index
|
||||||
%c50 = arith.constant 50 : index
|
%c50 = arith.constant 50 : index
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
// CHECK: call void @_QPtest_proc_dummy_other(ptr %[[VAL_6]])
|
// CHECK: call void @_QPtest_proc_dummy_other(ptr %[[VAL_6]])
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QFtest_proc_dummyPtest_proc_dummy_a(ptr
|
// CHECK-LABEL: define void @_QFtest_proc_dummyPtest_proc_dummy_a(ptr
|
||||||
// CHECK-SAME: captures(none) %[[VAL_0:.*]], ptr nest captures(none) %[[VAL_1:.*]])
|
// CHECK-SAME: {{[^%]*}}%[[VAL_0:.*]], ptr nest {{[^%]*}}%[[VAL_1:.*]])
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QPtest_proc_dummy_other(ptr
|
// CHECK-LABEL: define void @_QPtest_proc_dummy_other(ptr
|
||||||
// CHECK-SAME: %[[VAL_0:.*]])
|
// CHECK-SAME: %[[VAL_0:.*]])
|
||||||
@ -92,7 +92,7 @@ func.func @_QPtest_proc_dummy_other(%arg0: !fir.boxproc<() -> ()>) {
|
|||||||
// CHECK: call void @llvm.stackrestore.p0(ptr %[[VAL_27]])
|
// CHECK: call void @llvm.stackrestore.p0(ptr %[[VAL_27]])
|
||||||
|
|
||||||
// CHECK-LABEL: define { ptr, i64 } @_QFtest_proc_dummy_charPgen_message(ptr
|
// CHECK-LABEL: define { ptr, i64 } @_QFtest_proc_dummy_charPgen_message(ptr
|
||||||
// CHECK-SAME: captures(none) %[[VAL_0:.*]], i64 %[[VAL_1:.*]], ptr nest captures(none) %[[VAL_2:.*]])
|
// CHECK-SAME: {{[^%]*}}%[[VAL_0:.*]], i64 %[[VAL_1:.*]], ptr nest {{[^%]*}}%[[VAL_2:.*]])
|
||||||
// CHECK: %[[VAL_3:.*]] = getelementptr { { ptr, i64 } }, ptr %[[VAL_2]], i32 0, i32 0
|
// CHECK: %[[VAL_3:.*]] = getelementptr { { ptr, i64 } }, ptr %[[VAL_2]], i32 0, i32 0
|
||||||
// CHECK: %[[VAL_4:.*]] = load { ptr, i64 }, ptr %[[VAL_3]], align 8
|
// CHECK: %[[VAL_4:.*]] = load { ptr, i64 }, ptr %[[VAL_3]], align 8
|
||||||
// CHECK: %[[VAL_5:.*]] = extractvalue { ptr, i64 } %[[VAL_4]], 0
|
// CHECK: %[[VAL_5:.*]] = extractvalue { ptr, i64 } %[[VAL_4]], 0
|
||||||
|
@ -11,7 +11,7 @@ func.func @f1(%a : i32, %b : i32) -> i32 {
|
|||||||
return %3 : i32
|
return %3 : i32
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define i32 @f2(ptr captures(none) %0)
|
// CHECK-LABEL: define i32 @f2(ptr {{[^%]*}}%0)
|
||||||
func.func @f2(%a : !fir.ref<i32>) -> i32 {
|
func.func @f2(%a : !fir.ref<i32>) -> i32 {
|
||||||
%1 = fir.load %a : !fir.ref<i32>
|
%1 = fir.load %a : !fir.ref<i32>
|
||||||
// CHECK: %[[r2:.*]] = load
|
// CHECK: %[[r2:.*]] = load
|
||||||
|
@ -62,7 +62,7 @@ func.func @foo5(%box : !fir.box<!fir.ptr<!fir.array<?xi32>>>, %i : index) -> i32
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @foo6
|
// CHECK-LABEL: @foo6
|
||||||
// CHECK-SAME: (ptr %[[box:.*]], i64 %{{.*}}, ptr captures(none) %{{.*}})
|
// CHECK-SAME: (ptr {{[^%]*}}%[[box:.*]], i64 %{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
func.func @foo6(%box : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1>>>>, %i : i64 , %res : !fir.ref<!fir.char<1>>) {
|
func.func @foo6(%box : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1>>>>, %i : i64 , %res : !fir.ref<!fir.char<1>>) {
|
||||||
// CHECK: %[[addr_gep:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[box]], i32 0, i32 0
|
// 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: %[[addr:.*]] = load ptr, ptr %[[addr_gep]]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// RUN: %flang_fc1 -mmlir -disable-external-name-interop -emit-llvm %s -o -| FileCheck %s
|
// RUN: %flang_fc1 -mmlir -disable-external-name-interop -emit-llvm %s -o -| FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QPtest_callee(ptr %0)
|
// CHECK-LABEL: define void @_QPtest_callee(
|
||||||
func.func @_QPtest_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
|
func.func @_QPtest_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ func.func @_QPtest_slice() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QPtest_dt_callee(ptr %0)
|
// CHECK-LABEL: define void @_QPtest_dt_callee(
|
||||||
func.func @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
|
func.func @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ func.func @_QPtest_dt_slice() {
|
|||||||
func.func private @takesRank2CharBox(!fir.box<!fir.array<?x?x!fir.char<1,?>>>)
|
func.func private @takesRank2CharBox(!fir.box<!fir.array<?x?x!fir.char<1,?>>>)
|
||||||
|
|
||||||
// CHECK-LABEL: define void @emboxSubstring(
|
// CHECK-LABEL: define void @emboxSubstring(
|
||||||
// CHECK-SAME: ptr captures(none) %[[arg0:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[arg0:.*]])
|
||||||
func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
|
func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
|
||||||
%c2 = arith.constant 2 : index
|
%c2 = arith.constant 2 : index
|
||||||
%c3 = arith.constant 3 : index
|
%c3 = arith.constant 3 : index
|
||||||
@ -84,7 +84,7 @@ func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
|
|||||||
|
|
||||||
func.func private @do_something(!fir.box<!fir.array<?xf32>>) -> ()
|
func.func private @do_something(!fir.box<!fir.array<?xf32>>) -> ()
|
||||||
// CHECK: define void @fir_dev_issue_1416
|
// CHECK: define void @fir_dev_issue_1416
|
||||||
// CHECK-SAME: ptr captures(none) %[[base_addr:.*]], i64 %[[low:.*]], i64 %[[up:.*]], i64 %[[at:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[base_addr:.*]], i64 %[[low:.*]], i64 %[[up:.*]], i64 %[[at:.*]])
|
||||||
func.func @fir_dev_issue_1416(%arg0: !fir.ref<!fir.array<40x?xf32>>, %low: index, %up: index, %at : index) {
|
func.func @fir_dev_issue_1416(%arg0: !fir.ref<!fir.array<40x?xf32>>, %low: index, %up: index, %at : index) {
|
||||||
// Test fir.embox with a constant interior array shape.
|
// Test fir.embox with a constant interior array shape.
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
// CHECK-DAG: %[[c:.*]] = type { float, %[[b]] }
|
// CHECK-DAG: %[[c:.*]] = type { float, %[[b]] }
|
||||||
|
|
||||||
// CHECK-LABEL: @simple_field
|
// CHECK-LABEL: @simple_field
|
||||||
// CHECK-SAME: (ptr captures(none) %[[arg0:.*]])
|
// CHECK-SAME: (ptr {{[^%]*}}%[[arg0:.*]])
|
||||||
func.func @simple_field(%arg0: !fir.ref<!fir.type<a{x:f32,i:i32}>>) -> i32 {
|
func.func @simple_field(%arg0: !fir.ref<!fir.type<a{x:f32,i:i32}>>) -> i32 {
|
||||||
// CHECK: %[[GEP:.*]] = getelementptr %a, ptr %[[arg0]], i32 0, i32 1
|
// CHECK: %[[GEP:.*]] = getelementptr %a, ptr %[[arg0]], i32 0, i32 1
|
||||||
%2 = fir.coordinate_of %arg0, i : (!fir.ref<!fir.type<a{x:f32,i:i32}>>) -> !fir.ref<i32>
|
%2 = fir.coordinate_of %arg0, i : (!fir.ref<!fir.type<a{x:f32,i:i32}>>) -> !fir.ref<i32>
|
||||||
@ -17,7 +17,7 @@ func.func @simple_field(%arg0: !fir.ref<!fir.type<a{x:f32,i:i32}>>) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @derived_field
|
// CHECK-LABEL: @derived_field
|
||||||
// CHECK-SAME: (ptr captures(none) %[[arg0:.*]])
|
// CHECK-SAME: (ptr {{[^%]*}}%[[arg0:.*]])
|
||||||
func.func @derived_field(%arg0: !fir.ref<!fir.type<c{x:f32,some_b:!fir.type<b{x:f32,i:i32}>}>>) -> i32 {
|
func.func @derived_field(%arg0: !fir.ref<!fir.type<c{x:f32,some_b:!fir.type<b{x:f32,i:i32}>}>>) -> i32 {
|
||||||
// CHECK: %[[GEP:.*]] = getelementptr %c, ptr %[[arg0]], i32 0, i32 1, i32 1
|
// CHECK: %[[GEP:.*]] = getelementptr %c, ptr %[[arg0]], i32 0, i32 1, i32 1
|
||||||
%3 = fir.coordinate_of %arg0, some_b, i : (!fir.ref<!fir.type<c{x:f32,some_b:!fir.type<b{x:f32,i:i32}>}>>) -> !fir.ref<i32>
|
%3 = fir.coordinate_of %arg0, some_b, i : (!fir.ref<!fir.type<c{x:f32,some_b:!fir.type<b{x:f32,i:i32}>}>>) -> !fir.ref<i32>
|
||||||
|
@ -15,7 +15,7 @@ func.func @test_embox(%addr: !fir.ref<!some_freestyle_type>) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define void @test_embox(
|
// CHECK-LABEL: define void @test_embox(
|
||||||
// CHECK-SAME: ptr captures(none) %[[ADDR:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[ADDR:.*]])
|
||||||
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||||
// CHECK-SAME: { ptr undef, i64 4,
|
// CHECK-SAME: { ptr undef, i64 4,
|
||||||
// CHECK-SAME: i32 20240719, i8 0, i8 42, i8 0, i8 1, ptr null, [1 x i64] zeroinitializer },
|
// CHECK-SAME: i32 20240719, i8 0, i8 42, i8 0, i8 1, ptr null, [1 x i64] zeroinitializer },
|
||||||
|
@ -86,7 +86,7 @@ func.func @_QMunlimitedPsub1(%arg0: !fir.class<!fir.array<?xnone>> {fir.bindc_na
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QMunlimitedPsub1(
|
// CHECK-LABEL: define void @_QMunlimitedPsub1(
|
||||||
// CHECK-SAME: ptr %[[ARRAY:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[ARRAY:.*]]){{.*}}{
|
||||||
// CHECK: %[[BOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
// CHECK: %[[BOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||||
// CHECK: %{{.}} = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 7, i32 0, i32 2
|
// CHECK: %{{.}} = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 7, i32 0, i32 2
|
||||||
// CHECK: %[[TYPE_DESC_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 8
|
// CHECK: %[[TYPE_DESC_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 8
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
func.func private @bar1(!fir.box<!fir.array<?xf32>>)
|
func.func private @bar1(!fir.box<!fir.array<?xf32>>)
|
||||||
// CHECK-LABEL: define void @test_rebox_1(
|
// CHECK-LABEL: define void @test_rebox_1(
|
||||||
// CHECK-SAME: ptr %[[INBOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])
|
||||||
func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
|
func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
|
||||||
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
%c2 = arith.constant 2 : index
|
%c2 = arith.constant 2 : index
|
||||||
@ -54,7 +54,7 @@ func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
|
|||||||
|
|
||||||
func.func private @bar_rebox_test2(!fir.box<!fir.array<?x?x!fir.char<1,?>>>)
|
func.func private @bar_rebox_test2(!fir.box<!fir.array<?x?x!fir.char<1,?>>>)
|
||||||
// CHECK-LABEL: define void @test_rebox_2(
|
// CHECK-LABEL: define void @test_rebox_2(
|
||||||
// CHECK-SAME: ptr %[[INBOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])
|
||||||
func.func @test_rebox_2(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
|
func.func @test_rebox_2(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
%c4 = arith.constant 4 : index
|
%c4 = arith.constant 4 : index
|
||||||
@ -82,7 +82,7 @@ func.func @test_rebox_2(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
|
|||||||
|
|
||||||
func.func private @bar_rebox_test3(!fir.box<!fir.array<?x?x?xf32>>)
|
func.func private @bar_rebox_test3(!fir.box<!fir.array<?x?x?xf32>>)
|
||||||
// CHECK-LABEL: define void @test_rebox_3(
|
// CHECK-LABEL: define void @test_rebox_3(
|
||||||
// CHECK-SAME: ptr %[[INBOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])
|
||||||
func.func @test_rebox_3(%arg0: !fir.box<!fir.array<?xf32>>) {
|
func.func @test_rebox_3(%arg0: !fir.box<!fir.array<?xf32>>) {
|
||||||
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] }
|
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [3 x [3 x i64]] }
|
||||||
%c2 = arith.constant 2 : index
|
%c2 = arith.constant 2 : index
|
||||||
@ -116,7 +116,7 @@ func.func @test_rebox_3(%arg0: !fir.box<!fir.array<?xf32>>) {
|
|||||||
// time constant length.
|
// time constant length.
|
||||||
|
|
||||||
// CHECK-LABEL: define void @test_rebox_4(
|
// CHECK-LABEL: define void @test_rebox_4(
|
||||||
// CHECK-SAME: ptr %[[INPUT:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INPUT:.*]])
|
||||||
func.func @test_rebox_4(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
|
func.func @test_rebox_4(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>) {
|
||||||
// CHECK: %[[NEWBOX_STORAGE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[NEWBOX_STORAGE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
// CHECK: %[[EXTENT_GEP:.*]] = getelementptr {{{.*}}}, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 1
|
// CHECK: %[[EXTENT_GEP:.*]] = getelementptr {{{.*}}}, ptr %[[INPUT]], i32 0, i32 7, i32 0, i32 1
|
||||||
@ -144,7 +144,7 @@ func.func private @bar_test_rebox_4(!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,1
|
|||||||
// end subroutine
|
// end subroutine
|
||||||
|
|
||||||
// CHECK-LABEL: define void @test_cmplx_1(
|
// CHECK-LABEL: define void @test_cmplx_1(
|
||||||
// CHECK-SAME: ptr %[[INBOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])
|
||||||
func.func @test_cmplx_1(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {
|
func.func @test_cmplx_1(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {
|
||||||
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
%c1 = arith.constant 1 : index
|
%c1 = arith.constant 1 : index
|
||||||
@ -184,7 +184,7 @@ func.func @test_cmplx_1(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {
|
|||||||
// end subroutine
|
// end subroutine
|
||||||
|
|
||||||
// CHECK-LABEL: define void @test_cmplx_2(
|
// CHECK-LABEL: define void @test_cmplx_2(
|
||||||
// CHECK-SAME: ptr %[[INBOX:.*]])
|
// CHECK-SAME: ptr {{[^%]*}}%[[INBOX:.*]])
|
||||||
func.func @test_cmplx_2(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {
|
func.func @test_cmplx_2(%arg0: !fir.box<!fir.array<?xcomplex<f32>>>) {
|
||||||
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
// CHECK: %[[OUTBOX_ALLOC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
|
||||||
%c7 = arith.constant 7 : index
|
%c7 = arith.constant 7 : index
|
||||||
|
@ -80,27 +80,27 @@ func.func @not_enough_int_reg_3(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define void @takes_toobig(ptr byval(%toobig) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @takes_toobig(ptr noalias byval(%toobig) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @takes_toobig_align16(ptr byval(%toobig_align16) align 16 captures(none) %{{.*}}) {
|
// CHECK: define void @takes_toobig_align16(ptr noalias byval(%toobig_align16) align 16 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_int_reg_1b(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}}, ptr byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_int_reg_1b(ptr noalias captures(none) %{{.*}}, ptr noalias captures(none) %{{.*}}, ptr noalias captures(none) %{{.*}}, ptr noalias captures(none) %{{.*}}, ptr noalias captures(none) %{{.*}}, ptr noalias captures(none) %{{.*}}, ptr noalias byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_int_reg_2(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%fits_in_2_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_int_reg_2(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%fits_in_2_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @ftakes_toobig(ptr byval(%ftoobig) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @ftakes_toobig(ptr noalias byval(%ftoobig) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @ftakes_toobig_align16(ptr byval(%ftoobig_align16) align 16 captures(none) %{{.*}}) {
|
// CHECK: define void @ftakes_toobig_align16(ptr noalias byval(%ftoobig_align16) align 16 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_sse_reg_1(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_sse_reg_1(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr noalias byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_sse_reg_1b(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, ptr byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_sse_reg_1b(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}}, ptr noalias byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_sse_reg_1c(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, ptr byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_sse_reg_1c(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}, ptr noalias byval(%fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_sse_reg_2(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr byval(%fits_in_2_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @not_enough_sse_reg_2(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr noalias byval(%fits_in_2_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_contains_x87(ptr byval(%contains_x87) align 16 captures(none) %{{.*}}) {
|
// CHECK: define void @test_contains_x87(ptr noalias byval(%contains_x87) align 16 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_contains_complex_x87(ptr byval(%contains_complex_x87) align 16 captures(none) %{{.*}}) {
|
// CHECK: define void @test_contains_complex_x87(ptr noalias byval(%contains_complex_x87) align 16 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_nested_toobig(ptr byval(%nested_toobig) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @test_nested_toobig(ptr noalias byval(%nested_toobig) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_badly_aligned(ptr byval(%badly_aligned) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @test_badly_aligned(ptr noalias byval(%badly_aligned) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_logical_toobig(ptr byval(%logical_too_big) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @test_logical_toobig(ptr noalias byval(%logical_too_big) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @l_not_enough_int_reg(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%l_fits_in_2_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @l_not_enough_int_reg(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%l_fits_in_2_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_complex_toobig(ptr byval(%complex_too_big) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @test_complex_toobig(ptr noalias byval(%complex_too_big) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @cplx_not_enough_sse_reg_1(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr byval(%cplx_fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @cplx_not_enough_sse_reg_1(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr noalias byval(%cplx_fits_in_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @test_char_to_big(ptr byval(%char_too_big) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @test_char_to_big(ptr noalias byval(%char_too_big) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @char_not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%char_fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @char_not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%char_fits_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @mix_not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%mix_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @mix_not_enough_int_reg_1(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%mix_in_1_int_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @mix_not_enough_sse_reg_2(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr byval(%mix_in_1_int_reg_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
// CHECK: define void @mix_not_enough_sse_reg_2(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}, ptr noalias byval(%mix_in_1_int_reg_1_sse_reg) align 8 captures(none) %{{.*}}) {
|
||||||
// CHECK: define void @not_enough_int_reg_3(ptr sret({ fp128, fp128 }) align 16 captures(none) %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}})
|
// CHECK: define void @not_enough_int_reg_3(ptr noalias sret({ fp128, fp128 }) align 16 captures(none) %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, ptr noalias byval(%fits_in_1_int_reg) align 8 captures(none) %{{.*}})
|
||||||
|
@ -30,5 +30,5 @@ func.func @takecomplex10(%z: complex<f80>) {
|
|||||||
// AMD64: %[[VAL_3:.*]] = fir.alloca complex<f80>
|
// AMD64: %[[VAL_3:.*]] = fir.alloca complex<f80>
|
||||||
// AMD64: fir.store %[[VAL_2]] to %[[VAL_3]] : !fir.ref<complex<f80>>
|
// AMD64: fir.store %[[VAL_2]] to %[[VAL_3]] : !fir.ref<complex<f80>>
|
||||||
|
|
||||||
// AMD64_LLVM: define void @takecomplex10(ptr byval({ x86_fp80, x86_fp80 }) align 16 captures(none) %0)
|
// AMD64_LLVM: define void @takecomplex10(ptr noalias byval({ x86_fp80, x86_fp80 }) align 16 captures(none) %0)
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ func.func @gen4() -> complex<f32> {
|
|||||||
return %6 : complex<f32>
|
return %6 : complex<f32>
|
||||||
}
|
}
|
||||||
|
|
||||||
// I32-LABEL: define void @gen8(ptr sret({ double, double }) align 4 captures(none) %
|
// I32-LABEL: define void @gen8(ptr noalias sret({ double, double }) align 4 captures(none) %
|
||||||
// X64-LABEL: define { double, double } @gen8()
|
// X64-LABEL: define { double, double } @gen8()
|
||||||
// AARCH64-LABEL: define { double, double } @gen8()
|
// AARCH64-LABEL: define { double, double } @gen8()
|
||||||
// PPC-LABEL: define { double, double } @gen8()
|
// PPC-LABEL: define { double, double } @gen8()
|
||||||
@ -93,9 +93,9 @@ func.func @call8() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// I32-LABEL: define i64 @char1lensum(ptr captures(none) %0, ptr captures(none) %1, i32 %2, i32 %3)
|
// I32-LABEL: define i64 @char1lensum(ptr {{[^%]*}}%0, ptr {{[^%]*}}%1, i32 %2, i32 %3)
|
||||||
// X64-LABEL: define i64 @char1lensum(ptr captures(none) %0, ptr captures(none) %1, i64 %2, i64 %3)
|
// X64-LABEL: define i64 @char1lensum(ptr {{[^%]*}}%0, ptr {{[^%]*}}%1, i64 %2, i64 %3)
|
||||||
// PPC-LABEL: define i64 @char1lensum(ptr captures(none) %0, ptr captures(none) %1, i64 %2, i64 %3)
|
// PPC-LABEL: define i64 @char1lensum(ptr {{[^%]*}}%0, ptr {{[^%]*}}%1, i64 %2, i64 %3)
|
||||||
func.func @char1lensum(%arg0 : !fir.boxchar<1>, %arg1 : !fir.boxchar<1>) -> i64 {
|
func.func @char1lensum(%arg0 : !fir.boxchar<1>, %arg1 : !fir.boxchar<1>) -> i64 {
|
||||||
// X64-DAG: %[[p0:.*]] = insertvalue { ptr, i64 } undef, ptr %1, 0
|
// X64-DAG: %[[p0:.*]] = insertvalue { ptr, i64 } undef, ptr %1, 0
|
||||||
// X64-DAG: = insertvalue { ptr, i64 } %[[p0]], i64 %3, 1
|
// X64-DAG: = insertvalue { ptr, i64 } %[[p0]], i64 %3, 1
|
||||||
|
@ -28,7 +28,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define void @_QPsimple(
|
// CHECK-LABEL: define void @_QPsimple(
|
||||||
// CHECK-SAME: ptr %[[ARG0:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[ARG0:.*]]){{.*}}{
|
||||||
// [...]
|
// [...]
|
||||||
// load a(2):
|
// load a(2):
|
||||||
// CHECK: %[[VAL20:.*]] = getelementptr i8, ptr %{{.*}}, i64 %{{.*}}
|
// CHECK: %[[VAL20:.*]] = getelementptr i8, ptr %{{.*}}, i64 %{{.*}}
|
||||||
|
@ -60,7 +60,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define void @_QPfunc(
|
// CHECK-LABEL: define void @_QPfunc(
|
||||||
// CHECK-SAME: ptr %[[ARG0:.*]]){{.*}}{
|
// CHECK-SAME: ptr {{[^%]*}}%[[ARG0:.*]]){{.*}}{
|
||||||
// [...]
|
// [...]
|
||||||
// CHECK: %[[VAL5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[ARG0]], i32 0, i32 7, i32 0, i32 0
|
// CHECK: %[[VAL5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[ARG0]], i32 0, i32 7, i32 0, i32 0
|
||||||
// box access:
|
// box access:
|
||||||
|
@ -8,25 +8,25 @@
|
|||||||
|
|
||||||
!RUN: %flang_fc1 -emit-llvm -fopenmp %s -o - | FileCheck %s
|
!RUN: %flang_fc1 -emit-llvm -fopenmp %s -o - | FileCheck %s
|
||||||
|
|
||||||
!CHECK-DAG: define internal void @_copy_box_Uxi32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_Uxi32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_10xi32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_10xi32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_i64(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_i64(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_Uxi64(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_Uxi64(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_f32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_f32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_2x3xf32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_2x3xf32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_z32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_z32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_10xz32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_10xz32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_l32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_l32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_5xl32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_5xl32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_c8x8(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_c8x8(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_10xc8x8(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_10xc8x8(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_c16x5(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_c16x5(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_rec__QFtest_typesTdt(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_rec__QFtest_typesTdt(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_heap_Uxi32(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_heap_Uxi32(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
!CHECK-DAG: define internal void @_copy_box_ptr_Uxc8x9(ptr captures(none) %{{.*}}, ptr captures(none) %{{.*}})
|
!CHECK-DAG: define internal void @_copy_box_ptr_Uxc8x9(ptr {{[^%]*}}%{{.*}}, ptr {{[^%]*}}%{{.*}})
|
||||||
|
|
||||||
!CHECK-LABEL: define internal void @_copy_i32(
|
!CHECK-LABEL: define internal void @_copy_i32(
|
||||||
!CHECK-SAME: ptr captures(none) %[[DST:.*]], ptr captures(none) %[[SRC:.*]]){{.*}} {
|
!CHECK-SAME: ptr {{[^%]*}}%[[DST:.*]], ptr {{[^%]*}}%[[SRC:.*]]){{.*}} {
|
||||||
!CHECK-NEXT: %[[SRC_VAL:.*]] = load i32, ptr %[[SRC]]
|
!CHECK-NEXT: %[[SRC_VAL:.*]] = load i32, ptr %[[SRC]]
|
||||||
!CHECK-NEXT: store i32 %[[SRC_VAL]], ptr %[[DST]]
|
!CHECK-NEXT: store i32 %[[SRC_VAL]], ptr %[[DST]]
|
||||||
!CHECK-NEXT: ret void
|
!CHECK-NEXT: ret void
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
! BOTH-LABEL: }
|
! BOTH-LABEL: }
|
||||||
|
|
||||||
! BOTH-LABEL: define {{.*}}i64 @_QFPfn1
|
! BOTH-LABEL: define {{.*}}i64 @_QFPfn1
|
||||||
! BOTH-SAME: (ptr captures(none) %[[ARG1:.*]], ptr captures(none) %[[ARG2:.*]], ptr captures(none) %[[ARG3:.*]])
|
! BOTH-SAME: (ptr {{[^%]*}}%[[ARG1:.*]], ptr {{[^%]*}}%[[ARG2:.*]], ptr {{[^%]*}}%[[ARG3:.*]])
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[ARG1]], ![[A1:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[ARG1]], ![[A1:.*]], !DIExpression(), !{{.*}})
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[ARG2]], ![[B1:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[ARG2]], ![[B1:.*]], !DIExpression(), !{{.*}})
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[ARG3]], ![[C1:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[ARG3]], ![[C1:.*]], !DIExpression(), !{{.*}})
|
||||||
@ -29,7 +29,7 @@
|
|||||||
! BOTH-LABEL: }
|
! BOTH-LABEL: }
|
||||||
|
|
||||||
! BOTH-LABEL: define {{.*}}i32 @_QFPfn2
|
! BOTH-LABEL: define {{.*}}i32 @_QFPfn2
|
||||||
! BOTH-SAME: (ptr captures(none) %[[FN2ARG1:.*]], ptr captures(none) %[[FN2ARG2:.*]], ptr captures(none) %[[FN2ARG3:.*]])
|
! BOTH-SAME: (ptr {{[^%]*}}%[[FN2ARG1:.*]], ptr {{[^%]*}}%[[FN2ARG2:.*]], ptr {{[^%]*}}%[[FN2ARG3:.*]])
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG1]], ![[A2:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG1]], ![[A2:.*]], !DIExpression(), !{{.*}})
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG2]], ![[B2:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG2]], ![[B2:.*]], !DIExpression(), !{{.*}})
|
||||||
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG3]], ![[C2:.*]], !DIExpression(), !{{.*}})
|
! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG3]], ![[C2:.*]], !DIExpression(), !{{.*}})
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
! RUN: %if x86-registered-target %{ %{check-nounroll} %}
|
! RUN: %if x86-registered-target %{ %{check-nounroll} %}
|
||||||
!
|
!
|
||||||
! CHECK-LABEL: @unroll
|
! CHECK-LABEL: @unroll
|
||||||
! CHECK-SAME: (ptr writeonly captures(none) %[[ARG0:.*]])
|
! CHECK-SAME: (ptr {{[^%]*}}%[[ARG0:.*]])
|
||||||
subroutine unroll(a)
|
subroutine unroll(a)
|
||||||
integer(kind=8), intent(out) :: a(1000)
|
integer(kind=8), intent(out) :: a(1000)
|
||||||
integer(kind=8) :: i
|
integer(kind=8) :: i
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// RUN: %if x86-registered-target %{ %{check-nounroll} %}
|
// RUN: %if x86-registered-target %{ %{check-nounroll} %}
|
||||||
|
|
||||||
// CHECK-LABEL: @unroll
|
// CHECK-LABEL: @unroll
|
||||||
// CHECK-SAME: (ptr writeonly captures(none) %[[ARG0:.*]])
|
// CHECK-SAME: (ptr {{[^%]*}}%[[ARG0:.*]])
|
||||||
func.func @unroll(%arg0: !fir.ref<!fir.array<1000 x index>> {fir.bindc_name = "a"}) {
|
func.func @unroll(%arg0: !fir.ref<!fir.array<1000 x index>> {fir.bindc_name = "a"}) {
|
||||||
%scope = fir.dummy_scope : !fir.dscope
|
%scope = fir.dummy_scope : !fir.dscope
|
||||||
%c1000 = arith.constant 1000 : index
|
%c1000 = arith.constant 1000 : index
|
||||||
|
@ -22,7 +22,7 @@ contains
|
|||||||
end program test
|
end program test
|
||||||
|
|
||||||
! CHECK-LABEL: define internal void @_QFPsub(
|
! CHECK-LABEL: define internal void @_QFPsub(
|
||||||
! CHECK-SAME: ptr %[[arg:.*]])
|
! CHECK-SAME: ptr {{[^%]*}}%[[arg:.*]])
|
||||||
! CHECK: %[[extent:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 7, i64 0, i32 1
|
! CHECK: %[[extent:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 7, i64 0, i32 1
|
||||||
! CHECK: %[[extval:.*]] = load i64, ptr %[[extent]]
|
! CHECK: %[[extval:.*]] = load i64, ptr %[[extent]]
|
||||||
! CHECK: %[[elesize:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 1
|
! CHECK: %[[elesize:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 1
|
||||||
|
@ -49,8 +49,8 @@ module {
|
|||||||
// DISABLE-LABEL: ; ModuleID =
|
// DISABLE-LABEL: ; ModuleID =
|
||||||
// DISABLE-NOT: @_extruded
|
// DISABLE-NOT: @_extruded
|
||||||
// DISABLE: define void @sub1(
|
// DISABLE: define void @sub1(
|
||||||
// DISABLE-SAME: ptr captures(none) [[ARG0:%.*]],
|
// DISABLE-SAME: ptr {{[^%]*}}[[ARG0:%.*]],
|
||||||
// DISABLE-SAME: ptr captures(none) [[ARG1:%.*]])
|
// DISABLE-SAME: ptr {{[^%]*}}[[ARG1:%.*]])
|
||||||
// DISABLE-SAME: {
|
// DISABLE-SAME: {
|
||||||
// DISABLE: [[CONST_R0:%.*]] = alloca double
|
// DISABLE: [[CONST_R0:%.*]] = alloca double
|
||||||
// DISABLE: [[CONST_R1:%.*]] = alloca double
|
// DISABLE: [[CONST_R1:%.*]] = alloca double
|
||||||
|
113
flang/test/Transforms/function-attrs-noalias.fir
Normal file
113
flang/test/Transforms/function-attrs-noalias.fir
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// RUN: fir-opt --function-attr="set-noalias=true" %s | FileCheck %s
|
||||||
|
|
||||||
|
// Test the annotation of function arguments with llvm.noalias.
|
||||||
|
|
||||||
|
// Test !fir.ref arguments.
|
||||||
|
// CHECK-LABEL: func.func private @test_ref(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {llvm.noalias}) {
|
||||||
|
func.func private @test_ref(%arg0: !fir.ref<i32>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_target(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.target}) {
|
||||||
|
func.func private @test_ref_target(%arg0: !fir.ref<i32> {fir.target}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_volatile(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.volatile}) {
|
||||||
|
func.func private @test_ref_volatile(%arg0: !fir.ref<i32> {fir.volatile}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_asynchronous(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.asynchronous}) {
|
||||||
|
func.func private @test_ref_asynchronous(%arg0: !fir.ref<i32> {fir.asynchronous}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<i32>> {llvm.noalias}) {
|
||||||
|
// Test !fir.ref<!fir.box<>> arguments:
|
||||||
|
func.func private @test_ref_box(%arg0: !fir.ref<!fir.box<i32>>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box_target(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<i32>> {fir.target}) {
|
||||||
|
func.func private @test_ref_box_target(%arg0: !fir.ref<!fir.box<i32>> {fir.target}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box_volatile(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<i32>> {fir.volatile}) {
|
||||||
|
func.func private @test_ref_box_volatile(%arg0: !fir.ref<!fir.box<i32>> {fir.volatile}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box_asynchronous(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<i32>> {fir.asynchronous}) {
|
||||||
|
func.func private @test_ref_box_asynchronous(%arg0: !fir.ref<!fir.box<i32>> {fir.asynchronous}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test POINTER arguments.
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box_ptr(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>) {
|
||||||
|
func.func private @test_ref_box_ptr(%arg0: !fir.ref<!fir.box<!fir.ptr<i32>>>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test ALLOCATABLE arguments.
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_box_heap(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>> {llvm.noalias}) {
|
||||||
|
func.func private @test_ref_box_heap(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// BIND(C) functions are not annotated.
|
||||||
|
// CHECK-LABEL: func.func private @test_ref_bindc(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32>)
|
||||||
|
func.func private @test_ref_bindc(%arg0: !fir.ref<i32>) attributes {fir.bindc_name = "test_ref_bindc", fir.proc_attrs = #fir.proc_attrs<bind_c>} {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test function declaration from a module.
|
||||||
|
// CHECK-LABEL: func.func private @_QMtest_modPcheck_module(
|
||||||
|
// CHECK-SAME: !fir.ref<i32> {llvm.noalias})
|
||||||
|
func.func private @_QMtest_modPcheck_module(!fir.ref<i32>)
|
||||||
|
|
||||||
|
// Test !fir.box arguments:
|
||||||
|
// CHECK-LABEL: func.func private @test_box(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {llvm.noalias}) {
|
||||||
|
func.func private @test_box(%arg0: !fir.box<i32>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_target(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.target, llvm.noalias}) {
|
||||||
|
func.func private @test_box_target(%arg0: !fir.box<i32> {fir.target}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_volatile(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.volatile, llvm.noalias}) {
|
||||||
|
func.func private @test_box_volatile(%arg0: !fir.box<i32> {fir.volatile}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_asynchronous(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.asynchronous, llvm.noalias}) {
|
||||||
|
func.func private @test_box_asynchronous(%arg0: !fir.box<i32> {fir.asynchronous}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// !fir.boxchar<> is lowered before FunctionAttrPass, but let's
|
||||||
|
// make sure we do not annotate it.
|
||||||
|
// CHECK-LABEL: func.func private @test_boxchar(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.boxchar<1>) {
|
||||||
|
func.func private @test_boxchar(%arg0: !fir.boxchar<1>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
// RUN: fir-opt --function-attr %s | FileCheck %s
|
// RUN: fir-opt --function-attr="set-nocapture=true" %s | FileCheck %s
|
||||||
|
|
||||||
// If a function has a body and is not bind(c), and if the dummy argument doesn't have the target,
|
// If a function has a body and is not bind(c), and if the dummy argument doesn't have the target,
|
||||||
// asynchronous, volatile, or pointer attribute, then add llvm.nocapture to the dummy argument.
|
// asynchronous, volatile, or pointer attribute, then add llvm.nocapture to the dummy argument.
|
||||||
@ -43,3 +43,28 @@ func.func private @_QMarg_modPcheck_args(!fir.ref<i32> {fir.target}, !fir.ref<i3
|
|||||||
// CHECK-SAME: !fir.ref<i32> {llvm.nocapture},
|
// CHECK-SAME: !fir.ref<i32> {llvm.nocapture},
|
||||||
// CHECK-SAME: !fir.boxchar<1>,
|
// CHECK-SAME: !fir.boxchar<1>,
|
||||||
// CHECK-SAME: !fir.ref<complex<f32>> {llvm.nocapture})
|
// CHECK-SAME: !fir.ref<complex<f32>> {llvm.nocapture})
|
||||||
|
|
||||||
|
// Test !fir.box arguments:
|
||||||
|
// CHECK-LABEL: func.func private @test_box(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {llvm.nocapture}) {
|
||||||
|
func.func private @test_box(%arg0: !fir.box<i32>) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_target(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.target, llvm.nocapture}) {
|
||||||
|
func.func private @test_box_target(%arg0: !fir.box<i32> {fir.target}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_volatile(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.volatile, llvm.nocapture}) {
|
||||||
|
func.func private @test_box_volatile(%arg0: !fir.box<i32> {fir.volatile}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: func.func private @test_box_asynchronous(
|
||||||
|
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<i32> {fir.asynchronous, llvm.nocapture}) {
|
||||||
|
func.func private @test_box_asynchronous(%arg0: !fir.box<i32> {fir.asynchronous}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user