Skip to content
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

[OpenCL] Fix an infinite loop in builidng AddrSpaceQualType #92612

Merged
merged 3 commits into from
May 20, 2024
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
2 changes: 1 addition & 1 deletion clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2611,7 +2611,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
///
/// \returns if this is an array type, the completely unqualified array type
/// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const;

/// Determine whether the given types are equivalent after
/// cvr-qualifiers have been removed.
Expand Down
32 changes: 19 additions & 13 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3054,21 +3054,27 @@ QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
if (!T.hasAddressSpace())
return T;

// If we are composing extended qualifiers together, merge together
// into one ExtQuals node.
QualifierCollector Quals;
const Type *TypeNode;
// For arrays, strip the qualifier off the element type, then reconstruct the
// array type
if (T.getTypePtr()->isArrayType()) {
T = getUnqualifiedArrayType(T, Quals);
TypeNode = T.getTypePtr();
} else {
// If we are composing extended qualifiers together, merge together
// into one ExtQuals node.
while (T.hasAddressSpace()) {
TypeNode = Quals.strip(T);

// If the type no longer has an address space after stripping qualifiers,
// jump out.
if (!QualType(TypeNode, 0).hasAddressSpace())
break;

while (T.hasAddressSpace()) {
TypeNode = Quals.strip(T);

// If the type no longer has an address space after stripping qualifiers,
// jump out.
if (!QualType(TypeNode, 0).hasAddressSpace())
break;

// There might be sugar in the way. Strip it and try again.
T = T.getSingleStepDesugaredType(*this);
// There might be sugar in the way. Strip it and try again.
T = T.getSingleStepDesugaredType(*this);
}
}

Quals.removeAddressSpace();
Expand Down Expand Up @@ -6093,7 +6099,7 @@ CanQualType ASTContext::getCanonicalParamType(QualType T) const {
}

QualType ASTContext::getUnqualifiedArrayType(QualType type,
Qualifiers &quals) {
Qualifiers &quals) const {
SplitQualType splitType = type.getSplitUnqualifiedType();

// FIXME: getSplitUnqualifiedType() actually walks all the way to
Expand Down
25 changes: 25 additions & 0 deletions clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
//RUN: %clang_cc1 %s -triple spir -emit-llvm -O1 -o - | FileCheck %s

// CHECK-LABEL: define dso_local spir_kernel void @test(
// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 8 [[IN:%.*]], ptr addrspace(1) nocapture noundef writeonly align 8 [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META3:![0-9]+]] !kernel_arg_access_qual [[META4:![0-9]+]] !kernel_arg_type [[META5:![0-9]+]] !kernel_arg_base_type [[META5]] !kernel_arg_type_qual [[META6:![0-9]+]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[IN]], i32 8
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(1) [[ARRAYIDX1]], align 8, !tbaa [[TBAA7:![0-9]+]]
// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[TBAA7]]
// CHECK-NEXT: ret void
//
__kernel void test(__global long *In, __global long *Out) {
long m[4] = { In[0], In[1], 0, 0 };
*Out = m[1];
}
//.
// CHECK: [[META3]] = !{i32 1, i32 1}
// CHECK: [[META4]] = !{!"none", !"none"}
// CHECK: [[META5]] = !{!"long*", !"long*"}
// CHECK: [[META6]] = !{!"", !""}
// CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
// CHECK: [[META8]] = !{!"long", [[META9:![0-9]+]], i64 0}
// CHECK: [[META9]] = !{!"omnipotent char", [[META10:![0-9]+]], i64 0}
// CHECK: [[META10]] = !{!"Simple C++ TBAA"}
//.
Loading