Skip to content

Commit 759ab78

Browse files
authored
merge main into amd-staging (llvm#1940)
2 parents 89aa1ca + c549c77 commit 759ab78

File tree

109 files changed

+4058
-945
lines changed

Some content is hidden

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

109 files changed

+4058
-945
lines changed

bolt/lib/Passes/PatchEntries.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,10 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
9898
});
9999

100100
if (!Success) {
101-
// We can't change output layout for AArch64 due to LongJmp pass
102-
if (BC.isAArch64()) {
103-
if (opts::ForcePatch) {
104-
BC.errs() << "BOLT-ERROR: unable to patch entries in " << Function
105-
<< "\n";
106-
return createFatalBOLTError("");
107-
}
108-
109-
continue;
110-
}
111-
112101
// If the original function entries cannot be patched, then we cannot
113102
// safely emit new function body.
114103
BC.errs() << "BOLT-WARNING: failed to patch entries in " << Function
115-
<< ". The function will not be optimized.\n";
104+
<< ". The function will not be optimized\n";
116105
Function.setIgnored();
117106
continue;
118107
}

bolt/lib/Rewrite/BinaryPassManager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,10 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
497497
// memory profiling data.
498498
Manager.registerPass(std::make_unique<ReorderData>());
499499

500+
// Patch original function entries
501+
if (BC.HasRelocations)
502+
Manager.registerPass(std::make_unique<PatchEntries>());
503+
500504
if (BC.isAArch64()) {
501505
Manager.registerPass(
502506
std::make_unique<ADRRelaxationPass>(PrintAdrRelaxation));
@@ -524,10 +528,6 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
524528
// Assign each function an output section.
525529
Manager.registerPass(std::make_unique<AssignSections>());
526530

527-
// Patch original function entries
528-
if (BC.HasRelocations)
529-
Manager.registerPass(std::make_unique<PatchEntries>());
530-
531531
// This pass turns tail calls into jumps which makes them invisible to
532532
// function reordering. It's unsafe to use any CFG or instruction analysis
533533
// after this point.

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ New Compiler Flags
281281
The feature has `existed <https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program>`_)
282282
for a while and this is just a user facing option.
283283

284-
- New option ``-ftime-report-json`` added which outputs the same timing data as `-ftime-report` but formatted as JSON.
284+
- New option ``-ftime-report-json`` added which outputs the same timing data as ``-ftime-report`` but formatted as JSON.
285285

286286
Deprecated Compiler Flags
287287
-------------------------

clang/include/clang/Basic/OffloadArch.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ enum class OffloadArch {
101101
AMDGCNSPIRV,
102102
Generic, // A processor model named 'generic' if the target backend defines a
103103
// public one.
104+
// Intel CPUs
105+
GRANITERAPIDS,
106+
// Intel GPUs
107+
BMG_G21,
104108
LAST,
105109

106110
CudaDefault = OffloadArch::SM_52,
@@ -116,6 +120,18 @@ static inline bool IsAMDOffloadArch(OffloadArch A) {
116120
return A >= OffloadArch::GFX600 && A < OffloadArch::Generic;
117121
}
118122

123+
static inline bool IsIntelCPUOffloadArch(OffloadArch Arch) {
124+
return Arch >= OffloadArch::GRANITERAPIDS && Arch < OffloadArch::BMG_G21;
125+
}
126+
127+
static inline bool IsIntelGPUOffloadArch(OffloadArch Arch) {
128+
return Arch >= OffloadArch::BMG_G21 && Arch < OffloadArch::LAST;
129+
}
130+
131+
static inline bool IsIntelOffloadArch(OffloadArch Arch) {
132+
return IsIntelCPUOffloadArch(Arch) || IsIntelGPUOffloadArch(Arch);
133+
}
134+
119135
const char *OffloadArchToString(OffloadArch A);
120136
const char *OffloadArchToVirtualArchString(OffloadArch A);
121137

clang/lib/Basic/OffloadArch.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ static const OffloadArchToStringMap ArchNames[] = {
8787
GFX(1200), // gfx1200
8888
GFX(1201), // gfx1201
8989
{OffloadArch::AMDGCNSPIRV, "amdgcnspirv", "compute_amdgcn"},
90+
// Intel CPUs
91+
{OffloadArch::GRANITERAPIDS, "graniterapids", ""},
92+
// Intel GPUS
93+
{OffloadArch::BMG_G21, "bmg_g21", ""},
9094
{OffloadArch::Generic, "generic", ""},
9195
// clang-format on
9296
};

clang/lib/Basic/Targets/NVPTX.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
241241
case OffloadArch::GFX1201:
242242
case OffloadArch::AMDGCNSPIRV:
243243
case OffloadArch::Generic:
244+
case OffloadArch::GRANITERAPIDS:
245+
case OffloadArch::BMG_G21:
244246
case OffloadArch::LAST:
245247
break;
246248
case OffloadArch::UNKNOWN:

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
185185
}
186186
bool isInt(mlir::Type i) { return mlir::isa<cir::IntType>(i); }
187187

188+
//
189+
// Constant creation helpers
190+
// -------------------------
191+
//
192+
cir::ConstantOp getSInt32(int32_t c, mlir::Location loc) {
193+
return getConstantInt(loc, getSInt32Ty(), c);
194+
}
195+
188196
// Creates constant nullptr for pointer type ty.
189197
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
190198
assert(!cir::MissingFeatures::targetCodeGenInfoGetNullPointer());

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,41 @@ void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
948948
emitLValue(e);
949949
}
950950

951+
Address CIRGenFunction::emitArrayToPointerDecay(const Expr *e) {
952+
assert(e->getType()->isArrayType() &&
953+
"Array to pointer decay must have array source type!");
954+
955+
// Expressions of array type can't be bitfields or vector elements.
956+
LValue lv = emitLValue(e);
957+
Address addr = lv.getAddress();
958+
959+
// If the array type was an incomplete type, we need to make sure
960+
// the decay ends up being the right type.
961+
auto lvalueAddrTy = mlir::cast<cir::PointerType>(addr.getPointer().getType());
962+
963+
if (e->getType()->isVariableArrayType())
964+
return addr;
965+
966+
auto pointeeTy = mlir::cast<cir::ArrayType>(lvalueAddrTy.getPointee());
967+
968+
mlir::Type arrayTy = convertType(e->getType());
969+
assert(mlir::isa<cir::ArrayType>(arrayTy) && "expected array");
970+
assert(pointeeTy == arrayTy);
971+
972+
// The result of this decay conversion points to an array element within the
973+
// base lvalue. However, since TBAA currently does not support representing
974+
// accesses to elements of member arrays, we conservatively represent accesses
975+
// to the pointee object as if it had no any base lvalue specified.
976+
// TODO: Support TBAA for member arrays.
977+
QualType eltType = e->getType()->castAsArrayTypeUnsafe()->getElementType();
978+
assert(!cir::MissingFeatures::opTBAA());
979+
980+
mlir::Value ptr = builder.maybeBuildArrayDecay(
981+
cgm.getLoc(e->getSourceRange()), addr.getPointer(),
982+
convertTypeForMem(eltType));
983+
return Address(ptr, addr.getAlignment());
984+
}
985+
951986
/// Emit an `if` on a boolean condition, filling `then` and `else` into
952987
/// appropriated regions.
953988
mlir::LogicalResult CIRGenFunction::emitIfOnBoolExpr(const Expr *cond,

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,26 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
388388
// NOTE(CIR): clang calls CreateAdd but folds this to a unary op
389389
value = emitUnaryOp(e, kind, input, /*nsw=*/false);
390390
}
391-
} else if (isa<PointerType>(type)) {
392-
cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec pointer");
393-
return {};
391+
} else if (const PointerType *ptr = type->getAs<PointerType>()) {
392+
QualType type = ptr->getPointeeType();
393+
if (cgf.getContext().getAsVariableArrayType(type)) {
394+
// VLA types don't have constant size.
395+
cgf.cgm.errorNYI(e->getSourceRange(), "Pointer arithmetic on VLA");
396+
return {};
397+
} else if (type->isFunctionType()) {
398+
// Arithmetic on function pointers (!) is just +-1.
399+
cgf.cgm.errorNYI(e->getSourceRange(),
400+
"Pointer arithmetic on function pointer");
401+
return {};
402+
} else {
403+
// For everything else, we can just do a simple increment.
404+
mlir::Location loc = cgf.getLoc(e->getSourceRange());
405+
CIRGenBuilderTy &builder = cgf.getBuilder();
406+
int amount = (isInc ? 1 : -1);
407+
mlir::Value amt = builder.getSInt32(amount, loc);
408+
assert(!cir::MissingFeatures::sanitizers());
409+
value = builder.createPtrStride(loc, value, amt);
410+
}
394411
} else if (type->isVectorType()) {
395412
cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec vector");
396413
return {};
@@ -1152,8 +1169,78 @@ getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e) {
11521169
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf,
11531170
const BinOpInfo &op,
11541171
bool isSubtraction) {
1155-
cgf.cgm.errorNYI(op.loc, "pointer arithmetic");
1156-
return {};
1172+
// Must have binary (not unary) expr here. Unary pointer
1173+
// increment/decrement doesn't use this path.
1174+
const BinaryOperator *expr = cast<BinaryOperator>(op.e);
1175+
1176+
mlir::Value pointer = op.lhs;
1177+
Expr *pointerOperand = expr->getLHS();
1178+
mlir::Value index = op.rhs;
1179+
Expr *indexOperand = expr->getRHS();
1180+
1181+
// In the case of subtraction, the FE has ensured that the LHS is always the
1182+
// pointer. However, addition can have the pointer on either side. We will
1183+
// always have a pointer operand and an integer operand, so if the LHS wasn't
1184+
// a pointer, we need to swap our values.
1185+
if (!isSubtraction && !mlir::isa<cir::PointerType>(pointer.getType())) {
1186+
std::swap(pointer, index);
1187+
std::swap(pointerOperand, indexOperand);
1188+
}
1189+
assert(mlir::isa<cir::PointerType>(pointer.getType()) &&
1190+
"Need a pointer operand");
1191+
assert(mlir::isa<cir::IntType>(index.getType()) && "Need an integer operand");
1192+
1193+
// Some versions of glibc and gcc use idioms (particularly in their malloc
1194+
// routines) that add a pointer-sized integer (known to be a pointer value)
1195+
// to a null pointer in order to cast the value back to an integer or as
1196+
// part of a pointer alignment algorithm. This is undefined behavior, but
1197+
// we'd like to be able to compile programs that use it.
1198+
//
1199+
// Normally, we'd generate a GEP with a null-pointer base here in response
1200+
// to that code, but it's also UB to dereference a pointer created that
1201+
// way. Instead (as an acknowledged hack to tolerate the idiom) we will
1202+
// generate a direct cast of the integer value to a pointer.
1203+
//
1204+
// The idiom (p = nullptr + N) is not met if any of the following are true:
1205+
//
1206+
// The operation is subtraction.
1207+
// The index is not pointer-sized.
1208+
// The pointer type is not byte-sized.
1209+
//
1210+
if (BinaryOperator::isNullPointerArithmeticExtension(
1211+
cgf.getContext(), op.opcode, expr->getLHS(), expr->getRHS()))
1212+
return cgf.getBuilder().createIntToPtr(index, pointer.getType());
1213+
1214+
// Differently from LLVM codegen, ABI bits for index sizes is handled during
1215+
// LLVM lowering.
1216+
1217+
// If this is subtraction, negate the index.
1218+
if (isSubtraction)
1219+
index = cgf.getBuilder().createNeg(index);
1220+
1221+
assert(!cir::MissingFeatures::sanitizers());
1222+
1223+
const PointerType *pointerType =
1224+
pointerOperand->getType()->getAs<PointerType>();
1225+
if (!pointerType) {
1226+
cgf.cgm.errorNYI("Objective-C:pointer arithmetic with non-pointer type");
1227+
return nullptr;
1228+
}
1229+
1230+
QualType elementType = pointerType->getPointeeType();
1231+
if (cgf.getContext().getAsVariableArrayType(elementType)) {
1232+
cgf.cgm.errorNYI("variable array type");
1233+
return nullptr;
1234+
}
1235+
1236+
if (elementType->isVoidType() || elementType->isFunctionType()) {
1237+
cgf.cgm.errorNYI("void* or function pointer arithmetic");
1238+
return nullptr;
1239+
}
1240+
1241+
assert(!cir::MissingFeatures::sanitizers());
1242+
return cgf.getBuilder().create<cir::PtrStrideOp>(
1243+
cgf.getLoc(op.e->getExprLoc()), pointer.getType(), pointer, index);
11571244
}
11581245

11591246
mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &ops) {
@@ -1480,6 +1567,9 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
14801567
return v;
14811568
}
14821569

1570+
case CK_ArrayToPointerDecay:
1571+
return cgf.emitArrayToPointerDecay(subExpr).getPointer();
1572+
14831573
case CK_NullToPointer: {
14841574
if (mustVisitNullValue(subExpr))
14851575
cgf.emitIgnoredExpr(subExpr);

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
519519
return emitBinaryOperatorLValue(cast<BinaryOperator>(e));
520520
case Expr::CompoundAssignOperatorClass: {
521521
QualType ty = e->getType();
522-
if (const AtomicType *at = ty->getAs<AtomicType>()) {
522+
if (ty->getAs<AtomicType>()) {
523523
cgm.errorNYI(e->getSourceRange(),
524524
"CompoundAssignOperator with AtomicType");
525525
return LValue();

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ class CIRGenFunction : public CIRGenTypeCache {
449449

450450
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e);
451451

452+
Address emitArrayToPointerDecay(const Expr *array);
453+
452454
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d);
453455

454456
/// Emit code and set up symbol table for a variable declaration with auto,
@@ -485,6 +487,10 @@ class CIRGenFunction : public CIRGenTypeCache {
485487
LValue emitCompoundAssignmentLValue(const clang::CompoundAssignOperator *e);
486488

487489
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s);
490+
491+
mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s,
492+
llvm::ArrayRef<const Attr *> attrs);
493+
488494
mlir::LogicalResult emitDoStmt(const clang::DoStmt &s);
489495

490496
/// Emit an expression as an initializer for an object (variable, field, etc.)

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,13 @@ class OpenACCClauseCIREmitter final
147147
decodeDeviceType(clause.getArchitectures()[0].getIdentifierInfo()));
148148
} else if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp,
149149
mlir::acc::SerialOp, mlir::acc::KernelsOp,
150-
mlir::acc::DataOp>) {
150+
mlir::acc::DataOp, mlir::acc::LoopOp>) {
151151
// Nothing to do here, these constructs don't have any IR for these, as
152152
// they just modify the other clauses IR. So setting of
153153
// `lastDeviceTypeValues` (done above) is all we need.
154154
} else {
155155
// TODO: When we've implemented this for everything, switch this to an
156-
// unreachable. update, data, loop, routine, combined constructs remain.
156+
// unreachable. update, data, routine, combined constructs remain.
157157
return clauseNotImplemented(clause);
158158
}
159159
}
@@ -306,6 +306,36 @@ class OpenACCClauseCIREmitter final
306306
llvm_unreachable("set, is only valid device_num constructs");
307307
}
308308
}
309+
310+
void VisitSeqClause(const OpenACCSeqClause &clause) {
311+
if constexpr (isOneOfTypes<OpTy, mlir::acc::LoopOp>) {
312+
operation.addSeq(builder.getContext(), lastDeviceTypeValues);
313+
} else {
314+
// TODO: When we've implemented this for everything, switch this to an
315+
// unreachable. Routine, Combined constructs remain.
316+
return clauseNotImplemented(clause);
317+
}
318+
}
319+
320+
void VisitAutoClause(const OpenACCAutoClause &clause) {
321+
if constexpr (isOneOfTypes<OpTy, mlir::acc::LoopOp>) {
322+
operation.addAuto(builder.getContext(), lastDeviceTypeValues);
323+
} else {
324+
// TODO: When we've implemented this for everything, switch this to an
325+
// unreachable. Routine, Combined constructs remain.
326+
return clauseNotImplemented(clause);
327+
}
328+
}
329+
330+
void VisitIndependentClause(const OpenACCIndependentClause &clause) {
331+
if constexpr (isOneOfTypes<OpTy, mlir::acc::LoopOp>) {
332+
operation.addIndependent(builder.getContext(), lastDeviceTypeValues);
333+
} else {
334+
// TODO: When we've implemented this for everything, switch this to an
335+
// unreachable. Routine, Combined constructs remain.
336+
return clauseNotImplemented(clause);
337+
}
338+
}
309339
};
310340

311341
template <typename OpTy>

0 commit comments

Comments
 (0)