summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-08-13 12:28:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-08-13 12:28:03 +0000
commit677727e8296a802385345db6fa65e68223f4597a (patch)
treee8b3137703a6bf0c03c6d3b28da1eb9271bae00d /clang/lib/CodeGen
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Vendor import of llvm-project branch release/15.x llvmorg-15.0.0-rc2-40-gfbd2950d8d0d.vendor/llvm-project/llvmorg-15.0.0-rc2-40-gfbd2950d8d0d
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp8
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp15
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp13
4 files changed, 32 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 949112c63cc9..6915f950b6ce 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -649,8 +649,8 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
SmallVector<llvm::Function *, 8> ModuleInits;
for (Module *M : AllImports) {
- // No Itanium initializer in module map modules.
- if (M->isModuleMapModule())
+ // No Itanium initializer in header like modules.
+ if (M->isHeaderLikeModule())
continue; // TODO: warn of mixed use of module map modules and C++20?
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
SmallString<256> FnName;
@@ -778,8 +778,8 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
SmallVector<llvm::Function *, 8> ModuleInits;
if (CXX20ModuleInits)
for (Module *M : ImportedModules) {
- // No Itanium initializer in module map modules.
- if (M->isModuleMapModule())
+ // No Itanium initializer in header like modules.
+ if (M->isHeaderLikeModule())
continue;
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
SmallString<256> FnName;
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 05ab16668743..481438de0e53 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2343,6 +2343,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
std::vector<llvm::Type *> ArgElemTypes;
std::vector<llvm::Value*> Args;
llvm::BitVector ResultTypeRequiresCast;
+ llvm::BitVector ResultRegIsFlagReg;
// Keep track of inout constraints.
std::string InOutConstraints;
@@ -2400,6 +2401,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
ResultRegQualTys.push_back(QTy);
ResultRegDests.push_back(Dest);
+ bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
+ ResultRegIsFlagReg.push_back(IsFlagReg);
+
llvm::Type *Ty = ConvertTypeForMem(QTy);
const bool RequiresCast = Info.allowsRegister() &&
(getTargetHooks().isScalarizableAsmOperand(*this, Ty) ||
@@ -2717,10 +2721,21 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
// ResultRegDests can be also populated by addReturnRegisterOutputs() above,
// in which case its size may grow.
assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+ assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
llvm::Value *Tmp = RegResults[i];
llvm::Type *TruncTy = ResultTruncRegTypes[i];
+ if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+ // Target must guarantee the Value `Tmp` here is lowered to a boolean
+ // value.
+ llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+ llvm::Value *IsBooleanValue =
+ Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+ llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+ Builder.CreateCall(FnAssume, IsBooleanValue);
+ }
+
// If the result type of the LLVM IR asm doesn't match the result type of
// the expression, do the conversion.
if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4e8e120d89df..d87692face2a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -521,7 +521,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
void CodeGenModule::Release() {
Module *Primary = getContext().getModuleForCodeGen();
- if (CXX20ModuleInits && Primary && !Primary->isModuleMapModule())
+ if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
EmitModuleInitializers(Primary);
EmitDeferred();
DeferredDecls.insert(EmittedDeferredDecls.begin(),
@@ -2521,21 +2521,23 @@ void CodeGenModule::EmitModuleInitializers(clang::Module *Primary) {
// source, first Global Module Fragments, if present.
if (auto GMF = Primary->getGlobalModuleFragment()) {
for (Decl *D : getContext().getModuleInitializers(GMF)) {
- assert(D->getKind() == Decl::Var && "GMF initializer decl is not a var?");
+ if (isa<ImportDecl>(D))
+ continue;
+ assert(isa<VarDecl>(D) && "GMF initializer decl is not a var?");
EmitTopLevelDecl(D);
}
}
// Second any associated with the module, itself.
for (Decl *D : getContext().getModuleInitializers(Primary)) {
// Skip import decls, the inits for those are called explicitly.
- if (D->getKind() == Decl::Import)
+ if (isa<ImportDecl>(D))
continue;
EmitTopLevelDecl(D);
}
// Third any associated with the Privat eMOdule Fragment, if present.
if (auto PMF = Primary->getPrivateModuleFragment()) {
for (Decl *D : getContext().getModuleInitializers(PMF)) {
- assert(D->getKind() == Decl::Var && "PMF initializer decl is not a var?");
+ assert(isa<VarDecl>(D) && "PMF initializer decl is not a var?");
EmitTopLevelDecl(D);
}
}
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index d1ee61eab9d6..195ad8cdc13e 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -2871,7 +2871,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
} else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
Current = Integer;
} else if (k == BuiltinType::Float || k == BuiltinType::Double ||
- k == BuiltinType::Float16) {
+ k == BuiltinType::Float16 || k == BuiltinType::BFloat16) {
Current = SSE;
} else if (k == BuiltinType::LongDouble) {
const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
@@ -3002,7 +3002,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
Current = Integer;
else if (Size <= 128)
Lo = Hi = Integer;
- } else if (ET->isFloat16Type() || ET == getContext().FloatTy) {
+ } else if (ET->isFloat16Type() || ET == getContext().FloatTy ||
+ ET->isBFloat16Type()) {
Current = SSE;
} else if (ET == getContext().DoubleTy) {
Lo = Hi = SSE;
@@ -3474,9 +3475,9 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
if (SourceSize > T0Size)
T1 = getFPTypeAtOffset(IRType, IROffset + T0Size, TD);
if (T1 == nullptr) {
- // Check if IRType is a half + float. float type will be in IROffset+4 due
+ // Check if IRType is a half/bfloat + float. float type will be in IROffset+4 due
// to its alignment.
- if (T0->isHalfTy() && SourceSize > 4)
+ if (T0->is16bitFPTy() && SourceSize > 4)
T1 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
// If we can't get a second FP type, return a simple half or float.
// avx512fp16-abi.c:pr51813_2 shows it works to return float for
@@ -3488,7 +3489,7 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
if (T0->isFloatTy() && T1->isFloatTy())
return llvm::FixedVectorType::get(T0, 2);
- if (T0->isHalfTy() && T1->isHalfTy()) {
+ if (T0->is16bitFPTy() && T1->is16bitFPTy()) {
llvm::Type *T2 = nullptr;
if (SourceSize > 4)
T2 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
@@ -3497,7 +3498,7 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
return llvm::FixedVectorType::get(T0, 4);
}
- if (T0->isHalfTy() || T1->isHalfTy())
+ if (T0->is16bitFPTy() || T1->is16bitFPTy())
return llvm::FixedVectorType::get(llvm::Type::getHalfTy(getVMContext()), 4);
return llvm::Type::getDoubleTy(getVMContext());