Skip to content

Commit a65b329

Browse files
authored
merge main into amd-staging (llvm#1988)
2 parents 467b8af + abc262f commit a65b329

File tree

101 files changed

+2161
-1062
lines changed

Some content is hidden

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

101 files changed

+2161
-1062
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6476,6 +6476,8 @@ class Sema final : public SemaBase {
64766476
void setupImplicitSpecialMemberType(CXXMethodDecl *SpecialMem,
64776477
QualType ResultTy,
64786478
ArrayRef<QualType> Args);
6479+
// Helper for ActOnFields to check for all function pointer members.
6480+
bool EntirelyFunctionPointers(const RecordDecl *Record);
64796481

64806482
// A cache representing if we've fully checked the various comparison category
64816483
// types stored in ASTContext. The bit-index corresponds to the integer value

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,11 +1684,6 @@ mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
16841684
return {};
16851685
}
16861686

1687-
if (numInitElements == 0) {
1688-
cgf.cgm.errorNYI(e->getSourceRange(), "InitListExpr with 0 init elements");
1689-
return {};
1690-
}
1691-
16921687
if (e->getType()->isVectorType()) {
16931688
const auto vectorType =
16941689
mlir::cast<cir::VectorType>(cgf.convertType(e->getType()));
@@ -1710,6 +1705,12 @@ mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
17101705
cgf.getLoc(e->getSourceRange()), vectorType, elements);
17111706
}
17121707

1708+
if (numInitElements == 0) {
1709+
cgf.cgm.errorNYI(e->getSourceRange(),
1710+
"InitListExpr Non VectorType with 0 init elements");
1711+
return {};
1712+
}
1713+
17131714
return Visit(e->getInit(0));
17141715
}
17151716

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "CGCXXABI.h"
1414
#include "CGCleanup.h"
1515
#include "CGDebugInfo.h"
16+
#include "CGHLSLRuntime.h"
1617
#include "CGObjCRuntime.h"
1718
#include "CGOpenMPRuntime.h"
1819
#include "CGRecordLayout.h"
@@ -2095,6 +2096,18 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
20952096
assert (Ignore == false && "init list ignored");
20962097
unsigned NumInitElements = E->getNumInits();
20972098

2099+
// HLSL initialization lists in the AST are an expansion which can contain
2100+
// side-effecting expressions wrapped in opaque value expressions. To properly
2101+
// emit these we need to emit the opaque values before we emit the argument
2102+
// expressions themselves. This is a little hacky, but it prevents us needing
2103+
// to do a bigger AST-level change for a language feature that we need
2104+
// deprecate in the near future. See related HLSL language proposals in the
2105+
// proposals (https://github.com/microsoft/hlsl-specs/blob/main/proposals):
2106+
// * 0005-strict-initializer-lists.md
2107+
// * 0032-constructors.md
2108+
if (CGF.getLangOpts().HLSL)
2109+
CGF.CGM.getHLSLRuntime().emitInitListOpaqueValues(CGF, E);
2110+
20982111
if (E->hadArrayRangeDesignator())
20992112
CGF.ErrorUnsupported(E, "GNU array range designator extension");
21002113

clang/lib/Lex/PPExpressions.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -903,9 +903,8 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
903903
SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());
904904
if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
905905
// Parse error, skip the rest of the macro line.
906-
SourceRange ConditionRange = ExprStartLoc;
907906
if (Tok.isNot(tok::eod))
908-
ConditionRange = DiscardUntilEndOfDirective(Tok);
907+
DiscardUntilEndOfDirective(Tok);
909908

910909
// Restore 'DisableMacroExpansion'.
911910
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
@@ -916,7 +915,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
916915
return {std::nullopt,
917916
false,
918917
DT.IncludedUndefinedIds,
919-
{ExprStartLoc, ConditionRange.getEnd()}};
918+
{ExprStartLoc, Tok.getLocation()}};
920919
}
921920

922921
EvaluatedDefined = DT.State != DefinedTracker::Unknown;
@@ -948,8 +947,10 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
948947

949948
// Restore 'DisableMacroExpansion'.
950949
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
951-
SourceRange ValRange = ResVal.getRange();
952-
return {std::nullopt, false, DT.IncludedUndefinedIds, ValRange};
950+
return {std::nullopt,
951+
false,
952+
DT.IncludedUndefinedIds,
953+
{ExprStartLoc, Tok.getLocation()}};
953954
}
954955

955956
if (CheckForEoD) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19309,6 +19309,43 @@ static void ComputeSpecialMemberFunctionsEligiblity(Sema &S,
1930919309
CXXSpecialMemberKind::MoveAssignment);
1931019310
}
1931119311

19312+
bool Sema::EntirelyFunctionPointers(const RecordDecl *Record) {
19313+
// Check to see if a FieldDecl is a pointer to a function.
19314+
auto IsFunctionPointerOrForwardDecl = [&](const Decl *D) {
19315+
const FieldDecl *FD = dyn_cast<FieldDecl>(D);
19316+
if (!FD) {
19317+
// Check whether this is a forward declaration that was inserted by
19318+
// Clang. This happens when a non-forward declared / defined type is
19319+
// used, e.g.:
19320+
//
19321+
// struct foo {
19322+
// struct bar *(*f)();
19323+
// struct bar *(*g)();
19324+
// };
19325+
//
19326+
// "struct bar" shows up in the decl AST as a "RecordDecl" with an
19327+
// incomplete definition.
19328+
if (const auto *TD = dyn_cast<TagDecl>(D))
19329+
return !TD->isCompleteDefinition();
19330+
return false;
19331+
}
19332+
QualType FieldType = FD->getType().getDesugaredType(Context);
19333+
if (isa<PointerType>(FieldType)) {
19334+
QualType PointeeType = cast<PointerType>(FieldType)->getPointeeType();
19335+
return PointeeType.getDesugaredType(Context)->isFunctionType();
19336+
}
19337+
// If a member is a struct entirely of function pointers, that counts too.
19338+
if (const RecordType *RT = FieldType->getAs<RecordType>()) {
19339+
const RecordDecl *Record = RT->getDecl();
19340+
if (Record->isStruct() && EntirelyFunctionPointers(Record))
19341+
return true;
19342+
}
19343+
return false;
19344+
};
19345+
19346+
return llvm::all_of(Record->decls(), IsFunctionPointerOrForwardDecl);
19347+
}
19348+
1931219349
void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1931319350
ArrayRef<Decl *> Fields, SourceLocation LBrac,
1931419351
SourceLocation RBrac,
@@ -19646,41 +19683,13 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1964619683
// Handle attributes before checking the layout.
1964719684
ProcessDeclAttributeList(S, Record, Attrs);
1964819685

19649-
// Check to see if a FieldDecl is a pointer to a function.
19650-
auto IsFunctionPointerOrForwardDecl = [&](const Decl *D) {
19651-
const FieldDecl *FD = dyn_cast<FieldDecl>(D);
19652-
if (!FD) {
19653-
// Check whether this is a forward declaration that was inserted by
19654-
// Clang. This happens when a non-forward declared / defined type is
19655-
// used, e.g.:
19656-
//
19657-
// struct foo {
19658-
// struct bar *(*f)();
19659-
// struct bar *(*g)();
19660-
// };
19661-
//
19662-
// "struct bar" shows up in the decl AST as a "RecordDecl" with an
19663-
// incomplete definition.
19664-
if (const auto *TD = dyn_cast<TagDecl>(D))
19665-
return !TD->isCompleteDefinition();
19666-
return false;
19667-
}
19668-
QualType FieldType = FD->getType().getDesugaredType(Context);
19669-
if (isa<PointerType>(FieldType)) {
19670-
QualType PointeeType = cast<PointerType>(FieldType)->getPointeeType();
19671-
return PointeeType.getDesugaredType(Context)->isFunctionType();
19672-
}
19673-
return false;
19674-
};
19675-
1967619686
// Maybe randomize the record's decls. We automatically randomize a record
1967719687
// of function pointers, unless it has the "no_randomize_layout" attribute.
19678-
if (!getLangOpts().CPlusPlus &&
19688+
if (!getLangOpts().CPlusPlus && !getLangOpts().RandstructSeed.empty() &&
19689+
!Record->isRandomized() && !Record->isUnion() &&
1967919690
(Record->hasAttr<RandomizeLayoutAttr>() ||
1968019691
(!Record->hasAttr<NoRandomizeLayoutAttr>() &&
19681-
llvm::all_of(Record->decls(), IsFunctionPointerOrForwardDecl))) &&
19682-
!Record->isUnion() && !getLangOpts().RandstructSeed.empty() &&
19683-
!Record->isRandomized()) {
19692+
EntirelyFunctionPointers(Record)))) {
1968419693
SmallVector<Decl *, 32> NewDeclOrdering;
1968519694
if (randstruct::randomizeStructureLayout(Context, Record,
1968619695
NewDeclOrdering))

clang/test/CIR/CodeGen/vector-ext.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ void foo() {
6161
vi4 f = { x, 5, 6, x + 1 };
6262

6363
vi4 g = { 5 };
64+
65+
vi4 h = {};
6466
}
6567

6668
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
@@ -70,12 +72,33 @@ void foo() {
7072
// CIR: %[[VEC_E:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["e", init]
7173
// CIR: %[[VEC_F:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["f", init]
7274
// CIR: %[[VEC_G:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["g", init]
73-
// CIR: %[[VEC_E_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
75+
// CIR: %[[VEC_H:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["h", init]
76+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
77+
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
78+
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
79+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
80+
// CIR: %[[VEC_E_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
81+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
7482
// CIR: cir.store %[[VEC_E_VAL]], %[[VEC_E]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
75-
// CIR: %[[VEC_F_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
83+
// CIR: %[[GLOBAL_X:.*]] = cir.get_global @x : !cir.ptr<!s32i>
84+
// CIR: %[[X_VAL:.*]] = cir.load %[[GLOBAL_X]] : !cir.ptr<!s32i>, !s32i
85+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
86+
// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i
87+
// CIR: %[[GLOBAL_X:.*]] = cir.get_global @x : !cir.ptr<!s32i>
88+
// CIR: %[[X:.*]] = cir.load %[[GLOBAL_X]] : !cir.ptr<!s32i>, !s32i
89+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
90+
// CIR: %[[X_PLUS_1:.*]] = cir.binop(add, %[[X]], %[[CONST_1]]) nsw : !s32i
91+
// CIR: %[[VEC_F_VAL:.*]] = cir.vec.create(%[[X_VAL]], %[[CONST_5]], %[[CONST_6]], %[[X_PLUS_1]] :
92+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
7693
// CIR: cir.store %[[VEC_F_VAL]], %[[VEC_F]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
77-
// CIR: %[[VEC_G_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
94+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
95+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
96+
// CIR: %[[VEC_G_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_0]], %[[CONST_0]], %[[CONST_0]] :
97+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
7898
// CIR: cir.store %[[VEC_G_VAL]], %[[VEC_G]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
99+
// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
100+
// CIR: %[[VEC_H_VAL:.*]] = cir.vec.create(%[[ZERO]], %[[ZERO]], %[[ZERO]], %[[ZERO]] : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
101+
// CIR: cir.store %[[VEC_H_VAL]], %[[VEC_H]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
79102

80103
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
81104
// LLVM: %[[VEC_B:.*]] = alloca <3 x i32>, i64 1, align 16
@@ -84,9 +107,11 @@ void foo() {
84107
// LLVM: %[[VEC_E:.*]] = alloca <4 x i32>, i64 1, align 16
85108
// LLVM: %[[VEC_F:.*]] = alloca <4 x i32>, i64 1, align 16
86109
// LLVM: %[[VEC_G:.*]] = alloca <4 x i32>, i64 1, align 16
110+
// LLVM: %[[VEC_H:.*]] = alloca <4 x i32>, i64 1, align 16
87111
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_E]], align 16
88112
// LLVM: store <4 x i32> {{.*}}, ptr %[[VEC_F]], align 16
89113
// LLVM: store <4 x i32> <i32 5, i32 0, i32 0, i32 0>, ptr %[[VEC_G]], align 16
114+
// LLVM: store <4 x i32> zeroinitializer, ptr %[[VEC_H]], align 16
90115

91116
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
92117
// OGCG: %[[VEC_B:.*]] = alloca <3 x i32>, align 16
@@ -95,9 +120,11 @@ void foo() {
95120
// OGCG: %[[VEC_E:.*]] = alloca <4 x i32>, align 16
96121
// OGCG: %[[VEC_F:.*]] = alloca <4 x i32>, align 16
97122
// OGCG: %[[VEC_G:.*]] = alloca <4 x i32>, align 16
123+
// OGCG: %[[VEC_H:.*]] = alloca <4 x i32>, align 16
98124
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_E]], align 16
99125
// OGCG: store <4 x i32> {{.*}}, ptr %[[VEC_F]], align 16
100126
// OGCG: store <4 x i32> <i32 5, i32 0, i32 0, i32 0>, ptr %[[VEC_G]], align 16
127+
// OGCG: store <4 x i32> zeroinitializer, ptr %[[VEC_H]], align 16
101128

102129
void foo2(vi4 p) {}
103130

clang/test/CIR/CodeGen/vector.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ void foo() {
5151
vi4 e = { x, 5, 6, x + 1 };
5252

5353
vi4 f = { 5 };
54+
55+
vi4 g = {};
5456
}
5557

5658
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
@@ -59,32 +61,58 @@ void foo() {
5961
// CIR: %[[VEC_D:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["d", init]
6062
// CIR: %[[VEC_E:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["e", init]
6163
// CIR: %[[VEC_F:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["f", init]
62-
// CIR: %[[VEC_D_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
64+
// CIR: %[[VEC_G:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["g", init]
65+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
66+
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
67+
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
68+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
69+
// CIR: %[[VEC_D_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
70+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
6371
// CIR: cir.store %[[VEC_D_VAL]], %[[VEC_D]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
64-
// CIR: %[[VEC_E_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
72+
// CIR: %[[GLOBAL_X:.*]] = cir.get_global @x : !cir.ptr<!s32i>
73+
// CIR: %[[X_VAL:.*]] = cir.load %[[GLOBAL_X]] : !cir.ptr<!s32i>, !s32i
74+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
75+
// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i
76+
// CIR: %[[GLOBAL_X:.*]] = cir.get_global @x : !cir.ptr<!s32i>
77+
// CIR: %[[X:.*]] = cir.load %[[GLOBAL_X]] : !cir.ptr<!s32i>, !s32i
78+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
79+
// CIR: %[[X_PLUS_1:.*]] = cir.binop(add, %[[X]], %[[CONST_1]]) nsw : !s32i
80+
// CIR: %[[VEC_E_VAL:.*]] = cir.vec.create(%[[X_VAL]], %[[CONST_5]], %[[CONST_6]], %[[X_PLUS_1]] :
81+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
6582
// CIR: cir.store %[[VEC_E_VAL]], %[[VEC_E]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
66-
// CIR: %[[VEC_F_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
83+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
84+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
85+
// CIR: %[[VEC_F_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_0]], %[[CONST_0]], %[[CONST_0]] :
86+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
6787
// CIR: cir.store %[[VEC_F_VAL]], %[[VEC_F]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
88+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
89+
// CIR: %[[VEC_G_VAL:.*]] = cir.vec.create(%[[CONST_0]], %[[CONST_0]], %[[CONST_0]], %[[CONST_0]] :
90+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
91+
// CIR: cir.store %[[VEC_G_VAL]], %[[VEC_G]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
6892

6993
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
7094
// LLVM: %[[VEC_B:.*]] = alloca <2 x double>, i64 1, align 16
7195
// LLVM: %[[VEC_C:.*]] = alloca <2 x i64>, i64 1, align 16
7296
// LLVM: %[[VEC_D:.*]] = alloca <4 x i32>, i64 1, align 16
7397
// LLVM: %[[VEC_E:.*]] = alloca <4 x i32>, i64 1, align 16
7498
// LLVM: %[[VEC_F:.*]] = alloca <4 x i32>, i64 1, align 16
99+
// LLVM: %[[VEC_G:.*]] = alloca <4 x i32>, i64 1, align 16
75100
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_D]], align 16
76101
// LLVM: store <4 x i32> {{.*}}, ptr %[[VEC_E]], align 16
77102
// LLVM: store <4 x i32> <i32 5, i32 0, i32 0, i32 0>, ptr %[[VEC_F]], align 16
103+
// LLVM: store <4 x i32> zeroinitializer, ptr %[[VEC_G]], align 16
78104

79105
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
80106
// OGCG: %[[VEC_B:.*]] = alloca <2 x double>, align 16
81107
// OGCG: %[[VEC_C:.*]] = alloca <2 x i64>, align 16
82108
// OGCG: %[[VEC_D:.*]] = alloca <4 x i32>, align 16
83109
// OGCG: %[[VEC_E:.*]] = alloca <4 x i32>, align 16
84110
// OGCG: %[[VEC_F:.*]] = alloca <4 x i32>, align 16
111+
// OGCG: %[[VEC_G:.*]] = alloca <4 x i32>, align 16
85112
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_D]], align 16
86113
// OGCG: store <4 x i32> {{.*}}, ptr %[[VEC_E]], align 16
87114
// OGCG: store <4 x i32> <i32 5, i32 0, i32 0, i32 0>, ptr %[[VEC_F]], align 16
115+
// OGCG: store <4 x i32> zeroinitializer, ptr %[[VEC_G]], align 16
88116

89117
void foo2(vi4 p) {}
90118

clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,3 +941,21 @@ FourFloats case16() {
941941
FourFloats FF = {0, makeTwo(X), 3};
942942
return FF;
943943
}
944+
945+
946+
int case17Helper(int x) {
947+
return x;
948+
}
949+
950+
// InitList with OpaqueValueExpr
951+
// CHECK-LABEL: define void {{.*}}case17
952+
// CHECK: [[X:%.*]] = alloca <2 x i32>, align 8
953+
// CHECK-NEXT: [[C:%.*]] = call noundef i32 {{.*}}case17Helper{{.*}}(i32 noundef 0)
954+
// CHECK-NEXT: [[C1:%.*]] = call noundef i32 {{.*}}case17Helper{{.*}}(i32 noundef 1)
955+
// CHECK-NEXT: [[VI:%.*]] = insertelement <2 x i32> poison, i32 [[C]], i32 0
956+
// CHECK-NEXT: [[VI2:%.*]] = insertelement <2 x i32> [[VI]], i32 [[C1]], i32 1
957+
// CHECK-NEXT: store <2 x i32> [[VI2]], ptr [[X]], align 8
958+
// CHECK-NEXT: ret void
959+
void case17() {
960+
int2 X = {case17Helper(0), case17Helper(1)};
961+
}

clang/test/Sema/init-randomized-struct.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,49 @@ struct enum_decl_test {
7575
} __attribute__((randomize_layout));
7676

7777
struct enum_decl_test t13 = { BORK }; // Okay
78+
79+
struct mixed {
80+
int a;
81+
short b;
82+
unsigned c;
83+
char d;
84+
} __attribute__((randomize_layout));
85+
86+
struct mixed t14 = { 7 }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
87+
struct mixed t15 = { .b = 8 }; // Okay
88+
89+
// This should be autodetected as randomized.
90+
struct funcs {
91+
func_ptr a;
92+
func_ptr b;
93+
func_ptr c;
94+
func_ptr d;
95+
};
96+
97+
struct funcs t16 = { .c = foo }; // Okay
98+
struct funcs t17 = { foo }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
99+
100+
// This should be forced off.
101+
struct funcs_unshuffled {
102+
func_ptr a;
103+
func_ptr b;
104+
func_ptr c;
105+
func_ptr d;
106+
} __attribute__((no_randomize_layout));
107+
108+
struct funcs_unshuffled t18 = { .d = foo }; // Okay
109+
struct funcs_unshuffled t19 = { foo }; // Okay
110+
111+
// This is still all function pointers.
112+
// https://github.com/llvm/llvm-project/issues/138355
113+
struct funcs_composite {
114+
func_ptr a;
115+
func_ptr b;
116+
struct funcs inner;
117+
func_ptr c;
118+
func_ptr d;
119+
};
120+
121+
struct funcs_composite t20 = { .a = foo }; // Okay
122+
struct funcs_composite t21 = { .inner.c = foo }; // Okay
123+
struct funcs_composite t22 = { foo }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}

0 commit comments

Comments
 (0)