Skip to content

Commit 4dccc89

Browse files
authored
merge main into amd-staging (llvm#4587)
2 parents 895d8f0 + 1989bff commit 4dccc89

File tree

107 files changed

+5097
-170
lines changed

Some content is hidden

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

107 files changed

+5097
-170
lines changed

clang-tools-extra/clangd/unittests/lit.cfg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919

2020
if platform.system() == "Darwin":
2121
shlibpath_var = "DYLD_LIBRARY_PATH"
22-
elif platform.system() == "Windows":
22+
elif platform.system() == "Windows" or sys.platform == "cygwin":
2323
shlibpath_var = "PATH"
2424
else:
2525
shlibpath_var = "LD_LIBRARY_PATH"
2626
config.environment[shlibpath_var] = os.path.pathsep.join(
27-
("@SHLIBDIR@", "@LLVM_LIBS_DIR@", config.environment.get(shlibpath_var, ""))
27+
(config.shlibdir, config.llvm_libs_dir, config.environment.get(shlibpath_var, ""))
2828
)
2929

3030
# It is not realistically possible to account for all options that could

clang-tools-extra/include-cleaner/test/Unit/lit.cfg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
if platform.system() == "Darwin":
1313
shlibpath_var = "DYLD_LIBRARY_PATH"
14-
elif platform.system() == "Windows":
14+
elif platform.system() == "Windows" or sys.platform == "cygwin":
1515
shlibpath_var = "PATH"
1616
else:
1717
shlibpath_var = "LD_LIBRARY_PATH"
1818
config.environment[shlibpath_var] = os.path.pathsep.join(
19-
("@SHLIBDIR@", "@LLVM_LIBS_DIR@", config.environment.get(shlibpath_var, ""))
19+
(config.shlibdir, config.llvm_libs_dir, config.environment.get(shlibpath_var, ""))
2020
)
2121

2222
# It is not realistically possible to account for all options that could

clang-tools-extra/test/Unit/lit.cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
if platform.system() == "Darwin":
2323
shlibpath_var = "DYLD_LIBRARY_PATH"
24-
elif platform.system() == "Windows":
24+
elif platform.system() == "Windows" or sys.platform == "cygwin":
2525
shlibpath_var = "PATH"
2626
else:
2727
shlibpath_var = "LD_LIBRARY_PATH"

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
311311
}
312312

313313
/// Create a copy with inferred length.
314-
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src) {
315-
return cir::CopyOp::create(*this, dst.getLoc(), dst, src);
314+
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
315+
bool isVolatile = false) {
316+
return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
316317
}
317318

318319
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,6 +2724,8 @@ def CIR_CopyOp : CIR_Op<"copy",[
27242724
type of `src` and `dst` must match and both must implement the
27252725
`DataLayoutTypeInterface`.
27262726

2727+
The `volatile` keyword indicates that the operation is volatile.
2728+
27272729
Examples:
27282730

27292731
```mlir
@@ -2734,10 +2736,11 @@ def CIR_CopyOp : CIR_Op<"copy",[
27342736

27352737
let arguments = (ins
27362738
Arg<CIR_PointerType, "", [MemWrite]>:$dst,
2737-
Arg<CIR_PointerType, "", [MemRead]>:$src
2739+
Arg<CIR_PointerType, "", [MemRead]>:$src,
2740+
UnitAttr:$is_volatile
27382741
);
27392742

2740-
let assemblyFormat = [{$src `to` $dst
2743+
let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
27412744
attr-dict `:` qualified(type($dst))
27422745
}];
27432746
let hasVerifier = 1;

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,10 @@ struct MissingFeatures {
177177
static bool atomicInfo() { return false; }
178178
static bool atomicInfoGetAtomicPointer() { return false; }
179179
static bool atomicInfoGetAtomicAddress() { return false; }
180-
static bool atomicUseLibCall() { return false; }
181180
static bool atomicScope() { return false; }
182181
static bool atomicSyncScopeID() { return false; }
182+
static bool atomicTypes() { return false; }
183+
static bool atomicUseLibCall() { return false; }
183184

184185
// Global ctor handling
185186
static bool globalCtorLexOrder() { return false; }

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ auto nulloptTypeDecl() {
241241
auto hasNulloptType() { return hasType(nulloptTypeDecl()); }
242242

243243
auto inPlaceClass() {
244-
return recordDecl(hasAnyName("std::in_place_t", "absl::in_place_t",
245-
"base::in_place_t", "folly::in_place_t",
246-
"bsl::in_place_t"));
244+
return namedDecl(hasAnyName("std::in_place_t", "absl::in_place_t",
245+
"base::in_place_t", "folly::in_place_t",
246+
"bsl::in_place_t"));
247247
}
248248

249249
auto isOptionalNulloptConstructor() {

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,16 @@ struct CallStackRestore final : EHScopeStack::Cleanup {
740740
};
741741
} // namespace
742742

743+
/// Push the standard destructor for the given type as
744+
/// at least a normal cleanup.
745+
void CIRGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
746+
Address addr, QualType type) {
747+
assert(dtorKind && "cannot push destructor for trivial type");
748+
749+
CleanupKind cleanupKind = getCleanupKind(dtorKind);
750+
pushDestroy(cleanupKind, addr, type, getDestroyer(dtorKind));
751+
}
752+
743753
void CIRGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
744754
QualType type, Destroyer *destroyer) {
745755
pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type, destroyer);

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,14 +1626,15 @@ LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) {
16261626

16271627
/// Emit code to compute the specified expression which
16281628
/// can have any type. The result is returned as an RValue struct.
1629-
RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
1629+
RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot,
1630+
bool ignoreResult) {
16301631
switch (CIRGenFunction::getEvaluationKind(e->getType())) {
16311632
case cir::TEK_Scalar:
16321633
return RValue::get(emitScalarExpr(e));
16331634
case cir::TEK_Complex:
16341635
return RValue::getComplex(emitComplexExpr(e));
16351636
case cir::TEK_Aggregate: {
1636-
if (aggSlot.isIgnored())
1637+
if (!ignoreResult && aggSlot.isIgnored())
16371638
aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
16381639
getCounterAggTmpAsString());
16391640
emitAggExpr(e, aggSlot);
@@ -1869,8 +1870,7 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
18691870
/// Emit code to compute the specified expression, ignoring the result.
18701871
void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
18711872
if (e->isPRValue()) {
1872-
assert(!cir::MissingFeatures::aggValueSlot());
1873-
emitAnyExpr(e);
1873+
emitAnyExpr(e, AggValueSlot::ignored(), /*ignoreResult=*/true);
18741874
return;
18751875
}
18761876

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,73 @@ using namespace clang;
2424
using namespace clang::CIRGen;
2525

2626
namespace {
27+
// FIXME(cir): This should be a common helper between CIRGen
28+
// and traditional CodeGen
29+
/// Is the value of the given expression possibly a reference to or
30+
/// into a __block variable?
31+
static bool isBlockVarRef(const Expr *e) {
32+
// Make sure we look through parens.
33+
e = e->IgnoreParens();
34+
35+
// Check for a direct reference to a __block variable.
36+
if (const DeclRefExpr *dre = dyn_cast<DeclRefExpr>(e)) {
37+
const VarDecl *var = dyn_cast<VarDecl>(dre->getDecl());
38+
return (var && var->hasAttr<BlocksAttr>());
39+
}
40+
41+
// More complicated stuff.
42+
43+
// Binary operators.
44+
if (const BinaryOperator *op = dyn_cast<BinaryOperator>(e)) {
45+
// For an assignment or pointer-to-member operation, just care
46+
// about the LHS.
47+
if (op->isAssignmentOp() || op->isPtrMemOp())
48+
return isBlockVarRef(op->getLHS());
49+
50+
// For a comma, just care about the RHS.
51+
if (op->getOpcode() == BO_Comma)
52+
return isBlockVarRef(op->getRHS());
53+
54+
// FIXME: pointer arithmetic?
55+
return false;
56+
57+
// Check both sides of a conditional operator.
58+
} else if (const AbstractConditionalOperator *op =
59+
dyn_cast<AbstractConditionalOperator>(e)) {
60+
return isBlockVarRef(op->getTrueExpr()) ||
61+
isBlockVarRef(op->getFalseExpr());
62+
63+
// OVEs are required to support BinaryConditionalOperators.
64+
} else if (const OpaqueValueExpr *op = dyn_cast<OpaqueValueExpr>(e)) {
65+
if (const Expr *src = op->getSourceExpr())
66+
return isBlockVarRef(src);
67+
68+
// Casts are necessary to get things like (*(int*)&var) = foo().
69+
// We don't really care about the kind of cast here, except
70+
// we don't want to look through l2r casts, because it's okay
71+
// to get the *value* in a __block variable.
72+
} else if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
73+
if (cast->getCastKind() == CK_LValueToRValue)
74+
return false;
75+
return isBlockVarRef(cast->getSubExpr());
76+
77+
// Handle unary operators. Again, just aggressively look through
78+
// it, ignoring the operation.
79+
} else if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
80+
return isBlockVarRef(uop->getSubExpr());
81+
82+
// Look into the base of a field access.
83+
} else if (const MemberExpr *mem = dyn_cast<MemberExpr>(e)) {
84+
return isBlockVarRef(mem->getBase());
85+
86+
// Look into the base of a subscript.
87+
} else if (const ArraySubscriptExpr *sub = dyn_cast<ArraySubscriptExpr>(e)) {
88+
return isBlockVarRef(sub->getBase());
89+
}
90+
91+
return false;
92+
}
93+
2794
class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
2895

2996
CIRGenFunction &cgf;
@@ -41,9 +108,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
41108
AggValueSlot ensureSlot(mlir::Location loc, QualType t) {
42109
if (!dest.isIgnored())
43110
return dest;
44-
45-
cgf.cgm.errorNYI(loc, "Slot for ignored address");
46-
return dest;
111+
return cgf.createAggTemp(t, loc, "agg.tmp.ensured");
47112
}
48113

49114
void ensureDest(mlir::Location loc, QualType ty) {
@@ -89,6 +154,47 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
89154
(void)cgf.emitCompoundStmt(*e->getSubStmt(), &retAlloca, dest);
90155
}
91156

157+
void VisitBinAssign(const BinaryOperator *e) {
158+
// For an assignment to work, the value on the right has
159+
// to be compatible with the value on the left.
160+
assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
161+
e->getRHS()->getType()) &&
162+
"Invalid assignment");
163+
164+
if (isBlockVarRef(e->getLHS()) &&
165+
e->getRHS()->HasSideEffects(cgf.getContext())) {
166+
cgf.cgm.errorNYI(e->getSourceRange(),
167+
"block var reference with side effects");
168+
return;
169+
}
170+
171+
LValue lhs = cgf.emitLValue(e->getLHS());
172+
173+
// If we have an atomic type, evaluate into the destination and then
174+
// do an atomic copy.
175+
assert(!cir::MissingFeatures::atomicTypes());
176+
177+
// Codegen the RHS so that it stores directly into the LHS.
178+
assert(!cir::MissingFeatures::aggValueSlotGC());
179+
AggValueSlot lhsSlot = AggValueSlot::forLValue(
180+
lhs, AggValueSlot::IsDestructed, AggValueSlot::IsAliased,
181+
AggValueSlot::MayOverlap);
182+
183+
// A non-volatile aggregate destination might have volatile member.
184+
if (!lhsSlot.isVolatile() && cgf.hasVolatileMember(e->getLHS()->getType()))
185+
lhsSlot.setVolatile(true);
186+
187+
cgf.emitAggExpr(e->getRHS(), lhsSlot);
188+
189+
// Copy into the destination if the assignment isn't ignored.
190+
emitFinalDestCopy(e->getType(), lhs);
191+
192+
if (!dest.isIgnored() && !dest.isExternallyDestructed() &&
193+
e->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
194+
cgf.pushDestroy(QualType::DK_nontrivial_c_struct, dest.getAddress(),
195+
e->getType());
196+
}
197+
92198
void VisitDeclRefExpr(DeclRefExpr *e) { emitAggLoadOfLValue(e); }
93199

94200
void VisitInitListExpr(InitListExpr *e);
@@ -186,9 +292,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
186292
cgf.cgm.errorNYI(e->getSourceRange(),
187293
"AggExprEmitter: VisitPointerToDataMemberBinaryOperator");
188294
}
189-
void VisitBinAssign(const BinaryOperator *e) {
190-
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitBinAssign");
191-
}
192295
void VisitBinComma(const BinaryOperator *e) {
193296
cgf.emitIgnoredExpr(e->getLHS());
194297
Visit(e->getRHS());
@@ -503,7 +606,8 @@ void AggExprEmitter::emitCopy(QualType type, const AggValueSlot &dest,
503606
LValue destLV = cgf.makeAddrLValue(dest.getAddress(), type);
504607
LValue srcLV = cgf.makeAddrLValue(src.getAddress(), type);
505608
assert(!cir::MissingFeatures::aggValueSlotVolatile());
506-
cgf.emitAggregateCopy(destLV, srcLV, type, dest.mayOverlap());
609+
cgf.emitAggregateCopy(destLV, srcLV, type, dest.mayOverlap(),
610+
dest.isVolatile() || src.isVolatile());
507611
}
508612

509613
void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {
@@ -804,7 +908,8 @@ void CIRGenFunction::emitAggExpr(const Expr *e, AggValueSlot slot) {
804908
}
805909

806910
void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
807-
AggValueSlot::Overlap_t mayOverlap) {
911+
AggValueSlot::Overlap_t mayOverlap,
912+
bool isVolatile) {
808913
// TODO(cir): this function needs improvements, commented code for now since
809914
// this will be touched again soon.
810915
assert(!ty->isAnyComplexType() && "Unexpected copy of complex");
@@ -860,7 +965,7 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
860965
cgm.errorNYI("emitAggregateCopy: GC");
861966

862967
[[maybe_unused]] cir::CopyOp copyOp =
863-
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer());
968+
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile);
864969

865970
assert(!cir::MissingFeatures::opTBAA());
866971
}

0 commit comments

Comments
 (0)