Skip to content

Commit a5d2b37

Browse files
committed
merge main into amd-staging
2 parents 6e7e6ed + d1cc137 commit a5d2b37

File tree

111 files changed

+2967
-1632
lines changed

Some content is hidden

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

111 files changed

+2967
-1632
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,8 @@ Improvements to Clang's diagnostics
602602
Moved the warning for a missing (though implied) attribute on a redeclaration into this group.
603603
Added a new warning in this group for the case where the attribute is missing/implicit on
604604
an override of a virtual method.
605+
- Remove ``-Wperf-constraint-implies-noexcept`` from ``-Wall``. This warning is somewhat nit-picky and
606+
attempts to resolve it, by adding ``noexcept``, can create new ways for programs to crash. (#GH167540)
605607
- Implemented diagnostics when retrieving the tuple size for types where its specialization of `std::tuple_size`
606608
produces an invalid size (either negative or greater than the implementation limit). (#GH159563)
607609
- Fixed fix-it hint for fold expressions. Clang now correctly places the suggested right

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1312,7 +1312,7 @@ def Consumed : DiagGroup<"consumed">;
13121312
// DefaultIgnore in addition to putting it here.
13131313
def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool,
13141314
MisleadingIndentation, PackedNonPod,
1315-
VLACxxExtension, PerfConstraintImpliesNoexcept]>;
1315+
VLACxxExtension]>;
13161316

13171317
// Warnings that should be in clang-cl /w4.
13181318
def : DiagGroup<"CL4", [All, Extra]>;

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,10 +631,49 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
631631
lv.getVectorIdx()));
632632
}
633633

634+
if (lv.isExtVectorElt())
635+
return emitLoadOfExtVectorElementLValue(lv);
636+
634637
cgm.errorNYI(loc, "emitLoadOfLValue");
635638
return RValue::get(nullptr);
636639
}
637640

641+
int64_t CIRGenFunction::getAccessedFieldNo(unsigned int idx,
642+
const mlir::ArrayAttr elts) {
643+
auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);
644+
return elt.getInt();
645+
}
646+
647+
// If this is a reference to a subset of the elements of a vector, create an
648+
// appropriate shufflevector.
649+
RValue CIRGenFunction::emitLoadOfExtVectorElementLValue(LValue lv) {
650+
mlir::Location loc = lv.getExtVectorPointer().getLoc();
651+
mlir::Value vec = builder.createLoad(loc, lv.getExtVectorAddress());
652+
653+
// HLSL allows treating scalars as one-element vectors. Converting the scalar
654+
// IR value to a vector here allows the rest of codegen to behave as normal.
655+
if (getLangOpts().HLSL && !mlir::isa<cir::VectorType>(vec.getType())) {
656+
cgm.errorNYI(loc, "emitLoadOfExtVectorElementLValue: HLSL");
657+
return {};
658+
}
659+
660+
const mlir::ArrayAttr elts = lv.getExtVectorElts();
661+
662+
// If the result of the expression is a non-vector type, we must be extracting
663+
// a single element. Just codegen as an extractelement.
664+
const auto *exprVecTy = lv.getType()->getAs<clang::VectorType>();
665+
if (!exprVecTy) {
666+
int64_t indexValue = getAccessedFieldNo(0, elts);
667+
cir::ConstantOp index =
668+
builder.getConstInt(loc, builder.getSInt64Ty(), indexValue);
669+
return RValue::get(cir::VecExtractOp::create(builder, loc, vec, index));
670+
}
671+
672+
cgm.errorNYI(
673+
loc, "emitLoadOfExtVectorElementLValue: Result of expr is vector type");
674+
return {};
675+
}
676+
638677
static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {
639678
assert(!cir::MissingFeatures::weakRefReference());
640679
return cgm.getAddrOfFunction(gd);
@@ -1120,6 +1159,46 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
11201159
return lv;
11211160
}
11221161

1162+
LValue CIRGenFunction::emitExtVectorElementExpr(const ExtVectorElementExpr *e) {
1163+
// Emit the base vector as an l-value.
1164+
LValue base;
1165+
1166+
// ExtVectorElementExpr's base can either be a vector or pointer to vector.
1167+
if (e->isArrow()) {
1168+
cgm.errorNYI(e->getSourceRange(),
1169+
"emitExtVectorElementExpr: pointer to vector");
1170+
return {};
1171+
} else if (e->getBase()->isGLValue()) {
1172+
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
1173+
// emit the base as an lvalue.
1174+
assert(e->getBase()->getType()->isVectorType());
1175+
base = emitLValue(e->getBase());
1176+
} else {
1177+
// Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
1178+
cgm.errorNYI(e->getSourceRange(),
1179+
"emitExtVectorElementExpr: base is a normal rvalue");
1180+
return {};
1181+
}
1182+
1183+
QualType type =
1184+
e->getType().withCVRQualifiers(base.getQuals().getCVRQualifiers());
1185+
1186+
// Encode the element access list into a vector of unsigned indices.
1187+
SmallVector<uint32_t, 4> indices;
1188+
e->getEncodedElementAccess(indices);
1189+
1190+
if (base.isSimple()) {
1191+
SmallVector<int64_t> attrElts(indices.begin(), indices.end());
1192+
mlir::ArrayAttr elts = builder.getI64ArrayAttr(attrElts);
1193+
return LValue::makeExtVectorElt(base.getAddress(), elts, type,
1194+
base.getBaseInfo());
1195+
}
1196+
1197+
cgm.errorNYI(e->getSourceRange(),
1198+
"emitExtVectorElementExpr: isSimple is false");
1199+
return {};
1200+
}
1201+
11231202
LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e,
11241203
llvm::StringRef name) {
11251204
cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e, name);

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,9 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr(
839839
}
840840
}
841841

842+
// Prepare a 'this' for CXXDefaultInitExprs.
843+
CIRGenFunction::FieldConstructionScope fcScope(cgf, dest.getAddress());
844+
842845
LValue destLV = cgf.makeAddrLValue(dest.getAddress(), e->getType());
843846

844847
if (record->isUnion()) {

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
199199
return emitNullValue(e->getType(), cgf.getLoc(e->getSourceRange()));
200200
}
201201

202+
mlir::Value VisitGNUNullExpr(const GNUNullExpr *e) {
203+
return emitNullValue(e->getType(), cgf.getLoc(e->getSourceRange()));
204+
}
205+
202206
mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {
203207
if (e->isGLValue())
204208
return emitLoadOfLValue(cgf.getOrCreateOpaqueLValueMapping(e),
@@ -279,6 +283,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
279283
e->getSourceRange().getBegin());
280284
}
281285

286+
mlir::Value VisitExtVectorElementExpr(Expr *e) { return emitLoadOfLValue(e); }
287+
282288
mlir::Value VisitMemberExpr(MemberExpr *e);
283289

284290
mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,8 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
887887
return emitConditionalOperatorLValue(cast<BinaryConditionalOperator>(e));
888888
case Expr::ArraySubscriptExprClass:
889889
return emitArraySubscriptExpr(cast<ArraySubscriptExpr>(e));
890+
case Expr::ExtVectorElementExprClass:
891+
return emitExtVectorElementExpr(cast<ExtVectorElementExpr>(e));
890892
case Expr::UnaryOperatorClass:
891893
return emitUnaryOpLValue(cast<UnaryOperator>(e));
892894
case Expr::StringLiteralClass:

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,8 @@ class CIRGenFunction : public CIRGenTypeCache {
12771277
QualType &baseType, Address &addr);
12781278
LValue emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e);
12791279

1280+
LValue emitExtVectorElementExpr(const ExtVectorElementExpr *e);
1281+
12801282
Address emitArrayToPointerDecay(const Expr *e,
12811283
LValueBaseInfo *baseInfo = nullptr);
12821284

@@ -1342,6 +1344,8 @@ class CIRGenFunction : public CIRGenTypeCache {
13421344
mlir::Value emittedE,
13431345
bool isDynamic);
13441346

1347+
int64_t getAccessedFieldNo(unsigned idx, mlir::ArrayAttr elts);
1348+
13451349
RValue emitCall(const CIRGenFunctionInfo &funcInfo,
13461350
const CIRGenCallee &callee, ReturnValueSlot returnValue,
13471351
const CallArgList &args, cir::CIRCallOpInterface *callOp,
@@ -1637,6 +1641,8 @@ class CIRGenFunction : public CIRGenTypeCache {
16371641
/// Load a complex number from the specified l-value.
16381642
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc);
16391643

1644+
RValue emitLoadOfExtVectorElementLValue(LValue lv);
1645+
16401646
/// Given an expression that represents a value lvalue, this method emits
16411647
/// the address of the lvalue, then loads the result as an rvalue,
16421648
/// returning the rvalue.

clang/lib/CIR/CodeGen/CIRGenValue.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ class LValue {
166166
// this is the alignment of the whole vector)
167167
unsigned alignment;
168168
mlir::Value v;
169-
mlir::Value vectorIdx; // Index for vector subscript
169+
mlir::Value vectorIdx; // Index for vector subscript
170+
mlir::Attribute vectorElts; // ExtVector element subset: V.xyx
170171
mlir::Type elementType;
171172
LValueBaseInfo baseInfo;
172173
const CIRGenBitFieldInfo *bitFieldInfo{nullptr};
@@ -190,6 +191,7 @@ class LValue {
190191
bool isSimple() const { return lvType == Simple; }
191192
bool isVectorElt() const { return lvType == VectorElt; }
192193
bool isBitField() const { return lvType == BitField; }
194+
bool isExtVectorElt() const { return lvType == ExtVectorElt; }
193195
bool isGlobalReg() const { return lvType == GlobalReg; }
194196
bool isVolatile() const { return quals.hasVolatile(); }
195197

@@ -254,6 +256,22 @@ class LValue {
254256
return vectorIdx;
255257
}
256258

259+
// extended vector elements.
260+
Address getExtVectorAddress() const {
261+
assert(isExtVectorElt());
262+
return Address(getExtVectorPointer(), elementType, getAlignment());
263+
}
264+
265+
mlir::Value getExtVectorPointer() const {
266+
assert(isExtVectorElt());
267+
return v;
268+
}
269+
270+
mlir::ArrayAttr getExtVectorElts() const {
271+
assert(isExtVectorElt());
272+
return mlir::cast<mlir::ArrayAttr>(vectorElts);
273+
}
274+
257275
static LValue makeVectorElt(Address vecAddress, mlir::Value index,
258276
clang::QualType t, LValueBaseInfo baseInfo) {
259277
LValue r;
@@ -265,6 +283,19 @@ class LValue {
265283
return r;
266284
}
267285

286+
static LValue makeExtVectorElt(Address vecAddress, mlir::ArrayAttr elts,
287+
clang::QualType type,
288+
LValueBaseInfo baseInfo) {
289+
LValue r;
290+
r.lvType = ExtVectorElt;
291+
r.v = vecAddress.getPointer();
292+
r.elementType = vecAddress.getElementType();
293+
r.vectorElts = elts;
294+
r.initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
295+
baseInfo);
296+
return r;
297+
}
298+
268299
// bitfield lvalue
269300
Address getBitFieldAddress() const {
270301
return Address(getBitFieldPointer(), elementType, getAlignment());
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
void gnu_null_expr() {
9+
long a = __null;
10+
int *b = __null;
11+
}
12+
13+
// CIR: %[[A_ADDR:.*]] = cir.alloca !s64i, !cir.ptr<!s64i>, ["a", init]
14+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["b", init]
15+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s64i
16+
// CIR: cir.store {{.*}} %[[CONST_0]], %[[A_ADDR]] : !s64i, !cir.ptr<!s64i>
17+
// CIR: %[[CONST_NULL:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i>
18+
// CIR: cir.store {{.*}} %[[CONST_NULL]], %[[B_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
19+
20+
// LLVM: %[[A_ADDR:.*]] = alloca i64, i64 1, align 8
21+
// LLVM: %[[B_ADDR:.*]] = alloca ptr, i64 1, align 8
22+
// LLVM: store i64 0, ptr %[[A_ADDR]], align 8
23+
// LLVM: store ptr null, ptr %[[B_ADDR]], align 8
24+
25+
// OGCG: %[[A_ADDR:.*]] = alloca i64, align 8
26+
// OGCG: %[[B_ADDR:.*]] = alloca ptr, align 8
27+
// OGCG: store i64 0, ptr %[[A_ADDR]], align 8
28+
// OGCG: store ptr null, ptr %[[B_ADDR]], align 8

clang/test/CIR/CodeGen/struct-init.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,26 @@ void init_expr(int a, int b, int c) {
205205
// OGCG: %[[C_PLUS_THREE:.*]] = add nsw i32 %[[C]], 3
206206
// OGCG: store i32 %[[C_PLUS_THREE]], ptr %[[S_C]]
207207
// OGCG: ret void
208+
209+
void cxx_default_init_with_struct_field() {
210+
struct Parent {
211+
int getA();
212+
int a = getA();
213+
};
214+
Parent p = Parent{};
215+
}
216+
217+
// CIR: %[[P_ADDR:.*]] = cir.alloca !rec_Parent, !cir.ptr<!rec_Parent>, ["p", init]
218+
// CIR: %[[P_ELEM_0_PTR:.*]] = cir.get_member %[[P_ADDR]][0] {name = "a"} : !cir.ptr<!rec_Parent> -> !cir.ptr<!s32i>
219+
// CIR: %[[METHOD_CALL:.*]] = cir.call @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(%[[P_ADDR]]) : (!cir.ptr<!rec_Parent>) -> !s32i
220+
// CIR: cir.store{{.*}} %[[METHOD_CALL]], %[[P_ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
221+
222+
// LLVM: %[[P_ADDR:.*]] = alloca %struct.Parent, i64 1, align 4
223+
// LLVM: %[[P_ELEM_0_PTR:.*]] = getelementptr %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0
224+
// LLVM: %[[METHOD_CALL:.*]] = call i32 @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(ptr %[[P_ADDR]])
225+
// LLVM: store i32 %[[METHOD_CALL]], ptr %[[P_ELEM_0_PTR]], align 4
226+
227+
// OGCG: %[[P_ADDR:.*]] = alloca %struct.Parent, align 4
228+
// OGCG: %[[P_ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0
229+
// OGCG: %[[METHOD_CALL:.*]] = call noundef i32 @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(ptr {{.*}} %[[P_ADDR]])
230+
// OGCG: store i32 %[[METHOD_CALL]], ptr %[[P_ELEM_0_PTR]], align 4

0 commit comments

Comments
 (0)