Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AutoBump] Merge with ac1f2de7 (33) #293

Merged
merged 26 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1ca6b44
[mlir][scf] `scf.while` uplifting: optimize op matching (#88813)
Hardcode84 Apr 16, 2024
aae08f4
[MLIR][OpenMP] Make omp.taskloop into a loop wrapper (#87253)
skatrak Apr 16, 2024
ca4cf97
[clang][Interp][NFC] Fix Pointer::isZero() for block pointers
tbaederr Apr 15, 2024
422bf13
[AMDGPU] In VectorLegalizer::Expand, if UnrollVectorOp returns Load, …
choikwa Apr 16, 2024
4dd5180
[Flang][OpenMP][Lower] Split MLIR codegen for clauses and constructs …
skatrak Apr 16, 2024
31424be
[clang][Interp][NFC] Compare std::optionals directly
tbaederr Apr 15, 2024
a831c54
[clang][Interp] Avoid calling invalid functions
tbaederr Apr 15, 2024
b0194d2
[SEH] Ignore async exception flag when the environment is not MSVC (#…
phoebewang Apr 16, 2024
f4960da
Revert "[Verifier] Reject va_start in non-variadic function (#88809)"
JonChesterfield Apr 16, 2024
01f7989
[LoongArch] Use R_LARCH_ALIGN with section symbol (#84741)
MQ-mengqing Apr 16, 2024
c09384e
[clang][Interp] Support MemberExprs pointing to VarDecls
tbaederr Apr 15, 2024
1120d8e
[clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (#88455)
AlexVlx Apr 16, 2024
36b3c26
[JumpThreading] Thread over BB with only an unconditional branch (#86…
XChy Apr 16, 2024
32b74ca
[clang][Interp] Load value from MemberExpr if required
tbaederr Apr 15, 2024
92e96c7
[X86][GISel] Add DU chain lookups for LOAD & STORE (#87453)
MalaySanghi Apr 16, 2024
ac6b4c6
Reapply "[Verifier] Reject va_start in non-variadic function (#88809)"
JonChesterfield Apr 16, 2024
09e7d75
[clang][Interp] Don't add 'in call to' diagnostics for builtin frames
tbaederr Apr 16, 2024
a8de3ee
[clang][Interp][NFC] Fix some build warnings
tbaederr Apr 16, 2024
c18a3b6
[DAG] Fold extract_subvector(insert_subvector(x,y,c1),c2) --> extract…
RKSimon Apr 16, 2024
71b9f66
[clang][Index] Use canonical function parameter types in USRs (#68222)
sdkrystian Apr 16, 2024
dadcaf8
[mlir][ArmSME] Support decomposing constant splats into ArmSME tiles …
MacDue Apr 16, 2024
711df7b
[vector][mlir] Restrict vector.shuffle to fixed-width vectors (#88733)
banach-space Apr 16, 2024
75244a1
[clang][Interp] Implement align builtins
tbaederr Apr 16, 2024
91dd844
Recommit [RISCV] RISCV vector calling convention (2/2) (#79096) (#87736)
4vtomat Apr 16, 2024
ac1f2de
[MLIR][docs] Mention declarePromisedInterface in Interfaces doc (#88689)
frederik-h Apr 16, 2024
393bc06
[AutoBump] Merge with ac1f2de7
cferry-AMD Aug 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1267,10 +1267,30 @@ template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
// 'Base.Member'
const Expr *Base = E->getBase();
const ValueDecl *Member = E->getMemberDecl();

if (DiscardResult)
return this->discard(Base);

// MemberExprs are almost always lvalues, in which case we don't need to
// do the load. But sometimes they aren't.
const auto maybeLoadValue = [&]() -> bool {
if (E->isGLValue())
return true;
if (std::optional<PrimType> T = classify(E))
return this->emitLoadPop(*T, E);
return false;
};

if (const auto *VD = dyn_cast<VarDecl>(Member)) {
// I am almost confident in saying that a var decl must be static
// and therefore registered as a global variable. But this will probably
// turn out to be wrong some time in the future, as always.
if (auto GlobalIndex = P.getGlobal(VD))
return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
return false;
}

if (Initializing) {
if (!this->delegate(Base))
return false;
Expand All @@ -1280,16 +1300,14 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
}

// Base above gives us a pointer on the stack.
// TODO: Implement non-FieldDecl members.
const ValueDecl *Member = E->getMemberDecl();
if (const auto *FD = dyn_cast<FieldDecl>(Member)) {
const RecordDecl *RD = FD->getParent();
const Record *R = getRecord(RD);
const Record::Field *F = R->getField(FD);
// Leave a pointer to the field on the stack.
if (F->Decl->getType()->isReferenceType())
return this->emitGetFieldPop(PT_Ptr, F->Offset, E);
return this->emitGetPtrField(F->Offset, E);
return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
}

return false;
Expand Down Expand Up @@ -1624,7 +1642,7 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
return false;
if (!this->emitLoad(*LT, E))
return false;
if (*LT != *LHSComputationT) {
if (LT != LHSComputationT) {
if (!this->emitCast(*LT, *LHSComputationT, E))
return false;
}
Expand Down Expand Up @@ -1680,7 +1698,7 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
}

// And now cast from LHSComputationT to ResultT.
if (*ResultT != *LHSComputationT) {
if (ResultT != LHSComputationT) {
if (!this->emitCast(*LHSComputationT, *ResultT, E))
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/Disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
const Descriptor *Desc = G->block()->getDescriptor();
Pointer GP = getPtrGlobal(GI);

OS << GI << ": " << (void *)G->block() << " ";
OS << GI << ": " << (const void *)G->block() << " ";
{
ColorScope SC(OS, true,
GP.isInitialized()
Expand Down Expand Up @@ -268,7 +268,7 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation,
LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const {
{
ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_BLUE, true});
OS << "Block " << (void *)this << "\n";
OS << "Block " << (const void *)this << "\n";
}
unsigned NPointers = 0;
for (const Pointer *P = Pointers; P; P = P->Next) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Interp/FunctionPointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class FunctionPointer final {

const Function *getFunction() const { return Func; }
bool isZero() const { return !Func; }
bool isValid() const { return Valid; }
bool isWeak() const {
if (!Func || !Valid)
return false;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,10 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
<< const_cast<Expr *>(E) << E->getSourceRange();
return false;
}

if (!FuncPtr.isValid())
return false;

assert(F);

// Check argument nullability state.
Expand Down
118 changes: 118 additions & 0 deletions clang/lib/AST/Interp/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,117 @@ static bool interp__builtin_complex(InterpState &S, CodePtr OpPC,
return true;
}

/// __builtin_is_aligned()
/// __builtin_align_up()
/// __builtin_align_down()
/// The first parameter is either an integer or a pointer.
/// The second parameter is the requested alignment as an integer.
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
const CallExpr *Call) {
unsigned BuiltinOp = Func->getBuiltinID();
unsigned CallSize = callArgSize(S, Call);

PrimType AlignmentT = *S.Ctx.classify(Call->getArg(1));
const APSInt &Alignment = peekToAPSInt(S.Stk, AlignmentT);

if (Alignment < 0 || !Alignment.isPowerOf2()) {
S.FFDiag(Call, diag::note_constexpr_invalid_alignment) << Alignment;
return false;
}
unsigned SrcWidth = S.getCtx().getIntWidth(Call->getArg(0)->getType());
APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
if (APSInt::compareValues(Alignment, MaxValue) > 0) {
S.FFDiag(Call, diag::note_constexpr_alignment_too_big)
<< MaxValue << Call->getArg(0)->getType() << Alignment;
return false;
}

// The first parameter is either an integer or a pointer (but not a function
// pointer).
PrimType FirstArgT = *S.Ctx.classify(Call->getArg(0));

if (isIntegralType(FirstArgT)) {
const APSInt &Src = peekToAPSInt(S.Stk, FirstArgT, CallSize);
APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
if (BuiltinOp == Builtin::BI__builtin_align_up) {
APSInt AlignedVal =
APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
pushInteger(S, AlignedVal, Call->getType());
} else if (BuiltinOp == Builtin::BI__builtin_align_down) {
APSInt AlignedVal = APSInt(Src & ~(Align - 1), Src.isUnsigned());
pushInteger(S, AlignedVal, Call->getType());
} else {
assert(*S.Ctx.classify(Call->getType()) == PT_Bool);
S.Stk.push<Boolean>((Src & (Align - 1)) == 0);
}
return true;
}

assert(FirstArgT == PT_Ptr);
const Pointer &Ptr = S.Stk.peek<Pointer>(CallSize);

unsigned PtrOffset = Ptr.getByteOffset();
PtrOffset = Ptr.getIndex();
CharUnits BaseAlignment =
S.getCtx().getDeclAlign(Ptr.getDeclDesc()->asValueDecl());
CharUnits PtrAlign =
BaseAlignment.alignmentAtOffset(CharUnits::fromQuantity(PtrOffset));

if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
if (PtrAlign.getQuantity() >= Alignment) {
S.Stk.push<Boolean>(true);
return true;
}
// If the alignment is not known to be sufficient, some cases could still
// be aligned at run time. However, if the requested alignment is less or
// equal to the base alignment and the offset is not aligned, we know that
// the run-time value can never be aligned.
if (BaseAlignment.getQuantity() >= Alignment &&
PtrAlign.getQuantity() < Alignment) {
S.Stk.push<Boolean>(false);
return true;
}

S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_compute)
<< Alignment;
return false;
}

assert(BuiltinOp == Builtin::BI__builtin_align_down ||
BuiltinOp == Builtin::BI__builtin_align_up);

// For align_up/align_down, we can return the same value if the alignment
// is known to be greater or equal to the requested value.
if (PtrAlign.getQuantity() >= Alignment) {
S.Stk.push<Pointer>(Ptr);
return true;
}

// The alignment could be greater than the minimum at run-time, so we cannot
// infer much about the resulting pointer value. One case is possible:
// For `_Alignas(32) char buf[N]; __builtin_align_down(&buf[idx], 32)` we
// can infer the correct index if the requested alignment is smaller than
// the base alignment so we can perform the computation on the offset.
if (BaseAlignment.getQuantity() >= Alignment) {
assert(Alignment.getBitWidth() <= 64 &&
"Cannot handle > 64-bit address-space");
uint64_t Alignment64 = Alignment.getZExtValue();
CharUnits NewOffset =
CharUnits::fromQuantity(BuiltinOp == Builtin::BI__builtin_align_down
? llvm::alignDown(PtrOffset, Alignment64)
: llvm::alignTo(PtrOffset, Alignment64));

S.Stk.push<Pointer>(Ptr.atIndex(NewOffset.getQuantity()));
return true;
}

// Otherwise, we cannot constant-evaluate the result.
S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
return false;
}

bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call) {
const InterpFrame *Frame = S.Current;
Expand Down Expand Up @@ -1291,6 +1402,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;

case Builtin::BI__builtin_is_aligned:
case Builtin::BI__builtin_align_up:
case Builtin::BI__builtin_align_down:
if (!interp__builtin_is_aligned_up_down(S, OpPC, Frame, F, Call))
return false;
break;

default:
S.FFDiag(S.Current->getLocation(OpPC),
diag::note_invalid_subexpr_in_const_expr)
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/Interp/InterpFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx,
}

void InterpFrame::describe(llvm::raw_ostream &OS) const {
// We create frames for builtin functions as well, but we can't reliably
// diagnose them. The 'in call to' diagnostics for them add no value to the
// user _and_ it doesn't generally work since the argument types don't always
// match the function prototype. Just ignore them.
if (const auto *F = getFunction(); F && F->isBuiltin())
return;

const FunctionDecl *F = getCallee();
if (const auto *M = dyn_cast<CXXMethodDecl>(F);
M && M->isInstance() && !isa<CXXConstructorDecl>(F)) {
Expand Down
5 changes: 1 addition & 4 deletions clang/lib/AST/Interp/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,10 @@ class Pointer {

/// Checks if the pointer is null.
bool isZero() const {
if (Offset != 0)
return false;

if (isBlockPointer())
return asBlockPointer().Pointee == nullptr;
assert(isIntegralPointer());
return asIntPointer().Value == 0;
return asIntPointer().Value == 0 && Offset == 0;
}
/// Checks if the pointer is live.
bool isLive() const {
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/Interp/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ void State::addCallStack(unsigned Limit) {
SmallString<128> Buffer;
llvm::raw_svector_ostream Out(Buffer);
F->describe(Out);
addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
<< Out.str() << CallRange;
if (!Buffer.empty())
addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
<< Out.str() << CallRange;
}
}
8 changes: 4 additions & 4 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
SizeType = TargetInfo::UnsignedInt;
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
}

void getTargetDefines(const LangOptions &Opts,
Expand All @@ -276,7 +276,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
}

void getTargetDefines(const LangOptions &Opts,
Expand Down Expand Up @@ -336,7 +336,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
SizeType = TargetInfo::UnsignedInt;
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
}

void getTargetDefines(const LangOptions &Opts,
Expand All @@ -357,7 +357,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
}

void getTargetDefines(const LangOptions &Opts,
Expand Down
28 changes: 20 additions & 8 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,14 @@ static bool addExceptionArgs(const ArgList &Args, types::ID InputType,
bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
false);

bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
options::OPT_fno_async_exceptions, false);
if (EHa) {
CmdArgs.push_back("-fasync-exceptions");
EH = true;
// Async exceptions are Windows MSVC only.
if (Triple.isWindowsMSVCEnvironment()) {
bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
options::OPT_fno_async_exceptions, false);
if (EHa) {
CmdArgs.push_back("-fasync-exceptions");
EH = true;
}
}

// Obj-C exceptions are enabled by default, regardless of -fexceptions. This
Expand Down Expand Up @@ -8102,7 +8105,8 @@ struct EHFlags {
/// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
/// - c: Assume that extern "C" functions are implicitly nounwind.
/// The default is /EHs-c-, meaning cleanups are disabled.
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args,
bool isWindowsMSVC) {
EHFlags EH;

std::vector<std::string> EHArgs =
Expand All @@ -8112,8 +8116,15 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
switch (EHVal[I]) {
case 'a':
EH.Asynch = maybeConsumeDash(EHVal, I);
if (EH.Asynch)
if (EH.Asynch) {
// Async exceptions are Windows MSVC only.
if (!isWindowsMSVC) {
EH.Asynch = false;
D.Diag(clang::diag::warn_drv_unused_argument) << "/EHa" << EHVal;
continue;
}
EH.Synch = false;
}
continue;
case 'c':
EH.NoUnwindC = maybeConsumeDash(EHVal, I);
Expand Down Expand Up @@ -8177,7 +8188,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,

const Driver &D = getToolChain().getDriver();

EHFlags EH = parseClangCLEHFlags(D, Args);
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
EHFlags EH = parseClangCLEHFlags(D, Args, IsWindowsMSVC);
if (!isNVPTX && (EH.Synch || EH.Asynch)) {
if (types::isCXX(InputType))
CmdArgs.push_back("-fcxx-exceptions");
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/Index/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,13 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
Out << '>';
}

QualType CanonicalType = D->getType().getCanonicalType();
// Mangle in type information for the arguments.
for (auto *PD : D->parameters()) {
Out << '#';
VisitType(PD->getType());
if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) {
for (QualType PT : FPT->param_types()) {
Out << '#';
VisitType(PT);
}
}
if (D->isVariadic())
Out << '.';
Expand Down
Loading