Skip to content

Commit f54ffd8

Browse files
authored
Merge branch 'main' into remove-POST_BUILD
2 parents 8a5598d + 86b89a6 commit f54ffd8

File tree

16 files changed

+276
-76
lines changed

16 files changed

+276
-76
lines changed

flang/lib/Semantics/check-omp-atomic.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,8 @@ struct AtomicAnalysis {
519519
/// function references with scalar data pointer result of non-character
520520
/// intrinsic type or variables that are non-polymorphic scalar pointers
521521
/// and any length type parameter must be constant.
522-
void OmpStructureChecker::CheckAtomicType(
523-
SymbolRef sym, parser::CharBlock source, std::string_view name) {
522+
void OmpStructureChecker::CheckAtomicType(SymbolRef sym,
523+
parser::CharBlock source, std::string_view name, bool checkTypeOnPointer) {
524524
const DeclTypeSpec *typeSpec{sym->GetType()};
525525
if (!typeSpec) {
526526
return;
@@ -547,6 +547,22 @@ void OmpStructureChecker::CheckAtomicType(
547547
return;
548548
}
549549

550+
// Apply pointer-to-non-intrinsic rule only for intrinsic-assignment paths.
551+
if (checkTypeOnPointer) {
552+
using Category = DeclTypeSpec::Category;
553+
Category cat{typeSpec->category()};
554+
if (cat != Category::Numeric && cat != Category::Logical) {
555+
std::string details = " has the POINTER attribute";
556+
if (const auto *derived{typeSpec->AsDerived()}) {
557+
details += " and derived type '"s + derived->name().ToString() + "'";
558+
}
559+
context_.Say(source,
560+
"ATOMIC operation requires an intrinsic scalar variable; '%s'%s"_err_en_US,
561+
sym->name(), details);
562+
return;
563+
}
564+
}
565+
550566
// Go over all length parameters, if any, and check if they are
551567
// explicit.
552568
if (const DerivedTypeSpec *derived{typeSpec->AsDerived()}) {
@@ -562,7 +578,7 @@ void OmpStructureChecker::CheckAtomicType(
562578
}
563579

564580
void OmpStructureChecker::CheckAtomicVariable(
565-
const SomeExpr &atom, parser::CharBlock source) {
581+
const SomeExpr &atom, parser::CharBlock source, bool checkTypeOnPointer) {
566582
if (atom.Rank() != 0) {
567583
context_.Say(source, "Atomic variable %s should be a scalar"_err_en_US,
568584
atom.AsFortran());
@@ -572,7 +588,7 @@ void OmpStructureChecker::CheckAtomicVariable(
572588
assert(dsgs.size() == 1 && "Should have a single top-level designator");
573589
evaluate::SymbolVector syms{evaluate::GetSymbolVector(dsgs.front())};
574590

575-
CheckAtomicType(syms.back(), source, atom.AsFortran());
591+
CheckAtomicType(syms.back(), source, atom.AsFortran(), checkTypeOnPointer);
576592

577593
if (IsAllocatable(syms.back()) && !IsArrayElement(atom)) {
578594
context_.Say(source, "Atomic variable %s cannot be ALLOCATABLE"_err_en_US,
@@ -789,7 +805,8 @@ void OmpStructureChecker::CheckAtomicCaptureAssignment(
789805
if (!IsVarOrFunctionRef(atom)) {
790806
ErrorShouldBeVariable(atom, rsrc);
791807
} else {
792-
CheckAtomicVariable(atom, rsrc);
808+
CheckAtomicVariable(
809+
atom, rsrc, /*checkTypeOnPointer=*/!IsPointerAssignment(capture));
793810
// This part should have been checked prior to calling this function.
794811
assert(*GetConvertInput(capture.rhs) == atom &&
795812
"This cannot be a capture assignment");
@@ -808,7 +825,8 @@ void OmpStructureChecker::CheckAtomicReadAssignment(
808825
if (!IsVarOrFunctionRef(atom)) {
809826
ErrorShouldBeVariable(atom, rsrc);
810827
} else {
811-
CheckAtomicVariable(atom, rsrc);
828+
CheckAtomicVariable(
829+
atom, rsrc, /*checkTypeOnPointer=*/!IsPointerAssignment(read));
812830
CheckStorageOverlap(atom, {read.lhs}, source);
813831
}
814832
} else {
@@ -829,7 +847,8 @@ void OmpStructureChecker::CheckAtomicWriteAssignment(
829847
if (!IsVarOrFunctionRef(atom)) {
830848
ErrorShouldBeVariable(atom, rsrc);
831849
} else {
832-
CheckAtomicVariable(atom, lsrc);
850+
CheckAtomicVariable(
851+
atom, lsrc, /*checkTypeOnPointer=*/!IsPointerAssignment(write));
833852
CheckStorageOverlap(atom, {write.rhs}, source);
834853
}
835854
}
@@ -854,7 +873,8 @@ OmpStructureChecker::CheckAtomicUpdateAssignment(
854873
return std::nullopt;
855874
}
856875

857-
CheckAtomicVariable(atom, lsrc);
876+
CheckAtomicVariable(
877+
atom, lsrc, /*checkTypeOnPointer=*/!IsPointerAssignment(update));
858878

859879
auto [hasErrors, tryReassoc]{CheckAtomicUpdateAssignmentRhs(
860880
atom, update.rhs, source, /*suppressDiagnostics=*/true)};
@@ -1017,7 +1037,8 @@ void OmpStructureChecker::CheckAtomicConditionalUpdateAssignment(
10171037
return;
10181038
}
10191039

1020-
CheckAtomicVariable(atom, alsrc);
1040+
CheckAtomicVariable(
1041+
atom, alsrc, /*checkTypeOnPointer=*/!IsPointerAssignment(assign));
10211042

10221043
auto top{GetTopLevelOperationIgnoreResizing(cond)};
10231044
// Missing arguments to operations would have been diagnosed by now.

flang/lib/Semantics/check-omp-structure.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,10 @@ class OmpStructureChecker
262262
void CheckStorageOverlap(const evaluate::Expr<evaluate::SomeType> &,
263263
llvm::ArrayRef<evaluate::Expr<evaluate::SomeType>>, parser::CharBlock);
264264
void ErrorShouldBeVariable(const MaybeExpr &expr, parser::CharBlock source);
265-
void CheckAtomicType(
266-
SymbolRef sym, parser::CharBlock source, std::string_view name);
267-
void CheckAtomicVariable(
268-
const evaluate::Expr<evaluate::SomeType> &, parser::CharBlock);
265+
void CheckAtomicType(SymbolRef sym, parser::CharBlock source,
266+
std::string_view name, bool checkTypeOnPointer = true);
267+
void CheckAtomicVariable(const evaluate::Expr<evaluate::SomeType> &,
268+
parser::CharBlock, bool checkTypeOnPointer = true);
269269
std::pair<const parser::ExecutionPartConstruct *,
270270
const parser::ExecutionPartConstruct *>
271271
CheckUpdateCapture(const parser::ExecutionPartConstruct *ec1,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: not %flang_fc1 -fopenmp -fsyntax-only %s 2>&1 | FileCheck %s
2+
type t
3+
end type
4+
type(t), pointer :: a1, a2
5+
!$omp atomic write
6+
a1 = a2
7+
! CHECK: error: ATOMIC operation requires an intrinsic scalar variable; 'a1' has the POINTER attribute and derived type 't'
8+
end

llvm/include/llvm/ADT/StringSwitch.h

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class StringSwitch {
6666

6767
// Case-sensitive case matchers
6868
StringSwitch &Case(StringLiteral S, T Value) {
69-
CaseImpl(Value, S);
69+
CaseImpl(S, Value);
7070
return *this;
7171
}
7272

@@ -86,68 +86,68 @@ class StringSwitch {
8686

8787
StringSwitch &Cases(std::initializer_list<StringLiteral> CaseStrings,
8888
T Value) {
89-
return CasesImpl(Value, CaseStrings);
89+
return CasesImpl(CaseStrings, Value);
9090
}
9191

9292
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) {
93-
return CasesImpl(Value, {S0, S1});
93+
return CasesImpl({S0, S1}, Value);
9494
}
9595

9696
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
9797
T Value) {
98-
return CasesImpl(Value, {S0, S1, S2});
98+
return CasesImpl({S0, S1, S2}, Value);
9999
}
100100

101101
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
102102
StringLiteral S3, T Value) {
103-
return CasesImpl(Value, {S0, S1, S2, S3});
103+
return CasesImpl({S0, S1, S2, S3}, Value);
104104
}
105105

106106
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
107107
StringLiteral S3, StringLiteral S4, T Value) {
108-
return CasesImpl(Value, {S0, S1, S2, S3, S4});
108+
return CasesImpl({S0, S1, S2, S3, S4}, Value);
109109
}
110110

111111
[[deprecated("Pass cases in std::initializer_list instead")]]
112112
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
113113
StringLiteral S3, StringLiteral S4, StringLiteral S5,
114114
T Value) {
115-
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5});
115+
return CasesImpl({S0, S1, S2, S3, S4, S5}, Value);
116116
}
117117

118118
[[deprecated("Pass cases in std::initializer_list instead")]]
119119
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
120120
StringLiteral S3, StringLiteral S4, StringLiteral S5,
121121
StringLiteral S6, T Value) {
122-
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6});
122+
return CasesImpl({S0, S1, S2, S3, S4, S5, S6}, Value);
123123
}
124124

125125
[[deprecated("Pass cases in std::initializer_list instead")]]
126126
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
127127
StringLiteral S3, StringLiteral S4, StringLiteral S5,
128128
StringLiteral S6, StringLiteral S7, T Value) {
129-
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7});
129+
return CasesImpl({S0, S1, S2, S3, S4, S5, S6, S7}, Value);
130130
}
131131

132132
[[deprecated("Pass cases in std::initializer_list instead")]]
133133
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
134134
StringLiteral S3, StringLiteral S4, StringLiteral S5,
135135
StringLiteral S6, StringLiteral S7, StringLiteral S8,
136136
T Value) {
137-
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8});
137+
return CasesImpl({S0, S1, S2, S3, S4, S5, S6, S7, S8}, Value);
138138
}
139139

140140
[[deprecated("Pass cases in std::initializer_list instead")]]
141141
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
142142
StringLiteral S3, StringLiteral S4, StringLiteral S5,
143143
StringLiteral S6, StringLiteral S7, StringLiteral S8,
144144
StringLiteral S9, T Value) {
145-
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9});
145+
return CasesImpl({S0, S1, S2, S3, S4, S5, S6, S7, S8, S9}, Value);
146146
}
147147

148148
// Case-insensitive case matchers.
149149
StringSwitch &CaseLower(StringLiteral S, T Value) {
150-
CaseLowerImpl(Value, S);
150+
CaseLowerImpl(S, Value);
151151
return *this;
152152
}
153153

@@ -167,26 +167,26 @@ class StringSwitch {
167167

168168
StringSwitch &CasesLower(std::initializer_list<StringLiteral> CaseStrings,
169169
T Value) {
170-
return CasesLowerImpl(Value, CaseStrings);
170+
return CasesLowerImpl(CaseStrings, Value);
171171
}
172172

173173
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) {
174-
return CasesLowerImpl(Value, {S0, S1});
174+
return CasesLowerImpl({S0, S1}, Value);
175175
}
176176

177177
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
178178
T Value) {
179-
return CasesLowerImpl(Value, {S0, S1, S2});
179+
return CasesLowerImpl({S0, S1, S2}, Value);
180180
}
181181

182182
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
183183
StringLiteral S3, T Value) {
184-
return CasesLowerImpl(Value, {S0, S1, S2, S3});
184+
return CasesLowerImpl({S0, S1, S2, S3}, Value);
185185
}
186186

187187
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
188188
StringLiteral S3, StringLiteral S4, T Value) {
189-
return CasesLowerImpl(Value, {S0, S1, S2, S3, S4});
189+
return CasesLowerImpl({S0, S1, S2, S3, S4}, Value);
190190
}
191191

192192
[[nodiscard]] R Default(T Value) {
@@ -207,7 +207,7 @@ class StringSwitch {
207207

208208
private:
209209
// Returns true when `Str` matches the `S` argument, and stores the result.
210-
bool CaseImpl(T &Value, StringLiteral S) {
210+
bool CaseImpl(StringLiteral S, T &Value) {
211211
if (!Result && Str == S) {
212212
Result = std::move(Value);
213213
return true;
@@ -217,28 +217,28 @@ class StringSwitch {
217217

218218
// Returns true when `Str` matches the `S` argument (case-insensitive), and
219219
// stores the result.
220-
bool CaseLowerImpl(T &Value, StringLiteral S) {
220+
bool CaseLowerImpl(StringLiteral S, T &Value) {
221221
if (!Result && Str.equals_insensitive(S)) {
222222
Result = std::move(Value);
223223
return true;
224224
}
225225
return false;
226226
}
227227

228-
StringSwitch &CasesImpl(T &Value,
229-
std::initializer_list<StringLiteral> Cases) {
228+
StringSwitch &CasesImpl(std::initializer_list<StringLiteral> Cases,
229+
T &Value) {
230230
// Stop matching after the string is found.
231231
for (StringLiteral S : Cases)
232-
if (CaseImpl(Value, S))
232+
if (CaseImpl(S, Value))
233233
break;
234234
return *this;
235235
}
236236

237-
StringSwitch &CasesLowerImpl(T &Value,
238-
std::initializer_list<StringLiteral> Cases) {
237+
StringSwitch &CasesLowerImpl(std::initializer_list<StringLiteral> Cases,
238+
T &Value) {
239239
// Stop matching after the string is found.
240240
for (StringLiteral S : Cases)
241-
if (CaseLowerImpl(Value, S))
241+
if (CaseLowerImpl(S, Value))
242242
break;
243243
return *this;
244244
}

llvm/lib/Target/AArch64/AArch64InstrGISel.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ def G_SDOT : AArch64GenericInstruction {
233233
let hasSideEffects = 0;
234234
}
235235

236+
def G_USDOT : AArch64GenericInstruction {
237+
let OutOperandList = (outs type0:$dst);
238+
let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
239+
let hasSideEffects = 0;
240+
}
241+
236242
// Generic instruction for the BSP pseudo. It is expanded into BSP, which
237243
// expands into BSL/BIT/BIF after register allocation.
238244
def G_BSP : AArch64GenericInstruction {
@@ -278,6 +284,7 @@ def : GINodeEquiv<G_UADDLV, AArch64uaddlv>;
278284

279285
def : GINodeEquiv<G_UDOT, AArch64udot>;
280286
def : GINodeEquiv<G_SDOT, AArch64sdot>;
287+
def : GINodeEquiv<G_USDOT, AArch64usdot>;
281288

282289
def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
283290

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,8 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
18551855
return LowerTriOp(AArch64::G_UDOT);
18561856
case Intrinsic::aarch64_neon_sdot:
18571857
return LowerTriOp(AArch64::G_SDOT);
1858+
case Intrinsic::aarch64_neon_usdot:
1859+
return LowerTriOp(AArch64::G_USDOT);
18581860
case Intrinsic::aarch64_neon_sqxtn:
18591861
return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_S);
18601862
case Intrinsic::aarch64_neon_sqxtun:

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,8 +1256,17 @@ def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
12561256
(MOV64ri32 tconstpool :$dst)>, Requires<[KernelCode]>;
12571257
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
12581258
(MOV64ri32 tjumptable :$dst)>, Requires<[KernelCode]>;
1259-
def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1260-
(MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>;
1259+
1260+
// If the globaladdr is an absolute_symbol, don't bother using the sign extending
1261+
// instruction since there's no benefit to using it with absolute symbols.
1262+
def globalAddrNoAbsSym : PatLeaf<(tglobaladdr:$dst), [{
1263+
auto *GA = cast<GlobalAddressSDNode>(N);
1264+
return !GA->getGlobal()->getAbsoluteSymbolRange();
1265+
}]>;
1266+
def : Pat<(i64 (X86Wrapper globalAddrNoAbsSym:$dst)),
1267+
(MOV64ri32 tglobaladdr:$dst)>,
1268+
Requires<[KernelCode]>;
1269+
12611270
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
12621271
(MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>;
12631272
def : Pat<(i64 (X86Wrapper mcsym:$dst)),

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4267,12 +4267,14 @@ class VPlan {
42674267
BackedgeTakenCount = new VPValue();
42684268
return BackedgeTakenCount;
42694269
}
4270+
VPValue *getBackedgeTakenCount() const { return BackedgeTakenCount; }
42704271

42714272
/// The vector trip count.
42724273
VPValue &getVectorTripCount() { return VectorTripCount; }
42734274

42744275
/// Returns the VF of the vector loop region.
42754276
VPValue &getVF() { return VF; };
4277+
const VPValue &getVF() const { return VF; };
42764278

42774279
/// Returns VF * UF of the vector loop region.
42784280
VPValue &getVFxUF() { return VFxUF; }

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,12 @@ m_AnyOf(const Op0_t &Op0) {
400400
return m_VPInstruction<VPInstruction::AnyOf>(Op0);
401401
}
402402

403+
template <typename Op0_t>
404+
inline VPInstruction_match<VPInstruction::FirstActiveLane, Op0_t>
405+
m_FirstActiveLane(const Op0_t &Op0) {
406+
return m_VPInstruction<VPInstruction::FirstActiveLane>(Op0);
407+
}
408+
403409
template <unsigned Opcode, typename Op0_t>
404410
inline AllRecipe_match<Opcode, Op0_t> m_Unary(const Op0_t &Op0) {
405411
return AllRecipe_match<Opcode, Op0_t>(Op0);

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,7 @@ static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
788788
ScalarEvolution &SE) {
789789
VPValue *Incoming, *Mask;
790790
if (!match(Op, m_VPInstruction<VPInstruction::ExtractLane>(
791-
m_VPInstruction<VPInstruction::FirstActiveLane>(
792-
m_VPValue(Mask)),
793-
m_VPValue(Incoming))))
791+
m_FirstActiveLane(m_VPValue(Mask)), m_VPValue(Incoming))))
794792
return nullptr;
795793

796794
auto *WideIV = getOptimizableIVOf(Incoming, SE);

0 commit comments

Comments
 (0)