Skip to content

[SYCL] Refactor SYCL path for work_group_size_hint #7961

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

Merged
merged 3 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 24 additions & 4 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3497,35 +3497,55 @@ def SYCLReqdWorkGroupSize : InheritableAttr, LanguageOptionsSpecificAttr {
let HasCustomParsing = 1;
}

def WorkGroupSizeHint : InheritableAttr {
def WorkGroupSizeHint : InheritableAttr, LanguageOptionsSpecificAttr {
let Spellings = [GNU<"work_group_size_hint">,
CXX11<"sycl", "work_group_size_hint">];
let Args = [UnsignedArgument<"XDim">,
UnsignedArgument<"YDim">,
UnsignedArgument<"ZDim">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [WorkGroupSizeHintAttrDocs];
let LangOpts = [NotSYCL];
let SupportsNonconformingLambdaSyntax = 1;
let ParseKind = "WorkGroupSizeHint";
let HasCustomParsing = 1;
}

def SYCLWorkGroupSizeHint : InheritableAttr, LanguageOptionsSpecificAttr {
let Spellings = [GNU<"work_group_size_hint">,
CXX11<"sycl", "work_group_size_hint">];
let Args = [ExprArgument<"XDim">,
ExprArgument<"YDim", /*optional*/1>,
ExprArgument<"ZDim", /*optional*/1>];
let Subjects = SubjectList<[Function], ErrorDiag>;
// In OpenCL C this attribute takes no default values whereas in SYCL it does.
// To avoid confusing diagnostics, the checks are deferred to "handleWorkGroupSizeHint".
// To avoid confusing diagnostics, the checks are deferred to
// "handleWorkGroupSizeHint".
let HasCustomParsing = 1;
let AdditionalMembers = [{
Optional<llvm::APSInt> getXDimVal() const {
// X-dimension is not optional.
if (const auto *CE = dyn_cast<ConstantExpr>(getXDim()))
return CE->getResultAsAPSInt();
return std::nullopt;
}
Optional<llvm::APSInt> getYDimVal() const {
if (const auto *CE = dyn_cast<ConstantExpr>(getYDim()))
// Y-dimension is optional so a nullptr value is allowed.
if (const auto *CE = dyn_cast_or_null<ConstantExpr>(getYDim()))
return CE->getResultAsAPSInt();
return std::nullopt;
}
Optional<llvm::APSInt> getZDimVal() const {
if (const auto *CE = dyn_cast<ConstantExpr>(getZDim()))
// Z-dimension is optional so a nullptr value is allowed.
if (const auto *CE = dyn_cast_or_null<ConstantExpr>(getZDim()))
return CE->getResultAsAPSInt();
return std::nullopt;
}
}];
let Documentation = [WorkGroupSizeHintAttrDocs];
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
let SupportsNonconformingLambdaSyntax = 1;
let ParseKind = "WorkGroupSizeHint";
}

def InitPriority : InheritableAttr, TargetSpecificAttr<TargetSupportsInitPriority> {
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -10997,10 +10997,10 @@ class Sema final {
bool AllWorkGroupSizesSame(const Expr *LHSXDim, const Expr *LHSYDim,
const Expr *LHSZDim, const Expr *RHSXDim,
const Expr *RHSYDim, const Expr *RHSZDim);
void AddWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XDim, Expr *YDim, Expr *ZDim);
WorkGroupSizeHintAttr *
MergeWorkGroupSizeHintAttr(Decl *D, const WorkGroupSizeHintAttr &A);
void AddSYCLWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XDim, Expr *YDim, Expr *ZDim);
SYCLWorkGroupSizeHintAttr *
MergeSYCLWorkGroupSizeHintAttr(Decl *D, const SYCLWorkGroupSizeHintAttr &A);
void AddIntelReqdSubGroupSize(Decl *D, const AttributeCommonInfo &CI,
Expr *E);
IntelReqdSubGroupSizeAttr *
Expand Down
27 changes: 24 additions & 3 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,12 +613,33 @@ void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,

if (const WorkGroupSizeHintAttr *A = FD->getAttr<WorkGroupSizeHintAttr>()) {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getXDimVal())),
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getYDimVal())),
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getZDimVal()))};
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
}

if (const SYCLWorkGroupSizeHintAttr *A =
FD->getAttr<SYCLWorkGroupSizeHintAttr>()) {
llvm::Optional<llvm::APSInt> XDimVal = A->getXDimVal();
llvm::Optional<llvm::APSInt> YDimVal = A->getYDimVal();
llvm::Optional<llvm::APSInt> ZDimVal = A->getZDimVal();
llvm::SmallVector<llvm::Metadata *, 3> AttrMDArgs;

// On SYCL target the dimensions are reversed if present.
if (ZDimVal)
AttrMDArgs.push_back(
llvm::ConstantAsMetadata::get(Builder.getInt(*ZDimVal)));
if (YDimVal)
AttrMDArgs.push_back(
llvm::ConstantAsMetadata::get(Builder.getInt(*YDimVal)));
AttrMDArgs.push_back(
llvm::ConstantAsMetadata::get(Builder.getInt(*XDimVal)));

Fn->setMetadata("work_group_size_hint",
llvm::MDNode::get(Context, AttrMDArgs));
}

if (const ReqdWorkGroupSizeAttr *A = FD->getAttr<ReqdWorkGroupSizeAttr>()) {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2971,8 +2971,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
NewAttr = S.MergeSYCLIntelForcePow2DepthAttr(D, *A);
else if (const auto *A = dyn_cast<SYCLIntelInitiationIntervalAttr>(Attr))
NewAttr = S.MergeSYCLIntelInitiationIntervalAttr(D, *A);
else if (const auto *A = dyn_cast<WorkGroupSizeHintAttr>(Attr))
NewAttr = S.MergeWorkGroupSizeHintAttr(D, *A);
else if (const auto *A = dyn_cast<SYCLWorkGroupSizeHintAttr>(Attr))
NewAttr = S.MergeSYCLWorkGroupSizeHintAttr(D, *A);
else if (const auto *A = dyn_cast<SYCLIntelMaxGlobalWorkDimAttr>(Attr))
NewAttr = S.MergeSYCLIntelMaxGlobalWorkDimAttr(D, *A);
else if (const auto *BTFA = dyn_cast<BTFDeclTagAttr>(Attr))
Expand Down
82 changes: 44 additions & 38 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3275,6 +3275,9 @@ static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Handles reqd_work_group_size and work_group_size_hint.
template <typename WorkGroupAttr>
static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!AL.checkExactlyNumArgs(S, 3))
return;

uint32_t WGSize[3];
for (unsigned i = 0; i < 3; ++i) {
const Expr *E = AL.getArgAsExpr(i);
Expand Down Expand Up @@ -3348,24 +3351,24 @@ bool Sema::AllWorkGroupSizesSame(const Expr *LHSXDim, const Expr *LHSYDim,
[](DupArgResult V) { return V == DupArgResult::Same; });
}

void Sema::AddWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XDim, Expr *YDim, Expr *ZDim) {
void Sema::AddSYCLWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XDim, Expr *YDim, Expr *ZDim) {
// Returns nullptr if diagnosing, otherwise returns the original expression
// or the original expression converted to a constant expression.
auto CheckAndConvertArg = [&](Expr *E) -> Expr * {
auto CheckAndConvertArg = [&](Expr *E) -> Optional<Expr *> {
// We can only check if the expression is not value dependent.
if (!E->isValueDependent()) {
if (E && !E->isValueDependent()) {
llvm::APSInt ArgVal;
ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal);
if (Res.isInvalid())
return nullptr;
return std::nullopt;
E = Res.get();

// This attribute requires a strictly positive value.
if (ArgVal <= 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< CI << /*positive*/ 0;
return nullptr;
return std::nullopt;
}
}

Expand All @@ -3374,15 +3377,18 @@ void Sema::AddWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,

// Check all three argument values, and if any are bad, bail out. This will
// convert the given expressions into constant expressions when possible.
XDim = CheckAndConvertArg(XDim);
YDim = CheckAndConvertArg(YDim);
ZDim = CheckAndConvertArg(ZDim);
if (!XDim || !YDim || !ZDim)
Optional<Expr *> XDimConvert = CheckAndConvertArg(XDim);
Optional<Expr *> YDimConvert = CheckAndConvertArg(YDim);
Optional<Expr *> ZDimConvert = CheckAndConvertArg(ZDim);
if (!XDimConvert || !YDimConvert || !ZDimConvert)
return;
XDim = XDimConvert.value();
YDim = YDimConvert.value();
ZDim = ZDimConvert.value();

// If the attribute was already applied with different arguments, then
// diagnose the second attribute as a duplicate and don't add it.
if (const auto *Existing = D->getAttr<WorkGroupSizeHintAttr>()) {
if (const auto *Existing = D->getAttr<SYCLWorkGroupSizeHintAttr>()) {
// If any of the results are known to be different, we can diagnose at this
// point and drop the attribute.
if (AnyWorkGroupSizesDiffer(XDim, YDim, ZDim, Existing->getXDim(),
Expand All @@ -3400,13 +3406,14 @@ void Sema::AddWorkGroupSizeHintAttr(Decl *D, const AttributeCommonInfo &CI,
}

D->addAttr(::new (Context)
WorkGroupSizeHintAttr(Context, CI, XDim, YDim, ZDim));
SYCLWorkGroupSizeHintAttr(Context, CI, XDim, YDim, ZDim));
}

WorkGroupSizeHintAttr *
Sema::MergeWorkGroupSizeHintAttr(Decl *D, const WorkGroupSizeHintAttr &A) {
SYCLWorkGroupSizeHintAttr *
Sema::MergeSYCLWorkGroupSizeHintAttr(Decl *D,
const SYCLWorkGroupSizeHintAttr &A) {
// Check to see if there's a duplicate attribute already applied.
if (const auto *DeclAttr = D->getAttr<WorkGroupSizeHintAttr>()) {
if (const auto *DeclAttr = D->getAttr<SYCLWorkGroupSizeHintAttr>()) {
// If any of the results are known to be different, we can diagnose at this
// point and drop the attribute.
if (AnyWorkGroupSizesDiffer(DeclAttr->getXDim(), DeclAttr->getYDim(),
Expand All @@ -3424,40 +3431,36 @@ Sema::MergeWorkGroupSizeHintAttr(Decl *D, const WorkGroupSizeHintAttr &A) {
A.getZDim()))
return nullptr;
}
return ::new (Context)
WorkGroupSizeHintAttr(Context, A, A.getXDim(), A.getYDim(), A.getZDim());
return ::new (Context) SYCLWorkGroupSizeHintAttr(Context, A, A.getXDim(),
A.getYDim(), A.getZDim());
}

// Handles work_group_size_hint.
static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
// Handles SYCL work_group_size_hint.
static void handleSYCLWorkGroupSizeHint(Sema &S, Decl *D,
const ParsedAttr &AL) {
S.CheckDeprecatedSYCLAttributeSpelling(AL);

// __attribute__((work_group_size_hint) requires exactly three arguments.
if (AL.getSyntax() == ParsedAttr::AS_GNU || !AL.hasScope() ||
(AL.hasScope() && !AL.getScopeName()->isStr("sycl"))) {
if (!AL.checkExactlyNumArgs(S, 3))
return;
}

// FIXME: NumArgs checking is disabled in Attr.td to keep consistent
// disgnostics with OpenCL C that does not have optional values here.
if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
} else if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
return;

// Handles default arguments in [[sycl::work_group_size_hint]] attribute.
auto SetDefaultValue = [](Sema &S, const ParsedAttr &AL) {
assert(AL.getKind() == ParsedAttr::AT_WorkGroupSizeHint && AL.hasScope() &&
AL.getScopeName()->isStr("sycl"));
return IntegerLiteral::Create(S.Context, llvm::APInt(32, 1),
S.Context.IntTy, AL.getLoc());
};
size_t NumArgs = AL.getNumArgs();
Expr *XDimExpr = NumArgs > 0 ? AL.getArgAsExpr(0) : nullptr;
Expr *YDimExpr = NumArgs > 1 ? AL.getArgAsExpr(1) : nullptr;
Expr *ZDimExpr = NumArgs > 2 ? AL.getArgAsExpr(2) : nullptr;
S.AddSYCLWorkGroupSizeHintAttr(D, AL, XDimExpr, YDimExpr, ZDimExpr);
}

Expr *XDimExpr = AL.getArgAsExpr(0);
Expr *YDimExpr =
AL.isArgExpr(1) ? AL.getArgAsExpr(1) : SetDefaultValue(S, AL);
Expr *ZDimExpr =
AL.isArgExpr(2) ? AL.getArgAsExpr(2) : SetDefaultValue(S, AL);
S.AddWorkGroupSizeHintAttr(D, AL, XDimExpr, YDimExpr, ZDimExpr);
static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
// Handle the attribute based on whether we are targeting SYCL or not.
if (S.getLangOpts().SYCLIsDevice || S.getLangOpts().SYCLIsHost)
handleSYCLWorkGroupSizeHint(S, D, AL);
else
handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
}

// Checks correctness of mutual usage of different work_group_size attributes:
Expand Down Expand Up @@ -7911,7 +7914,7 @@ void Sema::CheckSYCLAddIRAttributesFunctionAttrConflicts(Decl *D) {
for (const auto *Attr : std::vector<AttributeCommonInfo *>{
D->getAttr<SYCLReqdWorkGroupSizeAttr>(),
D->getAttr<IntelReqdSubGroupSizeAttr>(),
D->getAttr<WorkGroupSizeHintAttr>(),
D->getAttr<SYCLWorkGroupSizeHintAttr>(),
D->getAttr<SYCLDeviceHasAttr>()})
if (Attr)
Diag(Attr->getLoc(), diag::warn_sycl_old_and_new_kernel_attributes)
Expand Down Expand Up @@ -12056,6 +12059,9 @@ void Sema::ProcessDeclAttributeList(
} else if (const auto *A = D->getAttr<SYCLReqdWorkGroupSizeAttr>()) {
Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
D->setInvalidDecl();
} else if (const auto *A = D->getAttr<SYCLWorkGroupSizeHintAttr>()) {
Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
D->setInvalidDecl();
} else if (const auto *A = D->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
D->setInvalidDecl();
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ static void collectSYCLAttributes(Sema &S, FunctionDecl *FD,
llvm::copy_if(FD->getAttrs(), std::back_inserter(Attrs), [](Attr *A) {
// FIXME: Make this list self-adapt as new SYCL attributes are added.
return isa<IntelReqdSubGroupSizeAttr, IntelNamedSubGroupSizeAttr,
SYCLReqdWorkGroupSizeAttr, WorkGroupSizeHintAttr,
SYCLReqdWorkGroupSizeAttr, SYCLWorkGroupSizeHintAttr,
SYCLIntelKernelArgsRestrictAttr, SYCLIntelNumSimdWorkItemsAttr,
SYCLIntelSchedulerTargetFmaxMhzAttr,
SYCLIntelMaxWorkGroupSizeAttr, SYCLIntelMaxGlobalWorkDimAttr,
Expand Down Expand Up @@ -4383,9 +4383,9 @@ static void PropagateAndDiagnoseDeviceAttr(
}
break;
}
case attr::Kind::WorkGroupSizeHint: {
auto *WGSH = cast<WorkGroupSizeHintAttr>(A);
if (auto *Existing = SYCLKernel->getAttr<WorkGroupSizeHintAttr>()) {
case attr::Kind::SYCLWorkGroupSizeHint: {
auto *WGSH = cast<SYCLWorkGroupSizeHintAttr>(A);
if (auto *Existing = SYCLKernel->getAttr<SYCLWorkGroupSizeHintAttr>()) {
if (S.AnyWorkGroupSizesDiffer(Existing->getXDim(), Existing->getYDim(),
Existing->getZDim(), WGSH->getXDim(),
WGSH->getYDim(), WGSH->getZDim())) {
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,9 @@ static void instantiateSYCLAddIRAnnotationsMemberAttr(
S.AddSYCLAddIRAnnotationsMemberAttr(New, *A, Args);
}

static void instantiateWorkGroupSizeHintAttr(
static void instantiateSYCLWorkGroupSizeHintAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const WorkGroupSizeHintAttr *A, Decl *New) {
const SYCLWorkGroupSizeHintAttr *A, Decl *New) {
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult XResult = S.SubstExpr(A->getXDim(), TemplateArgs);
Expand All @@ -857,8 +857,8 @@ static void instantiateWorkGroupSizeHintAttr(
if (ZResult.isInvalid())
return;

S.AddWorkGroupSizeHintAttr(New, *A, XResult.get(), YResult.get(),
ZResult.get());
S.AddSYCLWorkGroupSizeHintAttr(New, *A, XResult.get(), YResult.get(),
ZResult.get());
}

static void instantiateSYCLIntelMaxWorkGroupSizeAttr(
Expand Down Expand Up @@ -1200,8 +1200,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
*this, TemplateArgs, SYCLAddIRAnnotationsMember, New);
continue;
}
if (const auto *A = dyn_cast<WorkGroupSizeHintAttr>(TmplAttr)) {
instantiateWorkGroupSizeHintAttr(*this, TemplateArgs, A, New);
if (const auto *A = dyn_cast<SYCLWorkGroupSizeHintAttr>(TmplAttr)) {
instantiateSYCLWorkGroupSizeHintAttr(*this, TemplateArgs, A, New);
continue;
}
if (const auto *A = dyn_cast<SYCLDeviceHasAttr>(TmplAttr)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,4 @@ int main() {
// CHECK: ![[NUM32]] = !{i32 16, i32 16, i32 32}
// CHECK: ![[NUM88]] = !{i32 8, i32 8, i32 8}
// CHECK: ![[NUM22]] = !{i32 2, i32 2, i32 2}
// CHECK: ![[NUM123]] = !{i32 1, i32 2, i32 3}
// CHECK: ![[NUM123]] = !{i32 3, i32 2, i32 1}
32 changes: 32 additions & 0 deletions clang/test/CodeGenSYCL/check-work-group-attributes-match.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %clang_cc1 -fno-sycl-force-inline-kernel-lambda -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown -disable-llvm-passes -sycl-std=2020 -opaque-pointers -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fno-sycl-force-inline-kernel-lambda -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown -disable-llvm-passes -sycl-std=2020 -no-opaque-pointers -emit-llvm -o - %s | FileCheck %s

// Tests that work_group_size_hint and reqd_work_group_size generate the same
// metadata nodes for the same arguments.

#include "sycl.hpp"

using namespace sycl;

int main() {
queue q;

q.submit([&](handler &h) {
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_1d() #0 {{.*}} !work_group_size_hint ![[WG1D:[0-9]+]]{{.*}} !reqd_work_group_size ![[WG1D]]
h.single_task<class kernel_1d>([]() [[sycl::work_group_size_hint(8)]] [[sycl::reqd_work_group_size(8)]] {});
});

q.submit([&](handler &h) {
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_2d() #0 {{.*}} !work_group_size_hint ![[WG2D:[0-9]+]]{{.*}} !reqd_work_group_size ![[WG2D]]
h.single_task<class kernel_2d>([]() [[sycl::work_group_size_hint(8, 16)]] [[sycl::reqd_work_group_size(8, 16)]] {});
});

q.submit([&](handler &h) {
// CHECK: define {{.*}}spir_kernel void @{{.*}}kernel_3d() #0 {{.*}} !work_group_size_hint ![[WG3D:[0-9]+]]{{.*}} !reqd_work_group_size ![[WG3D]]
h.single_task<class kernel_3d>([]() [[sycl::work_group_size_hint(8, 16, 32)]] [[sycl::reqd_work_group_size(8, 16, 32)]] {});
});
}

// CHECK: ![[WG1D]] = !{i32 8}
// CHECK: ![[WG2D]] = !{i32 16, i32 8}
// CHECK: ![[WG3D]] = !{i32 32, i32 16, i32 8}
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,4 @@ int main() {
// CHECK: ![[NUM32]] = !{i32 16, i32 16, i32 32}
// CHECK: ![[NUM88]] = !{i32 8, i32 8, i32 8}
// CHECK: ![[NUM22]] = !{i32 2, i32 2, i32 2}
// CHECK: ![[NUM123]] = !{i32 1, i32 2, i32 3}
// CHECK: ![[NUM123]] = !{i32 3, i32 2, i32 1}
Loading