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:
Slava Zakharin 2025-05-28 17:18:04 -07:00
parent 55c7d5cdad
commit a0d699a8e6
30 changed files with 265 additions and 112 deletions

View File

@ -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">,
]; ];
} }

View File

@ -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>(

View File

@ -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);
} }
} }

View File

@ -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]]

View File

@ -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

View File

@ -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

View File

@ -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]]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]]

View File

@ -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

View File

@ -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>

View File

@ -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 },

View File

@ -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

View File

@ -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

View File

@ -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) %{{.*}})

View File

@ -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)
} }

View File

@ -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

View File

@ -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 %{{.*}}

View File

@ -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:

View File

@ -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

View File

@ -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(), !{{.*}})

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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
}

View File

@ -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
}