Skip to content

Commit 79e1274

Browse files
committed
merge main into amd-staging
Change-Id: I01c191e5db8d5da326013c06956f6b8047ccdc7b
2 parents dc6e68a + 6957c00 commit 79e1274

File tree

87 files changed

+4828
-414
lines changed

Some content is hidden

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

87 files changed

+4828
-414
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ Bug Fixes to C++ Support
815815
- Clang now diagnoses unexpanded parameter packs in attributes. (Fixes #GH93269).
816816
- Clang now allows ``@$``` in raw string literals. Fixes (#GH93130).
817817
- Fix an assertion failure when checking invalid ``this`` usage in the wrong context. (Fixes #GH91536).
818+
- Clang no longer models dependent NTTP arguments as ``TemplateParamObjectDecl`` s. Fixes (#GH84052).
818819

819820
Bug Fixes to AST Handling
820821
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/TemplateBase.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,13 @@ static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
221221

222222
// We model class non-type template parameters as their template parameter
223223
// object declaration.
224-
if (V.isStruct() || V.isUnion())
224+
if (V.isStruct() || V.isUnion()) {
225+
// Dependent types are not supposed to be described as
226+
// TemplateParamObjectDecls.
227+
if (T->isDependentType() || T->isInstantiationDependentType())
228+
return nullptr;
225229
return Ctx.getTemplateParamObjectDecl(T, V);
230+
}
226231

227232
// Pointers and references with an empty path use the special 'Declaration'
228233
// representation.

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,25 +1789,15 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
17891789
// Push a destructor if necessary.
17901790
// FIXME: if we have an array of structures, all explicitly
17911791
// initialized, we can end up pushing a linear number of cleanups.
1792-
bool pushedCleanup = false;
17931792
if (QualType::DestructionKind dtorKind
17941793
= field->getType().isDestructedType()) {
17951794
assert(LV.isSimple());
17961795
if (dtorKind) {
17971796
CGF.pushDestroyAndDeferDeactivation(NormalAndEHCleanup, LV.getAddress(),
17981797
field->getType(),
17991798
CGF.getDestroyer(dtorKind), false);
1800-
pushedCleanup = true;
18011799
}
18021800
}
1803-
1804-
// If the GEP didn't get used because of a dead zero init or something
1805-
// else, clean it up for -O0 builds and general tidiness.
1806-
if (!pushedCleanup && LV.isSimple())
1807-
if (llvm::GetElementPtrInst *GEP =
1808-
dyn_cast<llvm::GetElementPtrInst>(LV.emitRawPointer(CGF)))
1809-
if (GEP->use_empty())
1810-
GEP->eraseFromParent();
18111801
}
18121802
}
18131803

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5350,6 +5350,18 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
53505350
!IsDefinitionAvailableExternally &&
53515351
D->needsDestruction(getContext()) == QualType::DK_cxx_destructor;
53525352

5353+
// It is helpless to emit the definition for an available_externally variable
5354+
// which can't be marked as const.
5355+
// We don't need to check if it needs global ctor or dtor. See the above
5356+
// comment for ideas.
5357+
if (IsDefinitionAvailableExternally &&
5358+
(!D->hasConstantInitialization() ||
5359+
// TODO: Update this when we have interface to check constexpr
5360+
// destructor.
5361+
D->needsDestruction(getContext()) ||
5362+
!D->getType().isConstantStorage(getContext(), true, true)))
5363+
return;
5364+
53535365
const VarDecl *InitDecl;
53545366
const Expr *InitExpr = D->getAnyInitializer(InitDecl);
53555367

clang/lib/Driver/ToolChains/HIPUtility.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ class HIPUndefinedFatBinSymbols {
106106
std::string ID = IA->getId().str();
107107
if (!ID.empty()) {
108108
ID = llvm::utohexstr(llvm::MD5Hash(ID), /*LowerCase=*/true);
109-
FatBinSymbols.insert(Twine(FatBinPrefix + "_" + ID).str());
109+
FatBinSymbols.insert((FatBinPrefix + Twine('_') + ID).str());
110110
GPUBinHandleSymbols.insert(
111-
Twine(GPUBinHandlePrefix + "_" + ID).str());
111+
(GPUBinHandlePrefix + Twine('_') + ID).str());
112112
continue;
113113
}
114114
if (IA->getInputArg().getNumValues() == 0)

clang/test/CodeGenCXX/no-unique-address.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,28 @@ struct HasZeroSizedFieldWithNonTrivialInit {
101101
HasZeroSizedFieldWithNonTrivialInit testHasZeroSizedFieldWithNonTrivialInit = {.a = 1};
102102
// CHECK-LABEL: define {{.*}}cxx_global_var_init
103103
// CHECK: call {{.*}}@_ZN14NonTrivialInitC1Ev({{.*}}@testHasZeroSizedFieldWithNonTrivialInit
104+
105+
void *operator new(unsigned long, void *);
106+
template <class Ty>
107+
struct _box {
108+
[[no_unique_address]] Ty _value;
109+
};
110+
// Make sure this doesn't crash.
111+
// CHECK-LABEL: define {{.*}}placement_new_struct
112+
void placement_new_struct() {
113+
struct set_value_t {};
114+
115+
// GH88077
116+
struct _tuple : _box<set_value_t>, _box<int> {};
117+
118+
int _storage[1];
119+
new (_storage) _tuple{};
120+
121+
// GH89547
122+
struct _tuple2 {
123+
_box<set_value_t> a;
124+
};
125+
126+
int _storage2[1];
127+
new (_storage2) _tuple2{};
128+
}

clang/test/CodeGenCXX/partitions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ export int use() {
4040
}
4141

4242
// FIXME: The definition of the variables shouldn't be exported too.
43-
// CHECK: @_ZW3mod1a = available_externally global
44-
// CHECK: @_ZW3mod1b = available_externally global
43+
// CHECK: @_ZW3mod1a = external global
44+
// CHECK: @_ZW3mod1b = external global
4545
// CHECK: declare{{.*}} i32 @_ZW3mod3foov
4646
// CHECK: declare{{.*}} i32 @_ZW3mod3barv
4747

48-
// CHECK-OPT: @_ZW3mod1a = available_externally global
49-
// CHECK-OPT: @_ZW3mod1b = available_externally global
48+
// CHECK-OPT: @_ZW3mod1a = external global
49+
// CHECK-OPT: @_ZW3mod1b = external global
5050
// CHECK-OPT: declare{{.*}} i32 @_ZW3mod3foov
5151
// CHECK-OPT: declare{{.*}} i32 @_ZW3mod3barv

clang/test/Modules/pr93497.cppm

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
5+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/mod.cppm \
6+
// RUN: -emit-module-interface -o %t/mod.pcm
7+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/use.cpp \
8+
// RUN: -fmodule-file=mod=%t/mod.pcm -emit-llvm \
9+
// RUN: -o - | opt -S --passes=simplifycfg | FileCheck %t/use.cpp
10+
11+
//--- mod.cppm
12+
export module mod;
13+
14+
export struct Thing {
15+
static const Thing One;
16+
explicit Thing(int raw) :raw(raw) { }
17+
int raw;
18+
};
19+
20+
const Thing Thing::One = Thing(1);
21+
22+
export struct C {
23+
int value;
24+
};
25+
export const C ConstantValue = {1};
26+
27+
export const C *ConstantPtr = &ConstantValue;
28+
29+
C NonConstantValue = {1};
30+
export const C &ConstantRef = NonConstantValue;
31+
32+
export struct NonConstexprDtor {
33+
constexpr NonConstexprDtor(int raw) : raw(raw) {}
34+
~NonConstexprDtor();
35+
36+
int raw;
37+
};
38+
39+
export const NonConstexprDtor NonConstexprDtorValue = {1};
40+
41+
//--- use.cpp
42+
import mod;
43+
44+
int consume(int);
45+
int consumeC(C);
46+
47+
extern "C" __attribute__((noinline)) inline int unneeded() {
48+
return consume(43);
49+
}
50+
51+
extern "C" __attribute__((noinline)) inline int needed() {
52+
return consume(43);
53+
}
54+
55+
int use() {
56+
Thing t1 = Thing::One;
57+
return consume(t1.raw);
58+
}
59+
60+
int use2() {
61+
if (ConstantValue.value)
62+
return consumeC(ConstantValue);
63+
return unneeded();
64+
}
65+
66+
int use3() {
67+
auto Ptr = ConstantPtr;
68+
if (Ptr->value)
69+
return consumeC(*Ptr);
70+
return needed();
71+
}
72+
73+
int use4() {
74+
auto Ref = ConstantRef;
75+
if (Ref.value)
76+
return consumeC(Ref);
77+
return needed();
78+
}
79+
80+
int use5() {
81+
NonConstexprDtor V = NonConstexprDtorValue;
82+
if (V.raw)
83+
return consume(V.raw);
84+
return needed();
85+
}
86+
87+
// CHECK: @_ZNW3mod5Thing3OneE = external
88+
// CHECK: @_ZW3mod13ConstantValue ={{.*}}available_externally{{.*}} constant
89+
// CHECK: @_ZW3mod11ConstantPtr = external
90+
// CHECK: @_ZW3mod16NonConstantValue = external
91+
// CHECK: @_ZW3mod21NonConstexprDtorValue = external
92+
93+
// Check that the middle end can optimize the program by the constant information.
94+
// CHECK-NOT: @unneeded(
95+
96+
// Check that the use of ConstantPtr won't get optimized incorrectly.
97+
// CHECK-LABEL: @_Z4use3v(
98+
// CHECK: @needed(
99+
100+
// Check that the use of ConstantRef won't get optimized incorrectly.
101+
// CHECK-LABEL: @_Z4use4v(
102+
// CHECK: @needed(
103+
104+
// Check that the use of NonConstexprDtorValue won't get optimized incorrectly.
105+
// CHECK-LABEL: @_Z4use5v(
106+
// CHECK: @needed(

clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wconversion -verify %s
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++2c -Wconversion -verify %s
22

33
struct Test {
44
int a = 0;
@@ -102,3 +102,24 @@ void bar() {
102102
}
103103

104104
}
105+
106+
namespace GH84052 {
107+
108+
template <class... T>
109+
concept C = sizeof(T...[1]) == 1; // #C
110+
111+
struct A {};
112+
113+
template <class T, C<T> auto = A{}> struct Set {}; // #Set
114+
115+
template <class T> void foo() {
116+
Set<T> unrelated;
117+
}
118+
119+
Set<bool> sb;
120+
Set<float> sf;
121+
// expected-error@-1 {{constraints not satisfied for class template 'Set'}}
122+
// expected-note@#Set {{because 'C<decltype(GH84052::A{}), float>' evaluated to false}}
123+
// expected-note@#C {{evaluated to false}}
124+
125+
} // namespace GH84052

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@
4141
#include "flang/Optimizer/Support/Utils.h"
4242
#include "flang/Semantics/runtime-type-info.h"
4343
#include "flang/Semantics/tools.h"
44+
#include "llvm/Support/CommandLine.h"
4445
#include "llvm/Support/Debug.h"
4546
#include <optional>
4647

48+
static llvm::cl::opt<bool> allowAssumedRank(
49+
"allow-assumed-rank",
50+
llvm::cl::desc("Enable assumed rank lowering - experimental"),
51+
llvm::cl::init(false));
52+
4753
#define DEBUG_TYPE "flang-lower-variable"
4854

4955
/// Helper to lower a scalar expression using a specific symbol mapping.
@@ -1885,7 +1891,8 @@ void Fortran::lower::mapSymbolAttributes(
18851891
return;
18861892
}
18871893

1888-
if (Fortran::evaluate::IsAssumedRank(sym))
1894+
const bool isAssumedRank = Fortran::evaluate::IsAssumedRank(sym);
1895+
if (isAssumedRank && !allowAssumedRank)
18891896
TODO(loc, "assumed-rank variable in procedure implemented in Fortran");
18901897

18911898
Fortran::lower::BoxAnalyzer ba;
@@ -1894,6 +1901,8 @@ void Fortran::lower::mapSymbolAttributes(
18941901
// First deal with pointers and allocatables, because their handling here
18951902
// is the same regardless of their rank.
18961903
if (Fortran::semantics::IsAllocatableOrPointer(sym)) {
1904+
if (isAssumedRank)
1905+
TODO(loc, "assumed-rank pointer or allocatable");
18971906
// Get address of fir.box describing the entity.
18981907
// global
18991908
mlir::Value boxAlloc = preAlloc;
@@ -1942,7 +1951,7 @@ void Fortran::lower::mapSymbolAttributes(
19421951
if (mlir::Value len =
19431952
lowerExplicitCharLen(converter, loc, ba, symMap, stmtCtx))
19441953
explicitParams.push_back(len);
1945-
if (sym.Rank() == 0) {
1954+
if (!isAssumedRank && sym.Rank() == 0) {
19461955
// Do not keep scalar characters as fir.box (even when optional).
19471956
// Lowering and FIR is not meant to deal with scalar characters as
19481957
// fir.box outside of calls.
@@ -1987,9 +1996,11 @@ void Fortran::lower::mapSymbolAttributes(
19871996
}
19881997
}
19891998
// TODO: derived type length parameters.
1990-
lowerExplicitLowerBounds(converter, loc, ba, lbounds, symMap, stmtCtx);
1991-
lowerExplicitExtents(converter, loc, ba, lbounds, explicitExtents, symMap,
1992-
stmtCtx);
1999+
if (!isAssumedRank) {
2000+
lowerExplicitLowerBounds(converter, loc, ba, lbounds, symMap, stmtCtx);
2001+
lowerExplicitExtents(converter, loc, ba, lbounds, explicitExtents,
2002+
symMap, stmtCtx);
2003+
}
19932004
genBoxDeclare(converter, symMap, sym, dummyArg, lbounds, explicitParams,
19942005
explicitExtents, replace);
19952006
return;
@@ -2021,6 +2032,11 @@ void Fortran::lower::mapSymbolAttributes(
20212032
if (isUnusedEntryDummy) {
20222033
assert(!Fortran::semantics::IsAllocatableOrPointer(sym) &&
20232034
"handled above");
2035+
// Need to add support for allocatable assumed-rank to use
2036+
// logic below, or to simplify it and add codegen for fir.zero
2037+
// !fir.box<> instead.
2038+
if (isAssumedRank)
2039+
TODO(loc, "assumed rank in ENTRY");
20242040
// The box is read right away because lowering code does not expect
20252041
// a non pointer/allocatable symbol to be mapped to a MutableBox.
20262042
mlir::Type ty = converter.genType(var);
@@ -2042,6 +2058,13 @@ void Fortran::lower::mapSymbolAttributes(
20422058
return false;
20432059
};
20442060

2061+
if (isAssumedRank) {
2062+
assert(isUnusedEntryDummy && "assumed rank must be pointers/allocatables "
2063+
"or descriptor dummy arguments");
2064+
genUnusedEntryPointBox();
2065+
return;
2066+
}
2067+
20452068
// Helper to generate scalars for the symbol properties.
20462069
auto genValue = [&](const Fortran::lower::SomeExpr &expr) {
20472070
return genScalarValue(converter, loc, expr, symMap, stmtCtx);

flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,17 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
348348
// Helper to generate the hlfir fir.box with the local lower bounds and
349349
// type parameters.
350350
auto genHlfirBox = [&]() -> mlir::Value {
351-
if (!mlir::isa<fir::BaseBoxType>(firBase.getType())) {
351+
if (auto baseBoxType =
352+
mlir::dyn_cast<fir::BaseBoxType>(firBase.getType())) {
353+
// Rebox so that lower bounds are correct.
354+
if (baseBoxType.isAssumedRank())
355+
return builder.create<fir::ReboxAssumedRankOp>(
356+
loc, hlfirBaseType, firBase,
357+
fir::LowerBoundModifierAttribute::SetToOnes);
358+
return builder.create<fir::ReboxOp>(loc, hlfirBaseType, firBase,
359+
declareOp.getShape(),
360+
/*slice=*/mlir::Value{});
361+
} else {
352362
llvm::SmallVector<mlir::Value> typeParams;
353363
auto maybeCharType = mlir::dyn_cast<fir::CharacterType>(
354364
fir::unwrapSequenceType(fir::unwrapPassByRefType(hlfirBaseType)));
@@ -358,11 +368,6 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
358368
return builder.create<fir::EmboxOp>(
359369
loc, hlfirBaseType, firBase, declareOp.getShape(),
360370
/*slice=*/mlir::Value{}, typeParams);
361-
} else {
362-
// Rebox so that lower bounds are correct.
363-
return builder.create<fir::ReboxOp>(loc, hlfirBaseType, firBase,
364-
declareOp.getShape(),
365-
/*slice=*/mlir::Value{});
366371
}
367372
};
368373
if (!mlir::cast<fir::FortranVariableOpInterface>(declareOp.getOperation())

flang/test/HLFIR/declare-codegen.fir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,12 @@ func.func @dummy_scope(%arg0: !fir.ref<f32>) {
210210
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f32>) {
211211
// CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
212212
// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] {uniq_name = "x"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
213+
214+
func.func @assumed_rank_declare(%arg0: !fir.box<!fir.array<*:f32>>) {
215+
%0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
216+
return
217+
}
218+
// CHECK-LABEL: func.func @assumed_rank_declare(
219+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>>) {
220+
// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
221+
// CHECK: %[[VAL_2:.*]] = fir.rebox_assumed_rank %[[VAL_1]] lbs ones : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>

0 commit comments

Comments
 (0)