Skip to content

Commit c377011

Browse files
Merge branch 'llvm:main' into flang-x86-check-cpu
2 parents 2c39e34 + f6262fa commit c377011

File tree

228 files changed

+14447
-4735
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

228 files changed

+14447
-4735
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,6 @@ def FuncOp : CIR_Op<"func", [
365365
return getFunctionType().getReturnTypes();
366366
}
367367

368-
/// Hook for OpTrait::FunctionOpInterfaceTrait, called after verifying that
369-
/// the 'type' attribute is present and checks if it holds a function type.
370-
/// Ensures getType, getNumFuncArguments, and getNumFuncResults can be
371-
/// called safely.
372-
llvm::LogicalResult verifyType();
373-
374368
//===------------------------------------------------------------------===//
375369
// SymbolOpInterface Methods
376370
//===------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -287,32 +287,44 @@ def CIR_BoolType :
287287
def CIR_FuncType : CIR_Type<"Func", "func"> {
288288
let summary = "CIR function type";
289289
let description = [{
290-
The `!cir.func` is a function type. It consists of a single return type, a
291-
list of parameter types and can optionally be variadic.
290+
The `!cir.func` is a function type. It consists of an optional return type,
291+
a list of parameter types and can optionally be variadic.
292292

293293
Example:
294294

295295
```mlir
296-
!cir.func<!bool ()>
297-
!cir.func<!s32i (!s8i, !s8i)>
298-
!cir.func<!s32i (!s32i, ...)>
296+
!cir.func<()>
297+
!cir.func<() -> bool>
298+
!cir.func<(!s8i, !s8i)>
299+
!cir.func<(!s8i, !s8i) -> !s32i>
300+
!cir.func<(!s32i, ...) -> !s32i>
299301
```
300302
}];
301303

302304
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
303-
"mlir::Type":$returnType, "bool":$varArg);
305+
OptionalParameter<"mlir::Type">:$optionalReturnType,
306+
"bool":$varArg);
307+
// Use a custom parser to handle argument types with variadic elipsis.
304308
let assemblyFormat = [{
305-
`<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
309+
`<` custom<FuncTypeParams>($inputs, $varArg) (`->` $optionalReturnType^)? `>`
306310
}];
307311

308312
let builders = [
313+
// Create a FuncType, converting the return type from C-style to
314+
// MLIR-style. If the given return type is `cir::VoidType`, ignore it
315+
// and create the FuncType with no return type, which is how MLIR
316+
// represents function types.
309317
TypeBuilderWithInferredContext<(ins
310318
"llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
311319
CArg<"bool", "false">:$isVarArg), [{
312-
return $_get(returnType.getContext(), inputs, returnType, isVarArg);
320+
return $_get(returnType.getContext(), inputs,
321+
mlir::isa<cir::VoidType>(returnType) ? nullptr : returnType,
322+
isVarArg);
313323
}]>
314324
];
315325

326+
let genVerifyDecl = 1;
327+
316328
let extraClassDeclaration = [{
317329
/// Returns whether the function is variadic.
318330
bool isVarArg() const { return getVarArg(); }
@@ -323,12 +335,17 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
323335
/// Returns the number of arguments to the function.
324336
unsigned getNumInputs() const { return getInputs().size(); }
325337

326-
/// Returns the result type of the function as an ArrayRef, enabling better
327-
/// integration with generic MLIR utilities.
338+
/// Get the C-style return type of the function, which is !cir.void if the
339+
/// function returns nothing and the actual return type otherwise.
340+
mlir::Type getReturnType() const;
341+
342+
/// Get the MLIR-style return type of the function, which is an empty
343+
/// ArrayRef if the function returns nothing and a single-element ArrayRef
344+
/// with the actual return type otherwise.
328345
llvm::ArrayRef<mlir::Type> getReturnTypes() const;
329346

330-
/// Returns whether the function is returns void.
331-
bool isVoid() const;
347+
/// Does the function type return nothing?
348+
bool hasVoidReturn() const;
332349

333350
/// Returns a clone of this function type with the given argument
334351
/// and result types.

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bool CIRGenTypes::isFuncTypeConvertible(const FunctionType *ft) {
6060
mlir::Type CIRGenTypes::convertFunctionTypeInternal(QualType qft) {
6161
assert(qft.isCanonical());
6262
const FunctionType *ft = cast<FunctionType>(qft.getTypePtr());
63-
// First, check whether we can build the full fucntion type. If the function
63+
// First, check whether we can build the full function type. If the function
6464
// type depends on an incomplete type (e.g. a struct or enum), we cannot lower
6565
// the function type.
6666
if (!isFuncTypeConvertible(ft)) {

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -416,17 +416,6 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
416416
}
417417
}
418418

419-
// Hook for OpTrait::FunctionLike, called after verifying that the 'type'
420-
// attribute is present. This can check for preconditions of the
421-
// getNumArguments hook not failing.
422-
LogicalResult cir::FuncOp::verifyType() {
423-
auto type = getFunctionType();
424-
if (!isa<cir::FuncType>(type))
425-
return emitOpError("requires '" + getFunctionTypeAttrName().str() +
426-
"' attribute of function type");
427-
return success();
428-
}
429-
430419
// TODO(CIR): The properties of functions that require verification haven't
431420
// been implemented yet.
432421
mlir::LogicalResult cir::FuncOp::verify() { return success(); }

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
//===----------------------------------------------------------------------===//
2222

2323
static mlir::ParseResult
24-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
25-
bool &isVarArg);
26-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
27-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
24+
parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
25+
bool &isVarArg);
26+
static void printFuncTypeParams(mlir::AsmPrinter &p,
27+
mlir::ArrayRef<mlir::Type> params,
28+
bool isVarArg);
2829

2930
//===----------------------------------------------------------------------===//
3031
// Get autogenerated stuff
@@ -282,40 +283,32 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
282283
return get(llvm::to_vector(inputs), results[0], isVarArg());
283284
}
284285

285-
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
286-
llvm::SmallVector<mlir::Type> &params,
287-
bool &isVarArg) {
286+
// Custom parser that parses function parameters of form `(<type>*, ...)`.
287+
static mlir::ParseResult
288+
parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
289+
bool &isVarArg) {
288290
isVarArg = false;
289-
// `(` `)`
290-
if (succeeded(p.parseOptionalRParen()))
291-
return mlir::success();
292-
293-
// `(` `...` `)`
294-
if (succeeded(p.parseOptionalEllipsis())) {
295-
isVarArg = true;
296-
return p.parseRParen();
297-
}
298-
299-
// type (`,` type)* (`,` `...`)?
300-
mlir::Type type;
301-
if (p.parseType(type))
302-
return mlir::failure();
303-
params.push_back(type);
304-
while (succeeded(p.parseOptionalComma())) {
305-
if (succeeded(p.parseOptionalEllipsis())) {
306-
isVarArg = true;
307-
return p.parseRParen();
308-
}
309-
if (p.parseType(type))
310-
return mlir::failure();
311-
params.push_back(type);
312-
}
313-
314-
return p.parseRParen();
315-
}
316-
317-
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
318-
bool isVarArg) {
291+
return p.parseCommaSeparatedList(
292+
AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
293+
if (isVarArg)
294+
return p.emitError(p.getCurrentLocation(),
295+
"variadic `...` must be the last parameter");
296+
if (succeeded(p.parseOptionalEllipsis())) {
297+
isVarArg = true;
298+
return success();
299+
}
300+
mlir::Type type;
301+
if (failed(p.parseType(type)))
302+
return failure();
303+
params.push_back(type);
304+
return success();
305+
});
306+
}
307+
308+
static void printFuncTypeParams(mlir::AsmPrinter &p,
309+
mlir::ArrayRef<mlir::Type> params,
310+
bool isVarArg) {
311+
p << '(';
319312
llvm::interleaveComma(params, p,
320313
[&p](mlir::Type type) { p.printType(type); });
321314
if (isVarArg) {
@@ -326,11 +319,39 @@ void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
326319
p << ')';
327320
}
328321

322+
/// Get the C-style return type of the function, which is !cir.void if the
323+
/// function returns nothing and the actual return type otherwise.
324+
mlir::Type FuncType::getReturnType() const {
325+
if (hasVoidReturn())
326+
return cir::VoidType::get(getContext());
327+
return getOptionalReturnType();
328+
}
329+
330+
/// Get the MLIR-style return type of the function, which is an empty
331+
/// ArrayRef if the function returns nothing and a single-element ArrayRef
332+
/// with the actual return type otherwise.
329333
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
330-
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType;
334+
if (hasVoidReturn())
335+
return {};
336+
// Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
337+
// pointer to its elements and doesn't do lifetime extension. That would
338+
// result in returning a pointer to a temporary that has gone out of scope.
339+
return getImpl()->optionalReturnType;
331340
}
332341

333-
bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
342+
// Does the fuction type return nothing?
343+
bool FuncType::hasVoidReturn() const { return !getOptionalReturnType(); }
344+
345+
mlir::LogicalResult
346+
FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
347+
llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
348+
bool isVarArg) {
349+
if (returnType && mlir::isa<cir::VoidType>(returnType)) {
350+
emitError() << "!cir.func cannot have an explicit 'void' return type";
351+
return mlir::failure();
352+
}
353+
return mlir::success();
354+
}
334355

335356
//===----------------------------------------------------------------------===//
336357
// BoolType

clang/lib/CodeGen/CGCall.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5163,6 +5163,21 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
51635163
}
51645164
}
51655165
if (IRFunctionArgs.hasSRetArg()) {
5166+
// A mismatch between the allocated return value's AS and the target's
5167+
// chosen IndirectAS can happen e.g. when passing the this pointer through
5168+
// a chain involving stores to / loads from the DefaultAS; we address this
5169+
// here, symmetrically with the handling we have for normal pointer args.
5170+
if (SRetPtr.getAddressSpace() != RetAI.getIndirectAddrSpace()) {
5171+
llvm::Value *V = SRetPtr.getBasePointer();
5172+
LangAS SAS = getLangASFromTargetAS(SRetPtr.getAddressSpace());
5173+
LangAS DAS = getLangASFromTargetAS(RetAI.getIndirectAddrSpace());
5174+
llvm::Type *Ty = llvm::PointerType::get(getLLVMContext(),
5175+
RetAI.getIndirectAddrSpace());
5176+
5177+
SRetPtr = SRetPtr.withPointer(
5178+
getTargetHooks().performAddrSpaceCast(*this, V, SAS, DAS, Ty, true),
5179+
SRetPtr.isKnownNonNull());
5180+
}
51665181
IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
51675182
getAsNaturalPointerTo(SRetPtr, RetTy);
51685183
} else if (RetAI.isInAlloca()) {
@@ -5394,9 +5409,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
53945409
V->getType()->isIntegerTy())
53955410
V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());
53965411

5397-
// The only plausible mismatch here would be for pointer address spaces,
5398-
// which can happen e.g. when passing a sret arg that is in the AllocaAS
5399-
// to a function that takes a pointer to and argument in the DefaultAS.
5412+
// The only plausible mismatch here would be for pointer address spaces.
54005413
// We assume that the target has a reasonable mapping for the DefaultAS
54015414
// (it can be casted to from incoming specific ASes), and insert an AS
54025415
// cast to address the mismatch.

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,7 @@ void AggExprEmitter::withReturnValueSlot(
302302
llvm::Value *LifetimeSizePtr = nullptr;
303303
llvm::IntrinsicInst *LifetimeStartInst = nullptr;
304304
if (!UseTemp) {
305-
// It is possible for the existing slot we are using directly to have been
306-
// allocated in the correct AS for an indirect return, and then cast to
307-
// the default AS (this is the behaviour of CreateMemTemp), however we know
308-
// that the return address is expected to point to the uncasted AS, hence we
309-
// strip possible pointer casts here.
310-
if (Dest.getAddress().isValid())
311-
RetAddr = Dest.getAddress().withPointer(
312-
Dest.getAddress().getBasePointer()->stripPointerCasts(),
313-
Dest.getAddress().isKnownNonNull());
305+
RetAddr = Dest.getAddress();
314306
} else {
315307
RetAddr = CGF.CreateMemTempWithoutCast(RetTy, "tmp");
316308
llvm::TypeSize Size =

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "clang/Basic/CodeGenOptions.h"
3131
#include "clang/Basic/TargetInfo.h"
3232
#include "llvm/ADT/APFixedPoint.h"
33+
#include "llvm/IR/Argument.h"
3334
#include "llvm/IR/CFG.h"
3435
#include "llvm/IR/Constants.h"
3536
#include "llvm/IR/DataLayout.h"
@@ -2352,6 +2353,21 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
23522353
Value *Src = Visit(const_cast<Expr*>(E));
23532354
llvm::Type *SrcTy = Src->getType();
23542355
llvm::Type *DstTy = ConvertType(DestTy);
2356+
2357+
// FIXME: this is a gross but seemingly necessary workaround for an issue
2358+
// manifesting when a target uses a non-default AS for indirect sret args,
2359+
// but the source HLL is generic, wherein a valid C-cast or reinterpret_cast
2360+
// on the address of a local struct that gets returned by value yields an
2361+
// invalid bitcast from the a pointer to the IndirectAS to a pointer to the
2362+
// DefaultAS. We can only do this subversive thing because sret args are
2363+
// manufactured and them residing in the IndirectAS is a target specific
2364+
// detail, and doing an AS cast here still retains the semantics the user
2365+
// expects. It is desirable to remove this iff a better solution is found.
2366+
if (auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2367+
return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
2368+
CGF, Src, E->getType().getAddressSpace(), DestTy.getAddressSpace(),
2369+
DstTy);
2370+
23552371
assert(
23562372
(!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
23572373
SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&

clang/lib/Format/FormatToken.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -743,29 +743,6 @@ struct FormatToken {
743743
return isOneOf(tok::star, tok::amp, tok::ampamp);
744744
}
745745

746-
bool isCppAlternativeOperatorKeyword() const {
747-
assert(!TokenText.empty());
748-
if (!isalpha(TokenText[0]))
749-
return false;
750-
751-
switch (Tok.getKind()) {
752-
case tok::ampamp:
753-
case tok::ampequal:
754-
case tok::amp:
755-
case tok::pipe:
756-
case tok::tilde:
757-
case tok::exclaim:
758-
case tok::exclaimequal:
759-
case tok::pipepipe:
760-
case tok::pipeequal:
761-
case tok::caret:
762-
case tok::caretequal:
763-
return true;
764-
default:
765-
return false;
766-
}
767-
}
768-
769746
bool isUnaryOperator() const {
770747
switch (Tok.getKind()) {
771748
case tok::plus:

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6196,7 +6196,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
61966196
return Line.IsMultiVariableDeclStmt ||
61976197
(getTokenPointerOrReferenceAlignment(Right) ==
61986198
FormatStyle::PAS_Right &&
6199-
(!Right.Next || Right.Next->isNot(TT_FunctionDeclarationName)));
6199+
!(Right.Next &&
6200+
Right.Next->isOneOf(TT_FunctionDeclarationName, tok::kw_const)));
62006201
}
62016202
if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
62026203
TT_ClassHeadName, tok::kw_operator)) {

0 commit comments

Comments
 (0)