70 changes: 38 additions & 32 deletions flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "flang/Runtime/allocatable.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
Expand Down Expand Up @@ -439,6 +440,14 @@ static bool isDstGlobal(cuf::DataTransferOp op) {
return false;
}

static mlir::Value getShapeFromDecl(mlir::Value src) {
if (auto declareOp = src.getDefiningOp<fir::DeclareOp>())
return declareOp.getShape();
if (auto declareOp = src.getDefiningOp<hlfir::DeclareOp>())
return declareOp.getShape();
return mlir::Value{};
}

struct CUFDataTransferOpConversion
: public mlir::OpRewritePattern<cuf::DataTransferOp> {
using OpRewritePattern::OpRewritePattern;
Expand Down Expand Up @@ -528,54 +537,54 @@ struct CUFDataTransferOpConversion
}

// Conversion of data transfer involving at least one descriptor.
if (mlir::isa<fir::BaseBoxType>(srcTy) &&
mlir::isa<fir::BaseBoxType>(dstTy)) {
// Transfer between two descriptor.
if (mlir::isa<fir::BaseBoxType>(dstTy)) {
// Transfer to a descriptor.
mlir::func::FuncOp func =
isDstGlobal(op)
? fir::runtime::getRuntimeFunc<mkRTKey(
CUFDataTransferGlobalDescDesc)>(loc, builder)
: fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferDescDesc)>(
loc, builder);

auto fTy = func.getFunctionType();
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
mlir::Value dst = op.getDst();
mlir::Value src = op.getSrc();
llvm::SmallVector<mlir::Value> args{fir::runtime::createArguments(
builder, loc, fTy, dst, src, modeValue, sourceFile, sourceLine)};
builder.create<fir::CallOp>(loc, func, args);
rewriter.eraseOp(op);
} else if (mlir::isa<fir::BaseBoxType>(dstTy) && fir::isa_trivial(srcTy)) {
// Scalar to descriptor transfer.
mlir::Value val = op.getSrc();
if (op.getSrc().getDefiningOp() &&
mlir::isa<mlir::arith::ConstantOp>(op.getSrc().getDefiningOp())) {
mlir::Value alloc = builder.createTemporary(loc, srcTy);
builder.create<fir::StoreOp>(loc, op.getSrc(), alloc);
val = alloc;

if (!mlir::isa<fir::BaseBoxType>(srcTy)) {
// If src is not a descriptor, create one.
mlir::Value addr;
if (fir::isa_trivial(srcTy) &&
mlir::matchPattern(op.getSrc().getDefiningOp(),
mlir::m_Constant())) {
// Put constant in memory if it is not.
mlir::Value alloc = builder.createTemporary(loc, srcTy);
builder.create<fir::StoreOp>(loc, op.getSrc(), alloc);
addr = alloc;
} else {
addr = getDeviceAddress(rewriter, op.getSrcMutable(), symtab);
}
mlir::Type boxTy = fir::BoxType::get(srcTy);
llvm::SmallVector<mlir::Value> lenParams;
mlir::Value box =
builder.createBox(loc, boxTy, addr, getShapeFromDecl(src),
/*slice=*/nullptr, lenParams,
/*tdesc=*/nullptr);
mlir::Value memBox = builder.createTemporary(loc, box.getType());
builder.create<fir::StoreOp>(loc, box, memBox);
src = memBox;
}

mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(CUFMemsetDescriptor)>(loc,
builder);
auto fTy = func.getFunctionType();
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
llvm::SmallVector<mlir::Value> args{fir::runtime::createArguments(
builder, loc, fTy, op.getDst(), val, sourceFile, sourceLine)};
builder, loc, fTy, dst, src, modeValue, sourceFile, sourceLine)};
builder.create<fir::CallOp>(loc, func, args);
rewriter.eraseOp(op);
} else {
// Type used to compute the width.
mlir::Type computeType = dstTy;
auto seqTy = mlir::dyn_cast<fir::SequenceType>(dstTy);
bool dstIsDesc = false;
if (mlir::isa<fir::BaseBoxType>(dstTy)) {
dstIsDesc = true;
computeType = srcTy;
seqTy = mlir::dyn_cast<fir::SequenceType>(srcTy);
}
Expand Down Expand Up @@ -606,11 +615,8 @@ struct CUFDataTransferOpConversion
rewriter.create<mlir::arith::MulIOp>(loc, nbElement, widthValue);

mlir::func::FuncOp func =
dstIsDesc
? fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferDescPtr)>(
loc, builder)
: fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferPtrDesc)>(
loc, builder);
fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferPtrDesc)>(
loc, builder);
auto fTy = func.getFunctionType();
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,9 @@ TYPE_PARSER(
TYPE_PARSER(construct<OmpTaskDependenceType>(
"DEPOBJ" >> pure(OmpTaskDependenceType::Type::Depobj) ||
"IN"_id >> pure(OmpTaskDependenceType::Type::In) ||
"INOUT" >> pure(OmpTaskDependenceType::Type::Inout) ||
"INOUT"_id >> pure(OmpTaskDependenceType::Type::Inout) ||
"INOUTSET"_id >> pure(OmpTaskDependenceType::Type::Inoutset) ||
"MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Type::Mutexinoutset) ||
"OUT" >> pure(OmpTaskDependenceType::Type::Out) ||
"SINK" >> pure(OmpTaskDependenceType::Type::Sink) ||
"SOURCE" >> pure(OmpTaskDependenceType::Type::Source)))
Expand Down
56 changes: 42 additions & 14 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,45 @@ void OmpStructureChecker::CheckTargetUpdate() {
}
}

void OmpStructureChecker::CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Type &x) {
// Common checks for task-dependence-type (DEPEND and UPDATE clauses).
unsigned version{context_.langOptions().OpenMPVersion};
unsigned since{0}, deprecatedIn{~0u};

switch (x) {
case parser::OmpTaskDependenceType::Type::In:
case parser::OmpTaskDependenceType::Type::Out:
case parser::OmpTaskDependenceType::Type::Inout:
break;
case parser::OmpTaskDependenceType::Type::Source:
case parser::OmpTaskDependenceType::Type::Sink:
deprecatedIn = 52;
break;
case parser::OmpTaskDependenceType::Type::Mutexinoutset:
case parser::OmpTaskDependenceType::Type::Depobj:
since = 50;
break;
case parser::OmpTaskDependenceType::Type::Inoutset:
since = 52;
break;
}

if (version >= deprecatedIn) {
context_.Say(GetContext().clauseSource,
"%s task-dependence-type is deprecated in %s"_warn_en_US,
parser::ToUpperCaseLetters(
parser::OmpTaskDependenceType::EnumToString(x)),
ThisVersion(deprecatedIn));
} else if (version < since) {
context_.Say(GetContext().clauseSource,
"%s task-dependence-type is not supported in %s, %s"_warn_en_US,
parser::ToUpperCaseLetters(
parser::OmpTaskDependenceType::EnumToString(x)),
ThisVersion(version), TryVersion(since));
}
}

void OmpStructureChecker::Enter(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
Expand Down Expand Up @@ -3393,20 +3432,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
using DepType = parser::OmpTaskDependenceType::Type;
DepType depType = x.v.GetDepType();

if (version >= 52) {
switch (depType) {
case DepType::Sink:
case DepType::Source:
context_.Say(GetContext().clauseSource,
"The %s task-dependence-type is deprecated in %s"_warn_en_US,
parser::ToUpperCaseLetters(
parser::OmpTaskDependenceType::EnumToString(depType)),
ThisVersion(version));
break;
default:
break;
}
}
CheckTaskDependenceType(depType);

if (directive == llvm::omp::OMPD_depobj) {
// [5.0:255:11], [5.1:288:3]
Expand Down Expand Up @@ -3593,6 +3619,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) {
llvm::omp::Directive directive{GetContext().directive};
unsigned version{context_.langOptions().OpenMPVersion};

CheckTaskDependenceType(x.v.v.v);

// [5.1:288:4-5]
// An update clause on a depobj construct must not have source, sink or depobj
// as dependence-type.
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/check-omp-structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ class OmpStructureChecker
void CheckSIMDNest(const parser::OpenMPConstruct &x);
void CheckTargetNest(const parser::OpenMPConstruct &x);
void CheckTargetUpdate();
void CheckTaskDependenceType(const parser::OmpTaskDependenceType::Type &x);
void CheckCancellationNest(
const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
Expand Down
7 changes: 0 additions & 7 deletions flang/runtime/CUDA/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,6 @@ void RTDEF(CUFDataTransferPtrPtr)(void *dst, void *src, std::size_t bytes,
CUDA_REPORT_IF_ERROR(cudaMemcpy(dst, src, bytes, kind));
}

void RTDEF(CUFDataTransferDescPtr)(Descriptor *desc, void *addr,
std::size_t bytes, unsigned mode, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
terminator.Crash(
"not yet implemented: CUDA data transfer from a pointer to a descriptor");
}

void RTDEF(CUFDataTransferPtrDesc)(void *addr, Descriptor *desc,
std::size_t bytes, unsigned mode, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Use --mlir-disable-threading so that the AA queries are serialized
// as well as its diagnostic output.
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s

// Fortran code:
// program main
// integer, target :: arrayA(10)
// integer, pointer, dimension(:) :: ptrA
// integer :: i
// ptrA => arrayA
// !$omp teams distribute parallel do firstprivate(ptrA)
// do i = 1, 10
// arrayA(i) = arrayA(i) + ptrA(i);
// end do
// end program main

// CHECK-LABEL: Testing : "_QQmain"
// CHECK-DAG: ptrA#0 <-> ArrayA#0: MayAlias

omp.private {type = private} @_QFEi_private_ref_i32 : !fir.ref<i32> alloc {
^bb0(%arg0: !fir.ref<i32>):
%0 = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
%1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
omp.yield(%1#0 : !fir.ref<i32>)
}
omp.private {type = firstprivate} @_QFEptra_firstprivate_ref_box_ptr_Uxi32 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> alloc {
^bb0(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
%0 = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {bindc_name = "ptra", pinned, uniq_name = "_QFEptra"}
%1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEptra"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
omp.yield(%1#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
} copy {
^bb0(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %arg1: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
%0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
fir.store %0 to %arg1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
omp.yield(%arg1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
}
func.func @_QQmain() attributes {fir.bindc_name = "main"} {
%0 = fir.address_of(@_QFEarraya) : !fir.ref<!fir.array<10xi32>>
%c10 = arith.constant 10 : index
%1 = fir.shape %c10 : (index) -> !fir.shape<1>
%2:2 = hlfir.declare %0(%1) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEarraya"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
%3 = fir.address_of(@_QFEarrayb) : !fir.ref<!fir.array<10xi32>>
%c10_0 = arith.constant 10 : index
%4 = fir.shape %c10_0 : (index) -> !fir.shape<1>
%5:2 = hlfir.declare %3(%4) {uniq_name = "_QFEarrayb"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
%6 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
%7:2 = hlfir.declare %6 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%8 = fir.address_of(@_QFEptra) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
%9:2 = hlfir.declare %8 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEptra"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
%10 = fir.shape %c10 : (index) -> !fir.shape<1>
%11 = fir.embox %2#1(%10) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
fir.store %11 to %9#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
omp.teams {
omp.parallel private(@_QFEptra_firstprivate_ref_box_ptr_Uxi32 %9#0 -> %arg0, @_QFEi_private_ref_i32 %7#0 -> %arg1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<i32>) {
%12:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEptra"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
%13:2 = hlfir.declare %arg1 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%c1_i32 = arith.constant 1 : i32
%c10_i32 = arith.constant 10 : i32
%c1_i32_1 = arith.constant 1 : i32
omp.distribute {
omp.wsloop {
omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_1) {
fir.store %arg2 to %13#1 : !fir.ref<i32>
%14 = fir.load %13#0 : !fir.ref<i32>
%15 = fir.convert %14 : (i32) -> i64
%16 = hlfir.designate %2#0 (%15) : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
%17 = fir.load %16 : !fir.ref<i32>
%18 = fir.load %12#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
%19 = fir.load %13#0 : !fir.ref<i32>
%20 = fir.convert %19 : (i32) -> i64
%21 = hlfir.designate %18 (%20) {test.ptr = "ptrA" } : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, i64) -> !fir.ref<i32>
%22 = fir.load %21 : !fir.ref<i32>
%23 = arith.addi %17, %22 : i32
%24 = fir.load %13#0 : !fir.ref<i32>
%25 = fir.convert %24 : (i32) -> i64
%26 = hlfir.designate %2#0 (%25) {test.ptr = "ArrayA"} : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
hlfir.assign %23 to %26 : i32, !fir.ref<i32>
omp.yield
}
} {omp.composite}
} {omp.composite}
omp.terminator
} {omp.composite}
omp.terminator
}
return
}
fir.global internal @_QFEarraya target : !fir.array<10xi32> {
%0 = fir.zero_bits !fir.array<10xi32>
fir.has_value %0 : !fir.array<10xi32>
}
fir.global internal @_QFEarrayb : !fir.array<10xi32> {
%0 = fir.zero_bits !fir.array<10xi32>
fir.has_value %0 : !fir.array<10xi32>
}
fir.global internal @_QFEptra : !fir.box<!fir.ptr<!fir.array<?xi32>>> {
%0 = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
%c0 = arith.constant 0 : index
%1 = fir.shape %c0 : (index) -> !fir.shape<1>
%2 = fir.embox %0(%1) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
fir.has_value %2 : !fir.box<!fir.ptr<!fir.array<?xi32>>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Use --mlir-disable-threading so that the AA queries are serialized
// as well as its diagnostic output.
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s

// Fortran code:
//
// program main
// integer :: arrayA(10,10)
// integer :: tmp(2)
// integer :: i,j
// !$omp teams distribute parallel do private(tmp)
// do j = 1, 10
// do i = 1,10
// tmp = [i,j]
// arrayA = tmp(1)
// end do
// end do
// end program main

// CHECK-LABEL: Testing : "_QQmain"
// CHECK-DAG: tmp_private_array#0 <-> unnamed_array#0: NoAlias
// CHECK-DAG: tmp_private_array#1 <-> unnamed_array#0: NoAlias

omp.private {type = private} @_QFEi_private_ref_i32 : !fir.ref<i32> alloc {
^bb0(%arg0: !fir.ref<i32>):
%0 = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
%1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
omp.yield(%1#0 : !fir.ref<i32>)
}
omp.private {type = private} @_QFEj_private_ref_i32 : !fir.ref<i32> alloc {
^bb0(%arg0: !fir.ref<i32>):
%0 = fir.alloca i32 {bindc_name = "j", pinned, uniq_name = "_QFEj"}
%1:2 = hlfir.declare %0 {uniq_name = "_QFEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
omp.yield(%1#0 : !fir.ref<i32>)
}
omp.private {type = private} @_QFEtmp_private_ref_2xi32 : !fir.ref<!fir.array<2xi32>> alloc {
^bb0(%arg0: !fir.ref<!fir.array<2xi32>>):
%c2 = arith.constant 2 : index
%0 = fir.alloca !fir.array<2xi32> {bindc_name = "tmp", pinned, uniq_name = "_QFEtmp"}
%1 = fir.shape %c2 : (index) -> !fir.shape<1>
%2:2 = hlfir.declare %0(%1) {uniq_name = "_QFEtmp"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
omp.yield(%2#0 : !fir.ref<!fir.array<2xi32>>)
}
func.func @_QQmain() attributes {fir.bindc_name = "main"} {
%0 = fir.address_of(@_QFEarraya) : !fir.ref<!fir.array<10x10xi32>>
%c10 = arith.constant 10 : index
%c10_0 = arith.constant 10 : index
%1 = fir.shape %c10, %c10_0 : (index, index) -> !fir.shape<2>
%2:2 = hlfir.declare %0(%1) {uniq_name = "_QFEarraya"} : (!fir.ref<!fir.array<10x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xi32>>, !fir.ref<!fir.array<10x10xi32>>)
%3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
%4:2 = hlfir.declare %3 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%5 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFEj"}
%6:2 = hlfir.declare %5 {uniq_name = "_QFEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%c2 = arith.constant 2 : index
%7 = fir.alloca !fir.array<2xi32> {bindc_name = "tmp", uniq_name = "_QFEtmp"}
%8 = fir.shape %c2 : (index) -> !fir.shape<1>
%9:2 = hlfir.declare %7(%8) {uniq_name = "_QFEtmp"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
omp.teams {
omp.parallel private(@_QFEtmp_private_ref_2xi32 %9#0 -> %arg0, @_QFEj_private_ref_i32 %6#0 -> %arg1, @_QFEi_private_ref_i32 %4#0 -> %arg2 : !fir.ref<!fir.array<2xi32>>, !fir.ref<i32>, !fir.ref<i32>) {
%c2_1 = arith.constant 2 : index
%10 = fir.shape %c2_1 : (index) -> !fir.shape<1>
%11:2 = hlfir.declare %arg0(%10) {uniq_name = "_QFEtmp", test.ptr = "tmp_private_array"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>)
%12:2 = hlfir.declare %arg1 {uniq_name = "_QFEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%13:2 = hlfir.declare %arg2 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%c1_i32 = arith.constant 1 : i32
%c10_i32 = arith.constant 10 : i32
%c1_i32_2 = arith.constant 1 : i32
omp.distribute {
omp.wsloop {
omp.loop_nest (%arg3) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_2) {
fir.store %arg3 to %12#1 : !fir.ref<i32>
%c1_i32_3 = arith.constant 1 : i32
%14 = fir.convert %c1_i32_3 : (i32) -> index
%c10_i32_4 = arith.constant 10 : i32
%15 = fir.convert %c10_i32_4 : (i32) -> index
%c1 = arith.constant 1 : index
%16 = fir.convert %14 : (index) -> i32
%17:2 = fir.do_loop %arg4 = %14 to %15 step %c1 iter_args(%arg5 = %16) -> (index, i32) {
fir.store %arg5 to %13#1 : !fir.ref<i32>
%c2_5 = arith.constant 2 : index
%c1_6 = arith.constant 1 : index
%c1_7 = arith.constant 1 : index
%18 = fir.allocmem !fir.array<2xi32> {bindc_name = ".tmp.arrayctor", uniq_name = ""}
%19 = fir.shape %c2_5 : (index) -> !fir.shape<1>
%20:2 = hlfir.declare %18(%19) {uniq_name = ".tmp.arrayctor"} : (!fir.heap<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<2xi32>>, !fir.heap<!fir.array<2xi32>>)
%21 = fir.load %13#0 : !fir.ref<i32>
%22 = arith.addi %c1_6, %c1_7 : index
%23 = hlfir.designate %20#0 (%c1_6) : (!fir.heap<!fir.array<2xi32>>, index) -> !fir.ref<i32>
hlfir.assign %21 to %23 : i32, !fir.ref<i32>
%24 = fir.load %12#0 : !fir.ref<i32>
%25 = hlfir.designate %20#0 (%22) : (!fir.heap<!fir.array<2xi32>>, index) -> !fir.ref<i32>
hlfir.assign %24 to %25 : i32, !fir.ref<i32>
%true = arith.constant true
%26 = hlfir.as_expr %20#0 move %true {test.ptr = "unnamed_array"} : (!fir.heap<!fir.array<2xi32>>, i1) -> !hlfir.expr<2xi32>
hlfir.assign %26 to %11#0 : !hlfir.expr<2xi32>, !fir.ref<!fir.array<2xi32>>
hlfir.destroy %26 : !hlfir.expr<2xi32>
%c1_8 = arith.constant 1 : index
%27 = hlfir.designate %11#0 (%c1_8) : (!fir.ref<!fir.array<2xi32>>, index) -> !fir.ref<i32>
%28 = fir.load %27 : !fir.ref<i32>
hlfir.assign %28 to %2#0 : i32, !fir.ref<!fir.array<10x10xi32>>
%29 = arith.addi %arg4, %c1 : index
%30 = fir.convert %c1 : (index) -> i32
%31 = fir.load %13#1 : !fir.ref<i32>
%32 = arith.addi %31, %30 : i32
fir.result %29, %32 : index, i32
}
fir.store %17#1 to %13#1 : !fir.ref<i32>
omp.yield
}
} {omp.composite}
} {omp.composite}
omp.terminator
} {omp.composite}
omp.terminator
}
return
}
fir.global internal @_QFEarraya : !fir.array<10x10xi32> {
%0 = fir.zero_bits !fir.array<10x10xi32>
fir.has_value %0 : !fir.array<10x10xi32>
}
4 changes: 2 additions & 2 deletions flang/test/Driver/mlir-debug-pass-pipeline.f90
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@

! ALL-NEXT: CodeGenRewrite
! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated
! ALL-NEXT: TargetRewrite
! ALL-NEXT: CompilerGeneratedNamesConversion
! ALL-NEXT: ExternalNameConversion
! DEBUG-NEXT: AddDebugInfo
! NO-DEBUG-NOT: AddDebugInfo
! ALL-NEXT: TargetRewrite
! ALL-NEXT: CompilerGeneratedNamesConversion
! ALL: FIRToLLVMLowering
! ALL-NOT: LLVMIRLoweringPass
2 changes: 1 addition & 1 deletion flang/test/Driver/mlir-pass-pipeline.f90
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@

! ALL-NEXT: CodeGenRewrite
! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated
! ALL-NEXT: ExternalNameConversion
! ALL-NEXT: TargetRewrite
! ALL-NEXT: CompilerGeneratedNamesConversion
! ALL-NEXT: ExternalNameConversion
! ALL-NEXT: FIRToLLVMLowering
! ALL-NOT: LLVMIRLoweringPass
70 changes: 52 additions & 18 deletions flang/test/Fir/CUDA/cuda-data-transfer.fir
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ func.func @_QPsub2() {
}

// CHECK-LABEL: func.func @_QPsub2()
// CHECK: %[[TEMP_BOX:.*]] = fir.alloca !fir.box<i32>
// CHECK: %[[TEMP:.*]] = fir.alloca i32
// CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub2Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
// CHECK: %[[C2:.*]] = arith.constant 2 : i32
// CHECK: fir.store %[[C2]] to %[[TEMP]] : !fir.ref<i32>
// CHECK: %[[EMBOX:.*]] = fir.embox %[[TEMP]] : (!fir.ref<i32>) -> !fir.box<i32>
// CHECK: fir.store %[[EMBOX]] to %[[TEMP_BOX]] : !fir.ref<!fir.box<i32>>
// CHECK: %[[ADEV_BOX:.*]] = fir.convert %[[ADEV]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[TEMP_CONV:.*]] = fir.convert %[[TEMP]] : (!fir.ref<i32>) -> !fir.llvm_ptr<i8>
// CHECK: fir.call @_FortranACUFMemsetDescriptor(%[[ADEV_BOX]], %[[TEMP_CONV]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>, !fir.ref<i8>, i32) -> none
// CHECK: %[[TEMP_CONV:.*]] = fir.convert %[[TEMP_BOX]] : (!fir.ref<!fir.box<i32>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferDescDesc(%[[ADEV_BOX]], %[[TEMP_CONV]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none

func.func @_QPsub3() {
%0 = cuf.alloc !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "adev", data_attr = #cuf.cuda<device>, uniq_name = "_QFsub3Eadev"} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
Expand All @@ -48,12 +51,15 @@ func.func @_QPsub3() {
}

// CHECK-LABEL: func.func @_QPsub3()
// CHECK: %[[TEMP_BOX:.*]] = fir.alloca !fir.box<i32>
// CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub3Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
// CHECK: %[[V:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsub3Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
// CHECK: %[[EMBOX:.*]] = fir.embox %[[V]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
// CHECK: fir.store %[[EMBOX]] to %[[TEMP_BOX]] : !fir.ref<!fir.box<i32>>
// CHECK: %[[ADEV_BOX:.*]] = fir.convert %[[ADEV]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[V_CONV:.*]] = fir.convert %[[V]]#0 : (!fir.ref<i32>) -> !fir.llvm_ptr<i8>
// CHECK: fir.call @_FortranACUFMemsetDescriptor(%[[ADEV_BOX]], %[[V_CONV]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>, !fir.ref<i8>, i32) -> none

// CHECK: %[[V_CONV:.*]] = fir.convert %[[TEMP_BOX]] : (!fir.ref<!fir.box<i32>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferDescDesc(%[[ADEV_BOX]], %[[V_CONV]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none
func.func @_QPsub4() {
%0 = cuf.alloc !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "adev", data_attr = #cuf.cuda<device>, uniq_name = "_QFsub4Eadev"} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
%4:2 = hlfir.declare %0 {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub4Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
Expand All @@ -67,15 +73,14 @@ func.func @_QPsub4() {
return
}
// CHECK-LABEL: func.func @_QPsub4()
// CHECK: %[[TEMP_BOX:.*]] = fir.alloca !fir.box<!fir.array<10xi32>>
// CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub4Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
// CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub4Eahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
// CHECK: %[[NBELEM:.*]] = arith.constant 10 : index
// CHECK: %[[WIDTH:.*]] = arith.constant 4 : index
// CHECK: %[[BYTES:.*]] = arith.muli %[[NBELEM]], %[[WIDTH]] : index
// CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%[[AHOST_SHAPE:.*]]) {uniq_name = "_QFsub4Eahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
// CHECK: %[[EMBOX:.*]] = fir.embox %[[AHOST]]#0(%[[AHOST_SHAPE]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
// CHECK: fir.store %[[EMBOX]] to %[[TEMP_BOX]] : !fir.ref<!fir.box<!fir.array<10xi32>>>
// CHECK: %[[ADEV_BOX:.*]] = fir.convert %[[ADEV]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[AHOST_PTR:.*]] = fir.convert %[[AHOST]]#0 : (!fir.ref<!fir.array<10xi32>>) -> !fir.llvm_ptr<i8>
// CHECK: %[[BYTES_CONV:.*]] = fir.convert %[[BYTES]] : (index) -> i64
// CHECK: fir.call @_FortranACUFDataTransferDescPtr(%[[ADEV_BOX]], %[[AHOST_PTR]], %[[BYTES_CONV]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>, i64, i32, !fir.ref<i8>, i32) -> none
// CHECK: %[[AHOST_BOX:.*]] = fir.convert %[[TEMP_BOX]] : (!fir.ref<!fir.box<!fir.array<10xi32>>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferDescDesc(%[[ADEV_BOX]], %[[AHOST_BOX]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none
// CHECK: %[[NBELEM:.*]] = arith.constant 10 : index
// CHECK: %[[WIDTH:.*]] = arith.constant 4 : index
// CHECK: %[[BYTES:.*]] = arith.muli %[[NBELEM]], %[[WIDTH]] : index
Expand Down Expand Up @@ -110,16 +115,15 @@ func.func @_QPsub5(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}) {
}

// CHECK-LABEL: func.func @_QPsub5
// CHECK: %[[TEMP_BOX:.*]] = fir.alloca !fir.box<!fir.array<?x?xi32>>
// CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub5Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>)
// CHECK: %[[SHAPE:.*]] = fir.shape %[[I1:.*]], %[[I2:.*]] : (index, index) -> !fir.shape<2>
// CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%[[SHAPE]]) {uniq_name = "_QFsub5Eahost"} : (!fir.ref<!fir.array<?x?xi32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xi32>>, !fir.ref<!fir.array<?x?xi32>>)
// CHECK: %[[NBELEM:.*]] = arith.muli %[[I1]], %[[I2]] : index
// CHECK: %[[WIDTH:.*]] = arith.constant 4 : index
// CHECK: %[[BYTES:.*]] = arith.muli %[[NBELEM]], %[[WIDTH]] : index
// CHECK: %[[EMBOX:.*]] = fir.embox %[[AHOST]]#1(%[[SHAPE]]) : (!fir.ref<!fir.array<?x?xi32>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?xi32>>
// CHECK: fir.store %[[EMBOX]] to %[[TEMP_BOX]] : !fir.ref<!fir.box<!fir.array<?x?xi32>>>
// CHECK: %[[ADEV_BOX:.*]] = fir.convert %[[ADEV]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[AHOST_PTR:.*]] = fir.convert %[[AHOST]]#1 : (!fir.ref<!fir.array<?x?xi32>>) -> !fir.llvm_ptr<i8>
// CHECK: %[[BYTES_CONV:.*]] = fir.convert %[[BYTES]] : (index) -> i64
// CHECK: fir.call @_FortranACUFDataTransferDescPtr(%[[ADEV_BOX]], %[[AHOST_PTR]], %[[BYTES_CONV]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>, i64, i32, !fir.ref<i8>, i32) -> none
// CHECK: %[[AHOST_BOX:.*]] = fir.convert %[[TEMP_BOX]] : (!fir.ref<!fir.box<!fir.array<?x?xi32>>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferDescDesc(%[[ADEV_BOX]], %[[AHOST_BOX]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none
// CHECK: %[[NBELEM:.*]] = arith.muli %[[I1]], %[[I2]] : index
// CHECK: %[[WIDTH:.*]] = arith.constant 4 : index
// CHECK: %[[BYTES:.*]] = arith.muli %[[NBELEM]], %[[WIDTH]] : index
Expand Down Expand Up @@ -248,5 +252,35 @@ func.func @_QQdesc_global() attributes {fir.bindc_name = "host_sub"} {
// CHECK: %[[BOX_NONE:.*]] = fir.convert %[[GLOBAL_DECL:.*]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferGlobalDescDesc(%[[BOX_NONE]],{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none

fir.global @_QMmod2Eadev {data_attr = #cuf.cuda<device>} : !fir.box<!fir.heap<!fir.array<?xi32>>> {
%c0 = arith.constant 0 : index
%0 = fir.zero_bits !fir.heap<!fir.array<?xi32>>
%1 = fir.shape %c0 : (index) -> !fir.shape<1>
%2 = fir.embox %0(%1) {allocator_idx = 2 : i32} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
fir.has_value %2 : !fir.box<!fir.heap<!fir.array<?xi32>>>
}
func.func @_QPdesc_global_ptr() {
%c10 = arith.constant 10 : index
%0 = fir.address_of(@_QMmod2Eadev) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
%1 = fir.declare %0 {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmod2Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
%2 = fir.alloca !fir.array<10xi32> {bindc_name = "ahost", uniq_name = "_QFdesc_global_ptrEahost"}
%3 = fir.shape %c10 : (index) -> !fir.shape<1>
%4 = fir.declare %2(%3) {uniq_name = "_QFdesc_global_ptrEahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
cuf.data_transfer %4 to %1 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
return
}

// CHECK-LABEL: func.func @_QPdesc_global_ptr()
// CHECK: %[[TEMP_BOX:.*]] = fir.alloca !fir.box<!fir.array<10xi32>>
// CHECK: %[[ADDR_ADEV:.*]] = fir.address_of(@_QMmod2Eadev) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
// CHECK: %[[DECL_ADEV:.*]] = fir.declare %[[ADDR_ADEV]] {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmod2Eadev"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
// CHECK: %[[AHOST:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "ahost", uniq_name = "_QFdesc_global_ptrEahost"}
// CHECK: %[[SHAPE:.*]] = fir.shape %c10 : (index) -> !fir.shape<1>
// CHECK: %[[DECL_AHOST:.*]] = fir.declare %[[AHOST]](%[[SHAPE]]) {uniq_name = "_QFdesc_global_ptrEahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
// CHECK: %[[EMBOX:.*]] = fir.embox %[[DECL_AHOST]](%[[SHAPE]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
// CHECK: fir.store %[[EMBOX]] to %[[TEMP_BOX]] : !fir.ref<!fir.box<!fir.array<10xi32>>>
// CHECK: %[[ADEV_BOXNONE:.*]] = fir.convert %[[DECL_ADEV]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[AHOST_BOXNONE:.*]] = fir.convert %[[TEMP_BOX]] : (!fir.ref<!fir.box<!fir.array<10xi32>>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferGlobalDescDesc(%[[ADEV_BOXNONE]], %[[AHOST_BOXNONE]], %c0{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> none

} // end of module
4 changes: 2 additions & 2 deletions flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
Original file line number Diff line number Diff line change
Expand Up @@ -781,11 +781,11 @@ func.func @_QPsimple_reduction(%arg0: !fir.ref<!fir.array<100x!fir.logical<4>>>
// -----

// CHECK: llvm.func @_QPs
// CHECK: omp.atomic.read %{{.*}} = %{{.*}} : !llvm.ptr, !llvm.struct<(f32, f32)>
// CHECK: omp.atomic.read %{{.*}} = %{{.*}} : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)>

func.func @_QPs(%arg0: !fir.ref<complex<f32>> {fir.bindc_name = "x"}) {
%0 = fir.alloca complex<f32> {bindc_name = "v", uniq_name = "_QFsEv"}
omp.atomic.read %0 = %arg0 : !fir.ref<complex<f32>>, complex<f32>
omp.atomic.read %0 = %arg0 : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32>
return
}

Expand Down
12 changes: 12 additions & 0 deletions flang/test/Integration/debug-complex-2.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s

! Test that complex return type is correctly represented in debug.
complex function fn(a)
complex, intent(in) :: a
fn = a
end function

! CHECK-DAG: ![[CMPLX:.*]] = !DIBasicType(name: "complex", size: 64, encoding: DW_ATE_complex_float)
! CHECK-DAG: ![[SR_TY:.*]] = !DISubroutineType(cc: DW_CC_normal, types: ![[TYPES:.*]])
! CHECK-DAG: ![[TYPES]] = !{![[CMPLX]], ![[CMPLX]]}
! CHECK-DAG: !DISubprogram(name: "fn"{{.*}}type: ![[SR_TY]]{{.*}})
10 changes: 10 additions & 0 deletions flang/test/Integration/debug-external-linkage-name.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s

! Test that correct linkage name is generated in the debug info.
subroutine sub(a)
integer :: a
return a+1
end

!CHECK: !DISubprogram(name: "sub", linkageName: "sub_"{{.*}})

107 changes: 98 additions & 9 deletions flang/test/Lower/OpenACC/acc-atomic-capture.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ program acc_atomic_capture_test
!CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %2 {uniq_name = "_QFEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: %[[temp:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32>
!CHECK: acc.atomic.capture {
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: acc.atomic.update %[[Y_DECL]]#1 : !fir.ref<i32> {
!CHECK: ^bb0(%[[ARG:.*]]: i32):
!CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[ARG]] : i32
Expand All @@ -32,7 +32,7 @@ program acc_atomic_capture_test
!CHECK: %[[result:.*]] = arith.muli %[[temp]], %[[ARG]] : i32
!CHECK: acc.yield %[[result]] : i32
!CHECK: }
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: }

!$acc atomic capture
Expand All @@ -47,7 +47,7 @@ program acc_atomic_capture_test
!CHECK: %[[result_noreassoc:.*]] = hlfir.no_reassoc %[[result]] : i32
!CHECK: %[[result:.*]] = arith.addi %[[constant_20]], %[[result_noreassoc]] : i32
!CHECK: acc.atomic.capture {
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>
!CHECK: acc.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: acc.atomic.write %[[Y_DECL]]#1 = %[[result]] : !fir.ref<i32>, i32
!CHECK: }

Expand Down Expand Up @@ -82,7 +82,7 @@ subroutine pointers_in_atomic_capture()
!CHECK: %[[result:.*]] = arith.addi %[[ARG]], %[[loaded_value]] : i32
!CHECK: acc.yield %[[result]] : i32
!CHECK: }
!CHECK: acc.atomic.read %[[loaded_B_addr]] = %[[loaded_A_addr]] : !fir.ptr<i32>, i32
!CHECK: acc.atomic.read %[[loaded_B_addr]] = %[[loaded_A_addr]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
!CHECK: }
integer, pointer :: a, b
integer, target :: c, d
Expand Down Expand Up @@ -118,10 +118,99 @@ subroutine capture_with_convert_f32_to_i32()
! CHECK: %[[MUL:.*]] = arith.mulf %{{.*}}, %[[CST]] fastmath<contract> : f32
! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f32) -> i32
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[K_DECL]]#1 : !fir.ref<i32>, i32
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[K_DECL]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
! CHECK: acc.atomic.write %[[K_DECL]]#1 = %[[CONV]] : !fir.ref<i32>, i32
! CHECK: }

subroutine capture_with_convert_i32_to_f64()
real(8) :: x
integer :: v
x = 1.0
v = 0
!$acc atomic capture
v = x
x = v
!$acc end atomic
end subroutine capture_with_convert_i32_to_f64

! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f64()
! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"}
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[X:.*]] = fir.alloca f64 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"}
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f64Ex"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f64
! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f64, !fir.ref<f64>
! CHECK: %c0_i32 = arith.constant 0 : i32
! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f64
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f64>, f64
! CHECK: acc.atomic.write %[[X_DECL]]#1 = %[[CONV]] : !fir.ref<f64>, f64
! CHECK: }

subroutine capture_with_convert_f64_to_i32()
integer :: x
real(8) :: v
x = 1
v = 0
!$acc atomic capture
x = v * v
v = x
!$acc end atomic
end subroutine capture_with_convert_f64_to_i32

! CHECK-LABEL: func.func @_QPcapture_with_convert_f64_to_i32()
! CHECK: %[[V:.*]] = fir.alloca f64 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"}
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ev"} : (!fir.ref<f64>) -> (!fir.ref<f64>, !fir.ref<f64>)
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"}
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_f64_to_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %c1_i32 = arith.constant 1 : i32
! CHECK: hlfir.assign %c1_i32 to %[[X_DECL]]#0 : i32, !fir.ref<i32>
! CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f64
! CHECK: hlfir.assign %[[CST]] to %[[V_DECL]]#0 : f64, !fir.ref<f64>
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<f64>
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.update %[[X_DECL]]#1 : !fir.ref<i32> {
! CHECK: ^bb0(%arg0: i32):
! CHECK: %[[MUL:.*]] = arith.mulf %[[LOAD]], %[[LOAD]] fastmath<contract> : f64
! CHECK: %[[CONV:.*]] = fir.convert %[[MUL]] : (f64) -> i32
! CHECK: acc.yield %[[CONV]] : i32
! CHECK: }
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<f64>, !fir.ref<i32>, i32
! CHECK: }

subroutine capture_with_convert_i32_to_f32()
real(4) :: x
integer :: v
x = 1.0
v = 0
!$acc atomic capture
v = x
x = x + v
!$acc end atomic
end subroutine capture_with_convert_i32_to_f32

! CHECK-LABEL: func.func @_QPcapture_with_convert_i32_to_f32()
! CHECK: %[[V:.*]] = fir.alloca i32 {bindc_name = "v", uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"}
! CHECK: %[[V_DECL:.*]]:2 = hlfir.declare %[[V]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ev"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[X:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"}
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcapture_with_convert_i32_to_f32Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[CST:.*]] = arith.constant 1.000000e+00 : f32
! CHECK: hlfir.assign %[[CST]] to %[[X_DECL]]#0 : f32, !fir.ref<f32>
! CHECK: %c0_i32 = arith.constant 0 : i32
! CHECK: hlfir.assign %c0_i32 to %[[V_DECL]]#0 : i32, !fir.ref<i32>
! CHECK: %[[LOAD:.*]] = fir.load %[[V_DECL]]#0 : !fir.ref<i32>
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i32>, !fir.ref<f32>, f32
! CHECK: acc.atomic.update %[[X_DECL]]#1 : !fir.ref<f32> {
! CHECK: ^bb0(%arg0: f32):
! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (i32) -> f32
! CHECK: %[[ADD:.*]] = arith.addf %arg0, %[[CONV]] fastmath<contract> : f32
! CHECK: acc.yield %[[ADD]] : f32
! CHECK: }
! CHECK: }

subroutine array_ref_in_atomic_capture1
integer :: x(10), v
!$acc atomic capture
Expand All @@ -136,7 +225,7 @@ end subroutine array_ref_in_atomic_capture1
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]](%{{.*}}) {uniq_name = "_QFarray_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
! CHECK: %[[X_REF:.*]] = hlfir.designate %[[X_DECL]]#0 (%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, i32
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
! CHECK: acc.atomic.update %[[X_REF]] : !fir.ref<i32> {
! CHECK: ^bb0(%[[VAL_7:.*]]: i32):
! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
Expand All @@ -163,7 +252,7 @@ end subroutine array_ref_in_atomic_capture2
! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %{{.*}} : i32
! CHECK: acc.yield %[[VAL_8]] : i32
! CHECK: }
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, i32
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[X_REF]] : !fir.ref<i32>, !fir.ref<i32>, i32
! CHECK: }

subroutine comp_ref_in_atomic_capture1
Expand All @@ -184,7 +273,7 @@ end subroutine comp_ref_in_atomic_capture1
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFcomp_ref_in_atomic_capture1Ex"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>, !fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>)
! CHECK: %[[C:.*]] = hlfir.designate %[[X_DECL]]#0{"c"} : (!fir.ref<!fir.type<_QFcomp_ref_in_atomic_capture1Tt1{c:i32}>>) -> !fir.ref<i32>
! CHECK: acc.atomic.capture {
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, i32
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
! CHECK: acc.atomic.update %[[C]] : !fir.ref<i32> {
! CHECK: ^bb0(%[[VAL_5:.*]]: i32):
! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
Expand Down Expand Up @@ -215,5 +304,5 @@ end subroutine comp_ref_in_atomic_capture2
! CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %{{.*}} : i32
! CHECK: acc.yield %[[VAL_6]] : i32
! CHECK: }
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, i32
! CHECK: acc.atomic.read %[[V_DECL]]#1 = %[[C]] : !fir.ref<i32>, !fir.ref<i32>, i32
! CHECK: }
19 changes: 9 additions & 10 deletions flang/test/Lower/OpenACC/acc-atomic-read.f90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ end program acc_atomic_test
! CHECK: %[[G_DECL:.*]]:2 = hlfir.declare %[[VAR_G]] {uniq_name = "_QFEg"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[VAR_H:.*]] = fir.alloca f32 {bindc_name = "h", uniq_name = "_QFEh"}
! CHECK: %[[H_DECL:.*]]:2 = hlfir.declare %[[VAR_H]] {uniq_name = "_QFEh"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: acc.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, f32
! CHECK: acc.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, !fir.ref<f32>, f32
! CHECK: return
! CHECK: }

Expand All @@ -39,21 +39,20 @@ subroutine atomic_read_pointer()
! CHECK: %[[BOX_ADDR_X:.*]] = fir.box_addr %[[LOAD_X]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[LOAD_Y:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[BOX_ADDR_Y:.*]] = fir.box_addr %[[LOAD_Y]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: acc.atomic.read %[[BOX_ADDR_Y]] = %[[BOX_ADDR_X]] : !fir.ptr<i32>, i32
! CHECK: acc.atomic.read %[[BOX_ADDR_Y]] = %[[BOX_ADDR_X]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
! CHECK: }

subroutine atomic_read_with_convert()
subroutine atomic_read_with_cast()
integer(4) :: x
integer(8) :: y

!$acc atomic read
y = x
end

! CHECK-LABEL: func.func @_QPatomic_read_with_convert() {
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_convertEx"}
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_convertEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_convertEy"}
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_convertEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[CONV:.*]] = fir.convert %[[X_DECL]]#1 : (!fir.ref<i32>) -> !fir.ref<i64>
! CHECK: acc.atomic.read %[[Y_DECL]]#1 = %[[CONV]] : !fir.ref<i64>, i32
! CHECK-LABEL: func.func @_QPatomic_read_with_cast() {
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFatomic_read_with_castEx"}
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFatomic_read_with_castEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[Y:.*]] = fir.alloca i64 {bindc_name = "y", uniq_name = "_QFatomic_read_with_castEy"}
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFatomic_read_with_castEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: acc.atomic.read %[[Y_DECL]]#1 = %[[X_DECL]]#1 : !fir.ref<i64>, !fir.ref<i32>, i32
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenACC/acc-atomic-update-array.f90
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ subroutine atomic_read_array1(r, n, x)
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %{{[0-9]+}} {uniq_name = "_QFatomic_read_array1Ex"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %[[DECL_R:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} {uniq_name = "_QFatomic_read_array1Er"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
! CHECK: %[[DES:.*]] = hlfir.designate %[[DECL_R]]#0 (%{{.*}}) : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
! CHECK: acc.atomic.read %[[DECL_X]]#1 = %[[DES]] : !fir.ref<f32>, f32
! CHECK: acc.atomic.read %[[DECL_X]]#1 = %[[DES]] : !fir.ref<f32>, !fir.ref<f32>, f32

subroutine atomic_write_array1(r, n, x)
implicit none
Expand Down Expand Up @@ -88,5 +88,5 @@ subroutine atomic_capture_array1(r, n, x, y)
! CHECK: %[[ADD:.*]] = arith.addf %[[ARG]], %[[LOAD]] fastmath<contract> : f32
! CHECK: acc.yield %[[ADD]] : f32
! CHECK: }
! CHECK: acc.atomic.read %[[DECL_Y]]#1 = %[[R_I]] : !fir.ref<f32>, f32
! CHECK: acc.atomic.read %[[DECL_Y]]#1 = %[[R_I]] : !fir.ref<f32>, !fir.ref<f32>, f32
! CHECK: }
11 changes: 11 additions & 0 deletions flang/test/Lower/OpenMP/Todo/depend-clause-inoutset.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
!RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s
!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s

!CHECK: not yet implemented: INOUTSET and MUTEXINOUTSET are not supported yet
subroutine f00(x)
integer :: x
!$omp task depend(inoutset: x)
x = x + 1
!$omp end task
end

11 changes: 11 additions & 0 deletions flang/test/Lower/OpenMP/Todo/depend-clause-mutexinoutset.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
!RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s
!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -o - %s 2>&1 | FileCheck %s

!CHECK: not yet implemented: INOUTSET and MUTEXINOUTSET are not supported yet
subroutine f00(x)
integer :: x
!$omp task depend(mutexinoutset: x)
x = x + 1
!$omp end task
end

4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/Todo/task_detach.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
! RUN: %not_todo_cmd bbc -emit-fir %openmp_flags -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-fir %openmp_flags -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s

!===============================================================================
! `detach` clause
Expand Down
6 changes: 3 additions & 3 deletions flang/test/Lower/OpenMP/atomic-capture.f90
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ program OmpAtomicCapture
!CHECK: %[[TEMP:.*]] = arith.muli %[[VAL_Y_LOADED]], %[[ARG]] : i32
!CHECK: omp.yield(%[[TEMP]] : i32)
!CHECK: }
!CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[VAL_Y_DECLARE]]#1 : !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[VAL_Y_DECLARE]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: }
!$omp atomic hint(omp_sync_hint_uncontended) capture
y = x * y
Expand All @@ -36,7 +36,7 @@ program OmpAtomicCapture
!CHECK: %[[NO_REASSOC:.*]] = hlfir.no_reassoc %[[SUB]] : i32
!CHECK: %[[ADD:.*]] = arith.addi %[[VAL_20]], %[[NO_REASSOC]] : i32
!CHECK: omp.atomic.capture hint(nonspeculative) memory_order(acquire) {
!CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[VAL_Y_DECLARE]]#1 : !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[VAL_X_DECLARE]]#1 = %[[VAL_Y_DECLARE]]#1 : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: omp.atomic.write %[[VAL_Y_DECLARE]]#1 = %[[ADD]] : !fir.ref<i32>, i32
!CHECK: }
!CHECK: return
Expand Down Expand Up @@ -88,7 +88,7 @@ subroutine pointers_in_atomic_capture()
!CHECK: %[[TEMP:.*]] = arith.addi %[[ARG]], %[[VAL_B]] : i32
!CHECK: omp.yield(%[[TEMP]] : i32)
!CHECK: }
!CHECK: omp.atomic.read %[[VAL_B_BOX_ADDR]] = %[[VAL_A_BOX_ADDR]] : !fir.ptr<i32>, i32
!CHECK: omp.atomic.read %[[VAL_B_BOX_ADDR]] = %[[VAL_A_BOX_ADDR]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
!CHECK: }
!CHECK: return
!CHECK: }
Expand Down
14 changes: 7 additions & 7 deletions flang/test/Lower/OpenMP/atomic-read.f90
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
!CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X_REF]] {uniq_name = "_QFEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: %[[Y_REF:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
!CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y_REF]] {uniq_name = "_QFEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: omp.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 hint(uncontended) memory_order(acquire) : !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[A_DECL]]#1 = %[[B_DECL]]#1 memory_order(relaxed) : !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[C_DECL]]#1 = %[[D_DECL]]#1 hint(contended) memory_order(seq_cst) : !fir.ref<!fir.logical<4>>, !fir.logical<4>
!CHECK: omp.atomic.read %[[E_DECL]]#1 = %[[F_DECL]]#1 hint(speculative) : !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 hint(nonspeculative) : !fir.ref<f32>, f32
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, f32
!CHECK: omp.atomic.read %[[X_DECL]]#1 = %[[Y_DECL]]#1 hint(uncontended) memory_order(acquire) : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[A_DECL]]#1 = %[[B_DECL]]#1 memory_order(relaxed) : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[C_DECL]]#1 = %[[D_DECL]]#1 hint(contended) memory_order(seq_cst) : !fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, !fir.logical<4>
!CHECK: omp.atomic.read %[[E_DECL]]#1 = %[[F_DECL]]#1 hint(speculative) : !fir.ref<i32>, !fir.ref<i32>, i32
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 hint(nonspeculative) : !fir.ref<f32>, !fir.ref<f32>, f32
!CHECK: omp.atomic.read %[[G_DECL]]#1 = %[[H_DECL]]#1 : !fir.ref<f32>, !fir.ref<f32>, f32

program OmpAtomic

Expand Down Expand Up @@ -68,7 +68,7 @@ end program OmpAtomic
!CHECK: %[[X_POINTEE_ADDR:.*]] = fir.box_addr %[[X_ADDR]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
!CHECK: %[[Y_ADDR:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
!CHECK: %[[Y_POINTEE_ADDR:.*]] = fir.box_addr %[[Y_ADDR]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
!CHECK: omp.atomic.read %[[Y_POINTEE_ADDR]] = %[[X_POINTEE_ADDR]] : !fir.ptr<i32>, i32
!CHECK: omp.atomic.read %[[Y_POINTEE_ADDR]] = %[[X_POINTEE_ADDR]] : !fir.ptr<i32>, !fir.ptr<i32>, i32
!CHECK: %[[Y_ADDR:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
!CHECK: %[[Y_POINTEE_ADDR:.*]] = fir.box_addr %[[Y_ADDR]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
!CHECK: %[[Y_POINTEE_VAL:.*]] = fir.load %[[Y_POINTEE_ADDR]] : !fir.ptr<i32>
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Parser/OpenMP/task.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case %s
! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="CHECK-UNPARSE" %s
! RUN: %flang_fc1 %openmp_flags -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case %s
! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="CHECK-UNPARSE" %s

!CHECK: OmpBlockDirective -> llvm::omp::Directive = task
!CHECK: OmpClauseList -> OmpClause -> Detach -> OmpDetachClause -> OmpObject -> Designator -> DataRef -> Name = 'event'
Expand Down
17 changes: 17 additions & 0 deletions flang/test/Semantics/OpenMP/depend06.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror

subroutine f00(x)
integer :: x
!WARNING: INOUTSET task-dependence-type is not supported in OpenMP v4.5, try -fopenmp-version=52
!$omp task depend(inoutset: x)
x = x + 1
!$omp end task
end

subroutine f01(x)
integer :: x
!WARNING: MUTEXINOUTSET task-dependence-type is not supported in OpenMP v4.5, try -fopenmp-version=50
!$omp task depend(mutexinoutset: x)
x = x + 1
!$omp end task
end
2 changes: 1 addition & 1 deletion flang/test/Semantics/OpenMP/depobj-construct-v52.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

subroutine f00
integer :: obj
!WARNING: The SOURCE task-dependence-type is deprecated in OpenMP v5.2
!WARNING: SOURCE task-dependence-type is deprecated in OpenMP v5.2
!ERROR: A DEPEND clause on a DEPOBJ construct must not have SOURCE or SINK as dependence-type
!$omp depobj(obj) depend(source)
end
Expand Down
2 changes: 1 addition & 1 deletion libc/newhdrgen/yaml_to_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def main():
args = parser.parse_args()

if args.add_function:
add_function_to_yaml(yaml_file, args.add_function)
add_function_to_yaml(args.yaml_file, args.add_function)

header_class = GpuHeader if args.export_decls else HeaderFile
header = load_yaml_file(args.yaml_file, header_class, args.entry_points)
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_shift`` ``201806L``
---------------------------------------------------------- -----------------
``__cpp_lib_smart_ptr_for_overwrite`` *unimplemented*
``__cpp_lib_smart_ptr_for_overwrite`` ``202002L``
---------------------------------------------------------- -----------------
``__cpp_lib_source_location`` ``201907L``
---------------------------------------------------------- -----------------
Expand Down
4 changes: 2 additions & 2 deletions libcxx/docs/Status/Cxx20Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"`P0972R0 <https://wg21.link/P0972R0>`__","<chrono> ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","2018-11 (San Diego)","|Complete|","8",""
"`P1006R1 <https://wg21.link/P1006R1>`__","Constexpr in std::pointer_traits","2018-11 (San Diego)","|Complete|","8",""
"`P1007R3 <https://wg21.link/P1007R3>`__","``std::assume_aligned``\ ","2018-11 (San Diego)","|Complete|","15",""
"`P1020R1 <https://wg21.link/P1020R1>`__","Smart pointer creation with default initialization","2018-11 (San Diego)","|Complete|","16",""
"`P1020R1 <https://wg21.link/P1020R1>`__","Smart pointer creation with default initialization","2018-11 (San Diego)","|Complete|","16","The feature-test macro was not set until LLVM 20."
"`P1032R1 <https://wg21.link/P1032R1>`__","Misc constexpr bits","2018-11 (San Diego)","|Complete|","13",""
"`P1085R2 <https://wg21.link/P1085R2>`__","Should Span be Regular?","2018-11 (San Diego)","|Complete|","8",""
"`P1123R0 <https://wg21.link/P1123R0>`__","Editorial Guidance for merging P0019r8 and P0528r3","2018-11 (San Diego)","","",""
Expand Down Expand Up @@ -177,7 +177,7 @@
"`P1963R0 <https://wg21.link/P1963R0>`__","Fixing US 313","2020-02 (Prague)","","",""
"`P1964R2 <https://wg21.link/P1964R2>`__","Wording for boolean-testable","2020-02 (Prague)","|Complete|","13",""
"`P1970R2 <https://wg21.link/P1970R2>`__","Consistency for size() functions: Add ranges::ssize","2020-02 (Prague)","|Complete|","15",""
"`P1973R1 <https://wg21.link/P1973R1>`__","Rename ""_default_init"" Functions, Rev1","2020-02 (Prague)","|Complete|","16",""
"`P1973R1 <https://wg21.link/P1973R1>`__","Rename ""_default_init"" Functions, Rev1","2020-02 (Prague)","|Complete|","16","The feature-test macro was not set until LLVM 20."
"`P1976R2 <https://wg21.link/P1976R2>`__","Fixed-size span construction from dynamic range","2020-02 (Prague)","|Complete|","11",""
"`P1981R0 <https://wg21.link/P1981R0>`__","Rename leap to leap_second","2020-02 (Prague)","|Complete|","19",""
"`P1982R0 <https://wg21.link/P1982R0>`__","Rename link to time_zone_link","2020-02 (Prague)","|Complete|","19",""
Expand Down
114 changes: 54 additions & 60 deletions libcxx/include/__split_buffer
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,6 @@ public:

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __alloc_; }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT { return __alloc_; }

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_; }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT { return __end_cap_; }

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }

Expand All @@ -129,15 +123,15 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
return static_cast<size_type>(__end_cap() - __first_);
return static_cast<size_type>(__end_cap_ - __first_);
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
return static_cast<size_type>(__begin_ - __first_);
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
return static_cast<size_type>(__end_cap() - __end_);
return static_cast<size_type>(__end_cap_ - __end_);
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
Expand Down Expand Up @@ -196,7 +190,7 @@ public:
private:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
__alloc() = std::move(__c.__alloc());
__alloc_ = std::move(__c.__alloc_);
}

_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
Expand Down Expand Up @@ -225,14 +219,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __split_buffer<_Tp, _Allocator>::__invariants
return false;
if (__end_ != nullptr)
return false;
if (__end_cap() != nullptr)
if (__end_cap_ != nullptr)
return false;
} else {
if (__begin_ < __first_)
return false;
if (__end_ < __begin_)
return false;
if (__end_cap() < __end_)
if (__end_cap_ < __end_)
return false;
}
return true;
Expand All @@ -247,7 +241,7 @@ template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) {
_ConstructTransaction __tx(&this->__end_, __n);
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
__alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_));
__alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_));
}
}

Expand All @@ -262,7 +256,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
_ConstructTransaction __tx(&this->__end_, __n);
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
__alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), __x);
__alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), __x);
}
}

Expand All @@ -277,14 +271,14 @@ template <class _Tp, class _Allocator>
template <class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void
__split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
__alloc_rr& __a = this->__alloc();
__alloc_rr& __a = __alloc_;
for (; __first != __last; ++__first) {
if (__end_ == __end_cap()) {
size_type __old_cap = __end_cap() - __first_;
if (__end_ == __end_cap_) {
size_type __old_cap = __end_cap_ - __first_;
size_type __new_cap = std::max<size_type>(2 * __old_cap, 8);
__split_buffer __buf(__new_cap, 0, __a);
for (pointer __p = __begin_; __p != __end_; ++__p, (void)++__buf.__end_)
__alloc_traits::construct(__buf.__alloc(), std::__to_address(__buf.__end_), std::move(*__p));
__alloc_traits::construct(__buf.__alloc_, std::__to_address(__buf.__end_), std::move(*__p));
swap(__buf);
}
__alloc_traits::construct(__a, std::__to_address(this->__end_), *__first);
Expand All @@ -304,15 +298,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
_ConstructTransaction __tx(&this->__end_, __n);
for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__first) {
__alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), *__first);
__alloc_traits::construct(__alloc_, std::__to_address(__tx.__pos_), *__first);
}
}

template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) {
while (__begin_ != __new_begin)
__alloc_traits::destroy(__alloc(), std::__to_address(__begin_++));
__alloc_traits::destroy(__alloc_, std::__to_address(__begin_++));
}

template <class _Tp, class _Allocator>
Expand All @@ -325,7 +319,7 @@ template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT {
while (__new_last != __end_)
__alloc_traits::destroy(__alloc(), std::__to_address(--__end_));
__alloc_traits::destroy(__alloc_, std::__to_address(--__end_));
}

template <class _Tp, class _Allocator>
Expand All @@ -341,19 +335,19 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __sta
if (__cap == 0) {
__first_ = nullptr;
} else {
auto __allocation = std::__allocate_at_least(__alloc(), __cap);
auto __allocation = std::__allocate_at_least(__alloc_, __cap);
__first_ = __allocation.ptr;
__cap = __allocation.count;
}
__begin_ = __end_ = __first_ + __start;
__end_cap() = __first_ + __cap;
__end_cap_ = __first_ + __cap;
}

template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::~__split_buffer() {
clear();
if (__first_)
__alloc_traits::deallocate(__alloc(), __first_, capacity());
__alloc_traits::deallocate(__alloc_, __first_, capacity());
}

template <class _Tp, class _Allocator>
Expand All @@ -364,30 +358,30 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::__split_buffer(__
__end_(std::move(__c.__end_)),
__end_cap_(std::move(__c.__end_cap_)),
__alloc_(std::move(__c.__alloc_)) {
__c.__first_ = nullptr;
__c.__begin_ = nullptr;
__c.__end_ = nullptr;
__c.__end_cap() = nullptr;
__c.__first_ = nullptr;
__c.__begin_ = nullptr;
__c.__end_ = nullptr;
__c.__end_cap_ = nullptr;
}

template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20
__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
: __end_cap_(nullptr), __alloc_(__a) {
if (__a == __c.__alloc()) {
__first_ = __c.__first_;
__begin_ = __c.__begin_;
__end_ = __c.__end_;
__end_cap() = __c.__end_cap();
__c.__first_ = nullptr;
__c.__begin_ = nullptr;
__c.__end_ = nullptr;
__c.__end_cap() = nullptr;
if (__a == __c.__alloc_) {
__first_ = __c.__first_;
__begin_ = __c.__begin_;
__end_ = __c.__end_;
__end_cap_ = __c.__end_cap_;
__c.__first_ = nullptr;
__c.__begin_ = nullptr;
__c.__end_ = nullptr;
__c.__end_cap_ = nullptr;
} else {
auto __allocation = std::__allocate_at_least(__alloc(), __c.size());
auto __allocation = std::__allocate_at_least(__alloc_, __c.size());
__first_ = __allocation.ptr;
__begin_ = __end_ = __first_;
__end_cap() = __first_ + __allocation.count;
__end_cap_ = __first_ + __allocation.count;
typedef move_iterator<iterator> _Ip;
__construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
}
Expand All @@ -401,12 +395,12 @@ __split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
!__alloc_traits::propagate_on_container_move_assignment::value) {
clear();
shrink_to_fit();
__first_ = __c.__first_;
__begin_ = __c.__begin_;
__end_ = __c.__end_;
__end_cap() = __c.__end_cap();
__first_ = __c.__first_;
__begin_ = __c.__begin_;
__end_ = __c.__end_;
__end_cap_ = __c.__end_cap_;
__move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
__c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
__c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap_ = nullptr;
return *this;
}

Expand All @@ -416,19 +410,19 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::swap(__split
std::swap(__first_, __x.__first_);
std::swap(__begin_, __x.__begin_);
std::swap(__end_, __x.__end_);
std::swap(__end_cap(), __x.__end_cap());
std::__swap_allocator(__alloc(), __x.__alloc());
std::swap(__end_cap_, __x.__end_cap_);
std::__swap_allocator(__alloc_, __x.__alloc_);
}

template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::reserve(size_type __n) {
if (__n < capacity()) {
__split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
__split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc_);
__t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
std::swap(__first_, __t.__first_);
std::swap(__begin_, __t.__begin_);
std::swap(__end_, __t.__end_);
std::swap(__end_cap(), __t.__end_cap());
std::swap(__end_cap_, __t.__end_cap_);
}
}

Expand All @@ -438,13 +432,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fi
#if _LIBCPP_HAS_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_EXCEPTIONS
__split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
__split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc_);
__t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
__t.__end_ = __t.__begin_ + (__end_ - __begin_);
std::swap(__first_, __t.__first_);
std::swap(__begin_, __t.__begin_);
std::swap(__end_, __t.__end_);
std::swap(__end_cap(), __t.__end_cap());
std::swap(__end_cap_, __t.__end_cap_);
#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
}
Expand All @@ -456,45 +450,45 @@ template <class _Tp, class _Allocator>
template <class... _Args>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_front(_Args&&... __args) {
if (__begin_ == __first_) {
if (__end_ < __end_cap()) {
difference_type __d = __end_cap() - __end_;
if (__end_ < __end_cap_) {
difference_type __d = __end_cap_ - __end_;
__d = (__d + 1) / 2;
__begin_ = std::move_backward(__begin_, __end_, __end_ + __d);
__end_ += __d;
} else {
size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap_ - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc_);
__t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
std::swap(__first_, __t.__first_);
std::swap(__begin_, __t.__begin_);
std::swap(__end_, __t.__end_);
std::swap(__end_cap(), __t.__end_cap());
std::swap(__end_cap_, __t.__end_cap_);
}
}
__alloc_traits::construct(__alloc(), std::__to_address(__begin_ - 1), std::forward<_Args>(__args)...);
__alloc_traits::construct(__alloc_, std::__to_address(__begin_ - 1), std::forward<_Args>(__args)...);
--__begin_;
}

template <class _Tp, class _Allocator>
template <class... _Args>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
if (__end_ == __end_cap()) {
if (__end_ == __end_cap_) {
if (__begin_ > __first_) {
difference_type __d = __begin_ - __first_;
__d = (__d + 1) / 2;
__end_ = std::move(__begin_, __end_, __begin_ - __d);
__begin_ -= __d;
} else {
size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap_ - __first_), 1);
__split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc_);
__t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
std::swap(__first_, __t.__first_);
std::swap(__begin_, __t.__begin_);
std::swap(__end_, __t.__end_);
std::swap(__end_cap(), __t.__end_cap());
std::swap(__end_cap_, __t.__end_cap_);
}
}
__alloc_traits::construct(__alloc(), std::__to_address(__end_), std::forward<_Args>(__args)...);
__alloc_traits::construct(__alloc_, std::__to_address(__end_), std::forward<_Args>(__args)...);
++__end_;
}

Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__vector/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
__end_ = __begin_; // All the objects have been destroyed by relocating them.
std::swap(this->__begin_, __v.__begin_);
std::swap(this->__end_, __v.__end_);
std::swap(this->__end_cap(), __v.__end_cap());
std::swap(this->__end_cap(), __v.__end_cap_);
__v.__first_ = __v.__begin_;
__annotate_new(size());
}
Expand Down Expand Up @@ -852,7 +852,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a

std::swap(this->__begin_, __v.__begin_);
std::swap(this->__end_, __v.__end_);
std::swap(this->__end_cap(), __v.__end_cap());
std::swap(this->__end_cap(), __v.__end_cap_);
__v.__first_ = __v.__begin_;
__annotate_new(size());
return __ret;
Expand Down
22 changes: 11 additions & 11 deletions libcxx/include/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1229,8 +1229,8 @@ private:
clear();
shrink_to_fit();
}
__alloc() = __c.__alloc();
__map_.__alloc() = __c.__map_.__alloc();
__alloc() = __c.__alloc();
__map_.__alloc_ = __c.__map_.__alloc_;
}

_LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const deque&, false_type) {}
Expand Down Expand Up @@ -1309,7 +1309,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c)
: __map_(__pointer_allocator(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))),
__start_(0),
__size_(0),
__alloc_(__map_.__alloc()) {
__alloc_(__map_.__alloc_) {
__annotate_new(0);
__append(__c.begin(), __c.end());
}
Expand Down Expand Up @@ -2061,7 +2061,7 @@ void deque<_Tp, _Allocator>::__add_front_capacity() {
// Else need to allocate 1 buffer, *and* we need to reallocate __map_.
else {
__split_buffer<pointer, __pointer_allocator&> __buf(
std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc());
std::max<size_type>(2 * __map_.capacity(), 1), 0, __map_.__alloc_);

typedef __allocator_destructor<_Allocator> _Dp;
unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));
Expand All @@ -2073,7 +2073,7 @@ void deque<_Tp, _Allocator>::__add_front_capacity() {
std::swap(__map_.__first_, __buf.__first_);
std::swap(__map_.__begin_, __buf.__begin_);
std::swap(__map_.__end_, __buf.__end_);
std::swap(__map_.__end_cap(), __buf.__end_cap());
std::swap(__map_.__end_cap_, __buf.__end_cap_);
__start_ = __map_.size() == 1 ? __block_size / 2 : __start_ + __block_size;
}
__annotate_whole_block(0, __asan_poison);
Expand Down Expand Up @@ -2124,7 +2124,7 @@ void deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) {
else {
size_type __ds = (__nb + __back_capacity) * __block_size - __map_.empty();
__split_buffer<pointer, __pointer_allocator&> __buf(
std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc());
std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()), 0, __map_.__alloc_);
#if _LIBCPP_HAS_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_EXCEPTIONS
Expand All @@ -2150,7 +2150,7 @@ void deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) {
std::swap(__map_.__first_, __buf.__first_);
std::swap(__map_.__begin_, __buf.__begin_);
std::swap(__map_.__end_, __buf.__end_);
std::swap(__map_.__end_cap(), __buf.__end_cap());
std::swap(__map_.__end_cap_, __buf.__end_cap_);
__start_ += __ds;
}
}
Expand Down Expand Up @@ -2184,7 +2184,7 @@ void deque<_Tp, _Allocator>::__add_back_capacity() {
// Else need to allocate 1 buffer, *and* we need to reallocate __map_.
else {
__split_buffer<pointer, __pointer_allocator&> __buf(
std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc());
std::max<size_type>(2 * __map_.capacity(), 1), __map_.size(), __map_.__alloc_);

typedef __allocator_destructor<_Allocator> _Dp;
unique_ptr<pointer, _Dp> __hold(__alloc_traits::allocate(__a, __block_size), _Dp(__a, __block_size));
Expand All @@ -2196,7 +2196,7 @@ void deque<_Tp, _Allocator>::__add_back_capacity() {
std::swap(__map_.__first_, __buf.__first_);
std::swap(__map_.__begin_, __buf.__begin_);
std::swap(__map_.__end_, __buf.__end_);
std::swap(__map_.__end_cap(), __buf.__end_cap());
std::swap(__map_.__end_cap_, __buf.__end_cap_);
__annotate_whole_block(__map_.size() - 1, __asan_poison);
}
}
Expand Down Expand Up @@ -2249,7 +2249,7 @@ void deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) {
__split_buffer<pointer, __pointer_allocator&> __buf(
std::max<size_type>(2 * __map_.capacity(), __nb + __map_.size()),
__map_.size() - __front_capacity,
__map_.__alloc());
__map_.__alloc_);
#if _LIBCPP_HAS_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_EXCEPTIONS
Expand All @@ -2275,7 +2275,7 @@ void deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) {
std::swap(__map_.__first_, __buf.__first_);
std::swap(__map_.__begin_, __buf.__begin_);
std::swap(__map_.__end_, __buf.__end_);
std::swap(__map_.__end_cap(), __buf.__end_cap());
std::swap(__map_.__end_cap_, __buf.__end_cap_);
__start_ -= __ds;
}
}
Expand Down
9 changes: 3 additions & 6 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,8 @@ private:
size_type __guess = __align_it<__boundary>(__s + 1) - 1;
if (__guess == __min_cap)
__guess += __endian_factor;

_LIBCPP_ASSERT_INTERNAL(__guess >= __s, "recommendation is below the requested size");
return __guess;
}

Expand Down Expand Up @@ -3346,12 +3348,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
if (__requested_capacity <= capacity())
return;

size_type __target_capacity = std::max(__requested_capacity, size());
__target_capacity = __recommend(__target_capacity);
if (__target_capacity == capacity())
return;

__shrink_or_extend(__target_capacity);
__shrink_or_extend(__recommend(__requested_capacity));
}

template <class _CharT, class _Traits, class _Allocator>
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ __cpp_lib_void_t 201411L <type_traits>
# undef __cpp_lib_shared_ptr_arrays
# define __cpp_lib_shared_ptr_arrays 201707L
# define __cpp_lib_shift 201806L
// # define __cpp_lib_smart_ptr_for_overwrite 202002L
# define __cpp_lib_smart_ptr_for_overwrite 202002L
# define __cpp_lib_source_location 201907L
# define __cpp_lib_span 202002L
# define __cpp_lib_ssize 201902L
Expand Down
6 changes: 3 additions & 3 deletions libcxx/test/benchmarks/CartesianBenchmarks.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ constexpr auto makeEnumValueTuple(std::index_sequence<Idxs...>) {
}

template <class B>
static auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
auto skip(const B& Bench, int) -> decltype(Bench.skip()) {
return Bench.skip();
}
template <class B>
static auto skip(const B& Bench, char) {
auto skip(const B&, char) {
return false;
}

Expand All @@ -51,7 +51,7 @@ void makeBenchmarkFromValues(const std::vector<std::tuple<Args...> >& A) {
}

template <template <class...> class B, class Args, class... U>
void makeBenchmarkImpl(const Args& A, std::tuple<U...> t) {
void makeBenchmarkImpl(const Args& A, std::tuple<U...>) {
makeBenchmarkFromValues<B<U...> >(A);
}

Expand Down
10 changes: 5 additions & 5 deletions libcxx/test/benchmarks/ContainerBenchmarks.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void BM_EmplaceDuplicate(benchmark::State& st, Container c, GenInputs gen) {
}

template <class Container, class GenInputs>
static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
auto in = gen(st.range(0));
c.insert(in.begin(), in.end());
benchmark::DoNotOptimize(&(*c.begin()));
Expand All @@ -164,7 +164,7 @@ static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
}

template <class Container, class GenInputs>
static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {
void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {
c.rehash(8);
auto in = gen(st.range(0));
c.insert(in.begin(), in.end());
Expand All @@ -179,7 +179,7 @@ static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {
}

template <class Container, class GenInputs>
static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) {
void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) {
auto in = gen(st.range(0));
c.max_load_factor(3.0);
c.insert(in.begin(), in.end());
Expand All @@ -193,7 +193,7 @@ static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) {
}

template <class Container, class GenInputs>
static void BM_Compare_same_container(benchmark::State& st, Container, GenInputs gen) {
void BM_Compare_same_container(benchmark::State& st, Container, GenInputs gen) {
auto in = gen(st.range(0));
Container c1(in.begin(), in.end());
Container c2 = c1;
Expand All @@ -208,7 +208,7 @@ static void BM_Compare_same_container(benchmark::State& st, Container, GenInputs
}

template <class Container, class GenInputs>
static void BM_Compare_different_containers(benchmark::State& st, Container, GenInputs gen) {
void BM_Compare_different_containers(benchmark::State& st, Container, GenInputs gen) {
auto in1 = gen(st.range(0));
auto in2 = gen(st.range(0));
Container c1(in1.begin(), in1.end());
Expand Down
2 changes: 1 addition & 1 deletion libcxx/test/benchmarks/VariantBenchmarks.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static auto genVariants(std::index_sequence<Is...>) {

std::array<V, N> result = {};
for (auto& v : result) {
v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)]();
v = fs[getRandomInteger(std::size_t(0), sizeof...(Is) - 1)]();
}

return result;
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms.partition_point.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>
#include <array>
#include <cassert>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/count.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <benchmark/benchmark.h>
#include <cstring>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/equal.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <benchmark/benchmark.h>
#include <vector>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/fill.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

#include <algorithm>
#include <benchmark/benchmark.h>
#include <vector>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/find.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <benchmark/benchmark.h>
#include <cstring>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/for_each.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>
#include <benchmark/benchmark.h>
#include <deque>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <benchmark/benchmark.h>
#include <vector>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/lower_bound.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>
#include <numeric>
#include <random>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/make_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/algorithms/min.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <cassert>

#include <benchmark/benchmark.h>
#include "test_macros.h"

void run_sizes(auto benchmark) {
benchmark->Arg(1)
Expand Down Expand Up @@ -68,7 +71,9 @@ BENCHMARK(BM_std_min<char>)->Apply(run_sizes);
BENCHMARK(BM_std_min<short>)->Apply(run_sizes);
BENCHMARK(BM_std_min<int>)->Apply(run_sizes);
BENCHMARK(BM_std_min<long long>)->Apply(run_sizes);
#ifndef TEST_HAS_NO_INT128
BENCHMARK(BM_std_min<__int128>)->Apply(run_sizes);
#endif
BENCHMARK(BM_std_min<unsigned char>)->Apply(run_sizes);
BENCHMARK(BM_std_min<unsigned short>)->Apply(run_sizes);
BENCHMARK(BM_std_min<unsigned int>)->Apply(run_sizes);
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/min_max_element.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/minmax.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <cassert>

Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/mismatch.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>
#include <benchmark/benchmark.h>
#include <random>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/pop_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
3 changes: 3 additions & 0 deletions libcxx/test/benchmarks/algorithms/pstl.stable_sort.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: libcpp-has-no-incomplete-pstl

#include <algorithm>
#include <execution>

Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/push_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_contains.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

#include <algorithm>
#include <benchmark/benchmark.h>
#include <iterator>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_ends_with.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

#include <algorithm>
#include <benchmark/benchmark.h>
#include <iterator>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_make_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_pop_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_push_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_sort.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/ranges_sort_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/set_intersection.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>
#include <cstdlib>
#include <iterator>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/sort.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/sort_heap.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/algorithms/stable_sort.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <algorithm>

#include "common.h"
Expand Down
11 changes: 10 additions & 1 deletion libcxx/test/benchmarks/allocation.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
//
//===----------------------------------------------------------------------===//

// REQUIRES: -fsized-deallocation
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation

#include "benchmark/benchmark.h"

#include <cassert>
#include <cstdlib>
#include <new>
#include <vector>

#include "test_macros.h"

struct PointerList {
PointerList* Next = nullptr;
};
Expand All @@ -26,6 +32,7 @@ struct NewWrapper {
__attribute__((always_inline)) static void Deallocate(void* P, size_t) { ::operator delete(P); }
};

#ifdef TEST_COMPILER_CLANG
struct BuiltinNewWrapper {
__attribute__((always_inline)) static void* Allocate(size_t N) { return __builtin_operator_new(N); }
__attribute__((always_inline)) static void Deallocate(void* P, size_t) { __builtin_operator_delete(P); }
Expand All @@ -35,6 +42,7 @@ struct BuiltinSizedNewWrapper {
__attribute__((always_inline)) static void* Allocate(size_t N) { return __builtin_operator_new(N); }
__attribute__((always_inline)) static void Deallocate(void* P, size_t N) { __builtin_operator_delete(P, N); }
};
#endif

template <class AllocWrapper>
static void BM_AllocateAndDeallocate(benchmark::State& st) {
Expand Down Expand Up @@ -93,11 +101,12 @@ static int RegisterAllocBenchmarks() {
} TestCases[] = {
{"BM_Malloc", &BM_AllocateAndDeallocate<MallocWrapper>},
{"BM_New", &BM_AllocateAndDeallocate<NewWrapper>},
#ifdef TEST_COMPILER_CLANG
{"BM_BuiltinNewDelete", BM_AllocateAndDeallocate<BuiltinNewWrapper>},
{"BM_BuiltinSizedNewDelete", BM_AllocateAndDeallocate<BuiltinSizedNewWrapper>},
{"BM_BuiltinNewAllocateOnly", BM_AllocateOnly<BuiltinSizedNewWrapper>},
{"BM_BuiltinNewSizedDeallocateOnly", BM_DeallocateOnly<BuiltinSizedNewWrapper>},

#endif
};
for (auto TC : TestCases) {
benchmark::RegisterBenchmark(TC.name, TC.func)->Range(16, 4096 * 2);
Expand Down
3 changes: 3 additions & 0 deletions libcxx/test/benchmarks/atomic_wait.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <atomic>
#include <numeric>
#include <stop_token>
#include <thread>

#include "benchmark/benchmark.h"
Expand Down
3 changes: 3 additions & 0 deletions libcxx/test/benchmarks/atomic_wait_vs_mutex_lock.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// To run this test, build libcxx and cxx-benchmarks targets
// cd third-party/benchmark/tools
// ./compare.py filters ../../../build/libcxx/benchmarks/atomic_wait_vs_mutex_lock.libcxx.out BM_atomic_wait BM_mutex

#include <atomic>
#include <mutex>
#include <numeric>
#include <stop_token>
#include <thread>

#include "benchmark/benchmark.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/deque.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

#include <deque>

#include "benchmark/benchmark.h"
Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/deque_iterator.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <algorithm>
#include <deque>

Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/exception_ptr.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03

#include <benchmark/benchmark.h>
#include <exception>

Expand Down
2 changes: 2 additions & 0 deletions libcxx/test/benchmarks/filesystem.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14

#include <filesystem>

#include "GenerateInput.h"
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/format.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <format>

#include <string>

#include "benchmark/benchmark.h"
#include "make_string.h"
#include "test_macros.h"

#define CSTR(S) MAKE_CSTRING(CharT, S)

Expand All @@ -28,6 +31,8 @@ static void BM_format_string(benchmark::State& state) {
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
}
BENCHMARK(BM_format_string<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
BENCHMARK(BM_format_string<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
#endif

BENCHMARK_MAIN();
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Don't warn about std::sprintf
// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated

#include <array>
#include <charconv>
#include <cstdio>
Expand All @@ -29,7 +34,7 @@ static void BM_sprintf(benchmark::State& state) {
std::array<char, 100> output;
while (state.KeepRunningBatch(data.size()))
for (auto value : data) {
sprintf(output.data(), "%f", value);
std::sprintf(output.data(), "%f", value);
benchmark::DoNotOptimize(output.data());
}
}
Expand Down
7 changes: 6 additions & 1 deletion libcxx/test/benchmarks/format/write_int_comparison.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Don't warn about std::sprintf
// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated

#include <array>
#include <charconv>
#include <cstdio>
Expand All @@ -29,7 +34,7 @@ static void BM_sprintf(benchmark::State& state) {
std::array<char, 100> output;
while (state.KeepRunningBatch(data.size()))
for (auto value : data) {
sprintf(output.data(), "%d", value);
std::sprintf(output.data(), "%d", value);
benchmark::DoNotOptimize(output.data());
}
}
Expand Down
19 changes: 6 additions & 13 deletions libcxx/test/benchmarks/format/write_string_comparison.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

// Don't warn about std::sprintf
// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated

#include <array>
#include <concepts>
#include <cstdio>
Expand Down Expand Up @@ -135,7 +140,7 @@ std::string_view string_view_6000_characters = c_string_6000_characters;
static void BM_sprintf(benchmark::State& state, const char* value) {
std::array<char, 10'000> output;
for (auto _ : state)
benchmark::DoNotOptimize(sprintf(output.data(), "%s", value));
benchmark::DoNotOptimize(std::sprintf(output.data(), "%s", value));
}

template <class T>
Expand Down Expand Up @@ -191,18 +196,6 @@ static void BM_format_to_iterator(benchmark::State& state, const T& value, F&& f
\
/* */

// Verify these types have an iterator that format has optimizations for.
LIBCPP_STATIC_ASSERT(std::same_as<std::array<char, 1>::iterator, char*> || // the type depends on an ABI flag
std::same_as<std::array<char, 1>::iterator, std::__wrap_iter<char*>>);
LIBCPP_STATIC_ASSERT(std::same_as<std::string::iterator, std::__wrap_iter<char*>>);
LIBCPP_STATIC_ASSERT(std::same_as<std::vector<char>::iterator, std::__wrap_iter<char*>>);

// Verify these types have an iterator that format does not optimize for
LIBCPP_STATIC_ASSERT(!std::same_as<std::deque<char>::iterator, char*> &&
!std::same_as<std::deque<char>::iterator, std::__wrap_iter<char*>>);
LIBCPP_STATIC_ASSERT(!std::same_as<std::list<char>::iterator, char*> &&
!std::same_as<std::list<char>::iterator, std::__wrap_iter<char*>>);

BENCHMARK_CAPTURE(BM_sprintf, C_string_len_6, c_string_6_characters);
FORMAT_BENCHMARKS(C_string_len_6, c_string_6_characters)
FORMAT_BENCHMARKS(string_len_6, string_6_characters)
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/format_to.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <format>

#include <algorithm>
Expand All @@ -18,6 +20,7 @@

#include "benchmark/benchmark.h"
#include "make_string.h"
#include "test_macros.h"

#define CSTR(S) MAKE_CSTRING(CharT, S)

Expand Down Expand Up @@ -90,6 +93,7 @@ BENCHMARK(BM_format_to_string_begin<std::list<char>>)->RangeMultiplier(2)->Range
BENCHMARK(BM_format_to_string_span<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_string_pointer<char>)->RangeMultiplier(2)->Range(1, 1 << 20);

#ifndef TEST_HAS_NO_WIDE_CHARACTERS
BENCHMARK(BM_format_to_string_back_inserter<std::wstring>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_string_back_inserter<std::vector<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_string_back_inserter<std::list<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
Expand All @@ -98,5 +102,6 @@ BENCHMARK(BM_format_to_string_begin<std::vector<wchar_t>>)->RangeMultiplier(2)->
BENCHMARK(BM_format_to_string_begin<std::list<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_string_span<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_string_pointer<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
#endif

BENCHMARK_MAIN();
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/format_to_n.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <format>

#include <algorithm>
Expand All @@ -18,6 +20,7 @@

#include "benchmark/benchmark.h"
#include "make_string.h"
#include "test_macros.h"

#define CSTR(S) MAKE_CSTRING(CharT, S)

Expand Down Expand Up @@ -90,6 +93,7 @@ BENCHMARK(BM_format_to_n_string_begin<std::list<char>>)->RangeMultiplier(2)->Ran
BENCHMARK(BM_format_to_n_string_span<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_n_string_pointer<char>)->RangeMultiplier(2)->Range(1, 1 << 20);

#ifndef TEST_HAS_NO_WIDE_CHARACTERS
BENCHMARK(BM_format_to_n_string_back_inserter<std::wstring>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_n_string_back_inserter<std::vector<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_n_string_back_inserter<std::list<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
Expand All @@ -98,5 +102,6 @@ BENCHMARK(BM_format_to_n_string_begin<std::vector<wchar_t>>)->RangeMultiplier(2)
BENCHMARK(BM_format_to_n_string_begin<std::list<wchar_t>>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_n_string_span<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
BENCHMARK(BM_format_to_n_string_pointer<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
#endif

BENCHMARK_MAIN();
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/formatted_size.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <format>

#include <string>

#include "benchmark/benchmark.h"
#include "make_string.h"
#include "test_macros.h"

#define CSTR(S) MAKE_CSTRING(CharT, S)

Expand All @@ -26,6 +29,8 @@ static void BM_formatted_size_string(benchmark::State& state) {
state.SetBytesProcessed(state.iterations() * size * sizeof(CharT));
}
BENCHMARK(BM_formatted_size_string<char>)->RangeMultiplier(2)->Range(1, 1 << 20);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
BENCHMARK(BM_formatted_size_string<wchar_t>)->RangeMultiplier(2)->Range(1, 1 << 20);
#endif

BENCHMARK_MAIN();
10 changes: 7 additions & 3 deletions libcxx/test/benchmarks/formatter_float.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <format>

#include <array>
#include <bit>
#include <cmath>
#include <limits>
#include <random>
#include <string>
Expand Down Expand Up @@ -90,9 +94,9 @@ struct Value<ValueE::Random> {
std::array<F, 1000> result;
std::generate(result.begin(), result.end(), [&] {
while (true) {
auto result = std::bit_cast<F>(distribution(generator));
if (std::isfinite(result))
return result;
auto val = std::bit_cast<F>(distribution(generator));
if (std::isfinite(val))
return val;
}
});
return result;
Expand Down
5 changes: 5 additions & 0 deletions libcxx/test/benchmarks/formatter_int.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17

#include <array>
#include <format>
#include <random>

#include "CartesianBenchmarks.h"
#include "benchmark/benchmark.h"
#include "test_macros.h"

// Tests the full range of the value.
template <class T>
Expand Down Expand Up @@ -49,11 +52,13 @@ static void BM_BasicLow(benchmark::State& state) {
for (auto value : data)
benchmark::DoNotOptimize(std::format_to(output.begin(), "{}", value));
}
#ifndef TEST_HAS_NO_INT128
BENCHMARK(BM_BasicLow<__uint128_t>);
BENCHMARK(BM_BasicLow<__int128_t>);

BENCHMARK(BM_Basic<__uint128_t>);
BENCHMARK(BM_Basic<__int128_t>);
#endif

// *** Localization ***
enum class LocalizationE { False, True };
Expand Down
Loading