Skip to content

Commit 3562cfc

Browse files
authored
Merge branch 'main' into refactor/clang/unify-elementwise-builtins
2 parents 7be7e8b + f5742c4 commit 3562cfc

37 files changed

+4878
-3389
lines changed

clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ void FormatStringConverter::finalizeFormatText() {
700700
/// Append literal parts of the format text, reinstating escapes as required.
701701
void FormatStringConverter::appendFormatText(const StringRef Text) {
702702
for (const char Ch : Text) {
703+
const auto UCh = static_cast<unsigned char>(Ch);
703704
if (Ch == '\a')
704705
StandardFormatString += "\\a";
705706
else if (Ch == '\b')
@@ -724,10 +725,10 @@ void FormatStringConverter::appendFormatText(const StringRef Text) {
724725
} else if (Ch == '}') {
725726
StandardFormatString += "}}";
726727
FormatStringNeededRewriting = true;
727-
} else if (Ch < 32) {
728+
} else if (UCh < 32) {
728729
StandardFormatString += "\\x";
729-
StandardFormatString += llvm::hexdigit(Ch >> 4, true);
730-
StandardFormatString += llvm::hexdigit(Ch & 0xf, true);
730+
StandardFormatString += llvm::hexdigit(UCh >> 4, true);
731+
StandardFormatString += llvm::hexdigit(UCh & 0xf, true);
731732
} else
732733
StandardFormatString += Ch;
733734
}

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Potentially Breaking Changes
6969
- `CharTypdefsToIgnore` to `CharTypedefsToIgnore` in
7070
:doc:`bugprone-signed-char-misuse
7171
<clang-tidy/checks/bugprone/signed-char-misuse>`
72-
72+
7373
- Modified the custom message format of :doc:`bugprone-unsafe-functions
7474
<clang-tidy/checks/bugprone/unsafe-functions>` by assigning a special meaning
7575
to the character ``>`` at the start of the value of the option
@@ -394,7 +394,7 @@ Changes in existing checks
394394
<clang-tidy/checks/bugprone/unhandled-self-assignment>` check by adding
395395
an additional matcher that generalizes the copy-and-swap idiom pattern
396396
detection.
397-
397+
398398
- Improved :doc:`bugprone-unsafe-functions
399399
<clang-tidy/checks/bugprone/unsafe-functions>` check by hiding the default
400400
suffix when the reason starts with the character `>` in the `CustomFunctions`
@@ -497,7 +497,8 @@ Changes in existing checks
497497
- Improved :doc:`modernize-use-std-print
498498
<clang-tidy/checks/modernize/use-std-print>` check to correctly match
499499
when the format string is converted to a different type by an implicit
500-
constructor call.
500+
constructor call, and fixed a crash when handling format strings
501+
containing non-ASCII characters.
501502

502503
- Improved :doc:`performance-unnecessary-copy-initialization
503504
<clang-tidy/checks/performance/unnecessary-copy-initialization>` by printing

clang-tools-extra/test/clang-tidy/check_clang_tidy.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ def parse_arguments() -> Tuple[argparse.Namespace, List[str]]:
398398

399399

400400
def main() -> None:
401+
sys.stdout.reconfigure(encoding="utf-8")
402+
sys.stderr.reconfigure(encoding="utf-8")
401403
args, extra_args = parse_arguments()
402404

403405
abbreviated_stds = args.std

clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ void printf_deceptive_newline() {
5454
// CHECK-FIXES: std::println("Hello");
5555
}
5656

57+
void printf_utf8_text() {
58+
printf("你好世界\n");
59+
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
60+
// CHECK-FIXES: std::println("你好世界");
61+
}
62+
5763
void printf_crlf_newline() {
5864
printf("Hello\r\n");
5965
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
@@ -303,6 +309,12 @@ void fprintf_simple() {
303309
// CHECK-FIXES: std::print(stderr, "Hello");
304310
}
305311

312+
void fprintf_utf8_text() {
313+
fprintf(stderr, "你好世界\n");
314+
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
315+
// CHECK-FIXES: std::println(stderr, "你好世界");
316+
}
317+
306318
void std_printf_simple() {
307319
std::printf("std::Hello");
308320
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]

llvm/include/llvm/Analysis/IVDescriptors.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,17 @@ class RecurrenceDescriptor {
9595
RecurKind K, FastMathFlags FMF, Instruction *ExactFP,
9696
Type *RT, bool Signed, bool Ordered,
9797
SmallPtrSetImpl<Instruction *> &CI,
98-
unsigned MinWidthCastToRecurTy)
98+
unsigned MinWidthCastToRecurTy,
99+
bool PhiHasUsesOutsideReductionChain = false)
99100
: IntermediateStore(Store), StartValue(Start), LoopExitInstr(Exit),
100101
Kind(K), FMF(FMF), ExactFPMathInst(ExactFP), RecurrenceType(RT),
101102
IsSigned(Signed), IsOrdered(Ordered),
103+
PhiHasUsesOutsideReductionChain(PhiHasUsesOutsideReductionChain),
102104
MinWidthCastToRecurrenceType(MinWidthCastToRecurTy) {
103105
CastInsts.insert_range(CI);
106+
assert(
107+
(!PhiHasUsesOutsideReductionChain || isMinMaxRecurrenceKind(K)) &&
108+
"Only min/max recurrences are allowed to have multiple uses currently");
104109
}
105110

106111
/// This POD struct holds information about a potential recurrence operation.
@@ -339,6 +344,13 @@ class RecurrenceDescriptor {
339344
/// Expose an ordered FP reduction to the instance users.
340345
bool isOrdered() const { return IsOrdered; }
341346

347+
/// Returns true if the reduction PHI has any uses outside the reduction
348+
/// chain. This is relevant for min/max reductions that are part of a
349+
/// FindLastIV pattern.
350+
bool hasUsesOutsideReductionChain() const {
351+
return PhiHasUsesOutsideReductionChain;
352+
}
353+
342354
/// Attempts to find a chain of operations from Phi to LoopExitInst that can
343355
/// be treated as a set of reductions instructions for in-loop reductions.
344356
LLVM_ABI SmallVector<Instruction *, 4> getReductionOpChain(PHINode *Phi,
@@ -376,6 +388,10 @@ class RecurrenceDescriptor {
376388
// Currently only a non-reassociative FAdd can be considered in-order,
377389
// if it is also the only FAdd in the PHI's use chain.
378390
bool IsOrdered = false;
391+
// True if the reduction PHI has in-loop users outside the reduction chain.
392+
// This is relevant for min/max reductions that are part of a FindLastIV
393+
// pattern.
394+
bool PhiHasUsesOutsideReductionChain = false;
379395
// Instructions used for type-promoting the recurrence.
380396
SmallPtrSet<Instruction *, 8> CastInsts;
381397
// The minimum width used by the recurrence.

llvm/include/llvm/IR/IntrinsicsRISCVXCV.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,8 @@ let TargetPrefix = "riscv" in {
9090
def int_riscv_cv_mac_machhuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
9191
def int_riscv_cv_mac_macsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
9292
def int_riscv_cv_mac_machhsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
93+
94+
def int_riscv_cv_elw_elw
95+
: Intrinsic<[llvm_i32_ty], [llvm_ptr_ty],
96+
[IntrReadMem, IntrArgMemOnly, IntrHasSideEffects]>;
9397
} // TargetPrefix = "riscv"

llvm/lib/Analysis/IVDescriptors.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,52 @@ static bool checkOrderedReduction(RecurKind Kind, Instruction *ExactFPMathInst,
216216
return true;
217217
}
218218

219+
/// Returns true if \p Phi is a min/max reduction matching \p Kind where \p Phi
220+
/// is used outside the reduction chain. This is common for loops selecting the
221+
/// index of a minimum/maximum value (argmin/argmax).
222+
static bool isMinMaxReductionPhiWithUsersOutsideReductionChain(
223+
PHINode *Phi, RecurKind Kind, Loop *TheLoop, RecurrenceDescriptor &RedDes) {
224+
BasicBlock *Latch = TheLoop->getLoopLatch();
225+
if (!Latch)
226+
return false;
227+
228+
assert(Phi->getNumIncomingValues() == 2 && "phi must have 2 incoming values");
229+
Value *Inc = Phi->getIncomingValueForBlock(Latch);
230+
if (Phi->hasOneUse() || !Inc->hasOneUse() ||
231+
!RecurrenceDescriptor::isIntMinMaxRecurrenceKind(Kind))
232+
return false;
233+
234+
Value *A, *B;
235+
bool IsMinMax = [&]() {
236+
switch (Kind) {
237+
case RecurKind::UMax:
238+
return match(Inc, m_UMax(m_Value(A), m_Value(B)));
239+
case RecurKind::UMin:
240+
return match(Inc, m_UMin(m_Value(A), m_Value(B)));
241+
case RecurKind::SMax:
242+
return match(Inc, m_SMax(m_Value(A), m_Value(B)));
243+
case RecurKind::SMin:
244+
return match(Inc, m_SMin(m_Value(A), m_Value(B)));
245+
default:
246+
llvm_unreachable("all min/max kinds must be handled");
247+
}
248+
}();
249+
if (!IsMinMax)
250+
return false;
251+
252+
if (A == B || (A != Phi && B != Phi))
253+
return false;
254+
255+
SmallPtrSet<Instruction *, 4> CastInsts;
256+
Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());
257+
RedDes =
258+
RecurrenceDescriptor(RdxStart, /*Exit=*/nullptr, /*Store=*/nullptr, Kind,
259+
FastMathFlags(), /*ExactFP=*/nullptr, Phi->getType(),
260+
/*Signed=*/false, /*Ordered=*/false, CastInsts,
261+
/*MinWidthCastToRecurTy=*/-1U, /*PhiMultiUse=*/true);
262+
return true;
263+
}
264+
219265
bool RecurrenceDescriptor::AddReductionVar(
220266
PHINode *Phi, RecurKind Kind, Loop *TheLoop, FastMathFlags FuncFMF,
221267
RecurrenceDescriptor &RedDes, DemandedBits *DB, AssumptionCache *AC,
@@ -227,6 +273,11 @@ bool RecurrenceDescriptor::AddReductionVar(
227273
if (Phi->getParent() != TheLoop->getHeader())
228274
return false;
229275

276+
// Check for min/max reduction variables that feed other users in the loop.
277+
if (isMinMaxReductionPhiWithUsersOutsideReductionChain(Phi, Kind, TheLoop,
278+
RedDes))
279+
return true;
280+
230281
// Obtain the reduction start value from the value that comes from the loop
231282
// preheader.
232283
Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
774774
// Abort if the spill cannot be inserted at the MBB' start
775775
if (((BC.Entry == SpillPlacement::MustSpill) ||
776776
(BC.Entry == SpillPlacement::PrefSpill)) &&
777-
SlotIndex::isEarlierInstr(BI.FirstInstr,
778-
SA->getFirstSplitPoint(BC.Number)))
777+
!SA->canSplitBeforeProlog(BC.Number))
779778
return false;
780779
}
781780

@@ -830,11 +829,7 @@ bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
830829
BCS[B].Number = Number;
831830

832831
// Abort if the spill cannot be inserted at the MBB' start
833-
MachineBasicBlock *MBB = MF->getBlockNumbered(Number);
834-
auto FirstNonDebugInstr = MBB->getFirstNonDebugInstr();
835-
if (FirstNonDebugInstr != MBB->end() &&
836-
SlotIndex::isEarlierInstr(LIS->getInstructionIndex(*FirstNonDebugInstr),
837-
SA->getFirstSplitPoint(Number)))
832+
if (!SA->canSplitBeforeProlog(Number))
838833
return false;
839834
// Interference for the live-in value.
840835
if (Intf.first() <= Indexes->getMBBStartIdx(Number))

llvm/lib/CodeGen/SplitKit.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,54 @@ InsertPointAnalysis::getLastInsertPointIter(const LiveInterval &CurLI,
147147
return LIS.getInstructionFromIndex(LIP);
148148
}
149149

150+
bool InsertPointAnalysis::canSplitBeforeProlog(const LiveInterval &CurLI,
151+
const MachineBasicBlock &MBB) {
152+
const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
153+
154+
for (auto &MI : MBB) {
155+
if (MI.isPHI() || MI.isPosition() || MI.isDebugInstr() ||
156+
MI.isPseudoProbe())
157+
continue;
158+
159+
if (!TII->isBasicBlockPrologue(MI))
160+
return true;
161+
162+
for (auto &MO : MI.operands()) {
163+
if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual())
164+
continue;
165+
166+
// For the AMDGPU target if a MBB contains exec mask restore preamble,
167+
// SplitEditor may get state when it cannot insert a spill instruction
168+
// at the begin of the MBB.
169+
// E.g. for a MIR
170+
// bb.100:
171+
// %1 = S_OR_SAVEEXEC_B64 %2, implicit-def $exec, implicit-def $scc,
172+
// implicit $exec
173+
// ...
174+
// use %1
175+
// If the regalloc try to allocate a virtreg to the physreg already
176+
// assigned to virtreg %1 and the pyhsreg is computed as the best
177+
// candidate for split, it may insert COPY instruction.
178+
// bb.100:
179+
// %1 = S_OR_SAVEEXEC_B64 %2, implicit-def $exec, implicit-def $scc,
180+
// implicit $exec
181+
// %2 = COPY %orig
182+
// ...
183+
// use %1
184+
// Thus %1 and %orig still have interference. We may add cost for the
185+
// physreg candidate or abandon the candidate.
186+
const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
187+
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
188+
const TargetRegisterClass *RC = MRI.getRegClass(MO.getReg());
189+
const TargetRegisterClass *CurRC = MRI.getRegClass(CurLI.reg());
190+
if (TRI->getCommonSubClass(RC, CurRC))
191+
return false;
192+
}
193+
}
194+
195+
return true;
196+
}
197+
150198
//===----------------------------------------------------------------------===//
151199
// Split Analysis
152200
//===----------------------------------------------------------------------===//

llvm/lib/CodeGen/SplitKit.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class LLVM_LIBRARY_VISIBILITY InsertPointAnalysis {
8989
return Res;
9090
}
9191

92+
/// Return true if we can split \pCurLI before \pMBB's prolog.
93+
bool canSplitBeforeProlog(const LiveInterval &CurLI,
94+
const MachineBasicBlock &MBB);
9295
};
9396

9497
/// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting
@@ -247,6 +250,11 @@ class LLVM_LIBRARY_VISIBILITY SplitAnalysis {
247250
SlotIndex getFirstSplitPoint(unsigned Num) {
248251
return IPA.getFirstInsertPoint(*MF.getBlockNumbered(Num));
249252
}
253+
254+
bool canSplitBeforeProlog(unsigned Num) {
255+
MachineBasicBlock *BB = MF.getBlockNumbered(Num);
256+
return IPA.canSplitBeforeProlog(*CurLI, *BB);
257+
}
250258
};
251259

252260
/// SplitEditor - Edit machine code and LiveIntervals for live range

0 commit comments

Comments
 (0)