Skip to content

Commit f1275d6

Browse files
author
git apple-llvm automerger
committed
Merge commit 'f072263e9f62' from llvm.org/main into experimental/cas/main
2 parents 457eb1a + f072263 commit f1275d6

File tree

12 files changed

+349
-46
lines changed

12 files changed

+349
-46
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,8 +2605,7 @@ void UnwrappedLineParser::parseUnbracedBody(bool CheckEOF) {
26052605
FormatToken *Tok = nullptr;
26062606

26072607
if (Style.InsertBraces && !Line->InPPDirective && !Line->Tokens.empty() &&
2608-
PreprocessorDirectives.empty()) {
2609-
assert(!Line->Tokens.empty());
2608+
PreprocessorDirectives.empty() && FormatTok->isNot(tok::semi)) {
26102609
Tok = Style.BraceWrapping.AfterControlStatement == FormatStyle::BWACS_Never
26112610
? getLastNonComment(*Line)
26122611
: Line->Tokens.back().Tok;

clang/unittests/Format/FormatTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25365,6 +25365,30 @@ TEST_F(FormatTest, InsertBraces) {
2536525365
"}",
2536625366
Style);
2536725367

25368+
verifyFormat("do {\n"
25369+
"#if 0\n"
25370+
" if (a) {\n"
25371+
"#else\n"
25372+
" if (b) {\n"
25373+
"#endif\n"
25374+
"}\n"
25375+
"}\n"
25376+
"while (0)\n"
25377+
" ;",
25378+
Style);
25379+
// TODO: Replace the test above with the one below after #57539 is fixed.
25380+
#if 0
25381+
verifyFormat("do {\n"
25382+
"#if 0\n"
25383+
" if (a) {\n"
25384+
"#else\n"
25385+
" if (b) {\n"
25386+
"#endif\n"
25387+
" }\n"
25388+
"} while (0);",
25389+
Style);
25390+
#endif
25391+
2536825392
Style.ColumnLimit = 15;
2536925393

2537025394
verifyFormat("#define A \\\n"

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_CODEGEN_TARGETREGISTERINFO_H
1717

1818
#include "llvm/ADT/ArrayRef.h"
19+
#include "llvm/ADT/Optional.h"
1920
#include "llvm/ADT/SmallVector.h"
2021
#include "llvm/ADT/StringRef.h"
2122
#include "llvm/ADT/iterator_range.h"
@@ -523,6 +524,16 @@ class TargetRegisterInfo : public MCRegisterInfo {
523524
/// markSuperRegs() and checkAllSuperRegsMarked() in this case.
524525
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
525526

527+
/// Returns either a string explaining why the given register is reserved for
528+
/// this function, or an empty optional if no explanation has been written.
529+
/// The absence of an explanation does not mean that the register is not
530+
/// reserved (meaning, you should check that PhysReg is in fact reserved
531+
/// before calling this).
532+
virtual llvm::Optional<std::string>
533+
explainReservedReg(const MachineFunction &MF, MCRegister PhysReg) const {
534+
return {};
535+
}
536+
526537
/// Returns false if we can't guarantee that Physreg, specified as an IR asm
527538
/// clobber constraint, will be preserved across the statement.
528539
virtual bool isAsmClobberable(const MachineFunction &MF,

llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,14 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
411411
LocCookie, Msg, DiagnosticSeverity::DS_Warning));
412412
MMI->getModule()->getContext().diagnose(
413413
DiagnosticInfoInlineAsm(LocCookie, Note, DiagnosticSeverity::DS_Note));
414+
415+
for (const Register RR : RestrRegs) {
416+
if (llvm::Optional<std::string> reason =
417+
TRI->explainReservedReg(*MF, RR)) {
418+
MMI->getModule()->getContext().diagnose(DiagnosticInfoInlineAsm(
419+
LocCookie, *reason, DiagnosticSeverity::DS_Note));
420+
}
421+
}
414422
}
415423

416424
emitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,16 @@ const uint32_t *AArch64RegisterInfo::getWindowsStackProbePreservedMask() const {
308308
return CSR_AArch64_StackProbe_Windows_RegMask;
309309
}
310310

311+
llvm::Optional<std::string>
312+
AArch64RegisterInfo::explainReservedReg(const MachineFunction &MF,
313+
MCRegister PhysReg) const {
314+
if (hasBasePointer(MF) &&
315+
(PhysReg == AArch64::X19 || PhysReg == AArch64::W19))
316+
return std::string("X19 is used as the frame base pointer register.");
317+
318+
return {};
319+
}
320+
311321
BitVector
312322
AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
313323
const AArch64FrameLowering *TFI = getFrameLowering(MF);

llvm/lib/Target/AArch64/AArch64RegisterInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
9191

9292
BitVector getStrictlyReservedRegs(const MachineFunction &MF) const;
9393
BitVector getReservedRegs(const MachineFunction &MF) const override;
94+
llvm::Optional<std::string>
95+
explainReservedReg(const MachineFunction &MF,
96+
MCRegister PhysReg) const override;
9497
bool isAsmClobberable(const MachineFunction &MF,
9598
MCRegister PhysReg) const override;
9699
const TargetRegisterClass *

llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,8 +1583,11 @@ InductiveRangeCheck::computeSafeIterationSpace(
15831583
bool IsLatchSigned) const {
15841584
// We can deal when types of latch check and range checks don't match in case
15851585
// if latch check is more narrow.
1586-
auto *IVType = cast<IntegerType>(IndVar->getType());
1587-
auto *RCType = cast<IntegerType>(getBegin()->getType());
1586+
auto *IVType = dyn_cast<IntegerType>(IndVar->getType());
1587+
auto *RCType = dyn_cast<IntegerType>(getBegin()->getType());
1588+
// Do not work with pointer types.
1589+
if (!IVType || !RCType)
1590+
return None;
15881591
if (IVType->getBitWidth() > RCType->getBitWidth())
15891592
return None;
15901593
// IndVar is of the form "A + B * I" (where "I" is the canonical induction
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; Check that not only do we warn about clobbering x19 we also say
2+
; what it is used for.
3+
4+
; RUN: llc <%s -mtriple=aarch64-none-eabi 2>&1 | FileCheck %s
5+
6+
; CHECK: warning: inline asm clobber list contains reserved registers: X19
7+
; CHECK-NEXT: note: Reserved registers on the clobber list
8+
; CHECK-NEXT: note: X19 is used as the frame base pointer register.
9+
; CHECK-NEXT: note: X19 is used as the frame base pointer register.
10+
11+
define void @alloca(i64 %size) {
12+
entry:
13+
%a = alloca i128, i64 %size, align 64
14+
call void asm sideeffect "nop", "~{x19},~{w19}"()
15+
ret void
16+
}
17+

llvm/test/CodeGen/AArch64/rm_redundant_cmp.ll

Lines changed: 116 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12
; RUN: llc < %s -mtriple=aarch64-linux-gnuabi -O2 | FileCheck %s
23

34
; The following cases are for i16
@@ -9,11 +10,18 @@
910
@cost_u_i16 = common global %struct.s_unsigned_i16 zeroinitializer, align 2
1011

1112
define void @test_i16_2cmp_signed_1() {
12-
; CHECK-LABEL: test_i16_2cmp_signed_1
13-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
14-
; CHECK-NEXT: b.lt
15-
; CHECK-NOT: cmp
16-
; CHECK: ret
13+
; CHECK-LABEL: test_i16_2cmp_signed_1:
14+
; CHECK: // %bb.0: // %entry
15+
; CHECK-NEXT: adrp x8, :got:cost_s_i8_i16
16+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_s_i8_i16]
17+
; CHECK-NEXT: ldrsh w9, [x8, #2]
18+
; CHECK-NEXT: ldrsh w10, [x8, #4]
19+
; CHECK-NEXT: cmp w9, w10
20+
; CHECK-NEXT: b.lt .LBB0_2
21+
; CHECK-NEXT: // %bb.1: // %if.end8.sink.split
22+
; CHECK-NEXT: strh w9, [x8]
23+
; CHECK-NEXT: .LBB0_2: // %if.end8
24+
; CHECK-NEXT: ret
1725
entry:
1826
%0 = load i16, i16* getelementptr inbounds (%struct.s_signed_i16, %struct.s_signed_i16* @cost_s_i8_i16, i64 0, i32 1), align 2
1927
%1 = load i16, i16* getelementptr inbounds (%struct.s_signed_i16, %struct.s_signed_i16* @cost_s_i8_i16, i64 0, i32 2), align 2
@@ -37,11 +45,21 @@ if.end8: ; preds = %if.else, %if.then7,
3745
}
3846

3947
define void @test_i16_2cmp_signed_2() {
40-
; CHECK-LABEL: test_i16_2cmp_signed_2
41-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
42-
; CHECK-NEXT: b.gt
43-
; CHECK-NOT: cmp
44-
; CHECK: b.ge
48+
; CHECK-LABEL: test_i16_2cmp_signed_2:
49+
; CHECK: // %bb.0: // %entry
50+
; CHECK-NEXT: adrp x8, :got:cost_s_i8_i16
51+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_s_i8_i16]
52+
; CHECK-NEXT: ldrsh w9, [x8, #2]
53+
; CHECK-NEXT: ldrsh w10, [x8, #4]
54+
; CHECK-NEXT: cmp w9, w10
55+
; CHECK-NEXT: b.gt .LBB1_2
56+
; CHECK-NEXT: // %bb.1: // %if.else
57+
; CHECK-NEXT: mov w9, w10
58+
; CHECK-NEXT: b.ge .LBB1_3
59+
; CHECK-NEXT: .LBB1_2: // %if.end8.sink.split
60+
; CHECK-NEXT: strh w9, [x8]
61+
; CHECK-NEXT: .LBB1_3: // %if.end8
62+
; CHECK-NEXT: ret
4563
entry:
4664
%0 = load i16, i16* getelementptr inbounds (%struct.s_signed_i16, %struct.s_signed_i16* @cost_s_i8_i16, i64 0, i32 1), align 2
4765
%1 = load i16, i16* getelementptr inbounds (%struct.s_signed_i16, %struct.s_signed_i16* @cost_s_i8_i16, i64 0, i32 2), align 2
@@ -65,11 +83,18 @@ if.end8: ; preds = %if.else, %if.then7,
6583
}
6684

6785
define void @test_i16_2cmp_unsigned_1() {
68-
; CHECK-LABEL: test_i16_2cmp_unsigned_1
69-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
70-
; CHECK-NEXT: b.lo
71-
; CHECK-NOT: cmp
72-
; CHECK: ret
86+
; CHECK-LABEL: test_i16_2cmp_unsigned_1:
87+
; CHECK: // %bb.0: // %entry
88+
; CHECK-NEXT: adrp x8, :got:cost_u_i16
89+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_u_i16]
90+
; CHECK-NEXT: ldrh w9, [x8, #2]
91+
; CHECK-NEXT: ldrh w10, [x8, #4]
92+
; CHECK-NEXT: cmp w9, w10
93+
; CHECK-NEXT: b.lo .LBB2_2
94+
; CHECK-NEXT: // %bb.1: // %if.end8.sink.split
95+
; CHECK-NEXT: strh w9, [x8]
96+
; CHECK-NEXT: .LBB2_2: // %if.end8
97+
; CHECK-NEXT: ret
7398
entry:
7499
%0 = load i16, i16* getelementptr inbounds (%struct.s_unsigned_i16, %struct.s_unsigned_i16* @cost_u_i16, i64 0, i32 1), align 2
75100
%1 = load i16, i16* getelementptr inbounds (%struct.s_unsigned_i16, %struct.s_unsigned_i16* @cost_u_i16, i64 0, i32 2), align 2
@@ -93,11 +118,21 @@ if.end8: ; preds = %if.else, %if.then7,
93118
}
94119

95120
define void @test_i16_2cmp_unsigned_2() {
96-
; CHECK-LABEL: test_i16_2cmp_unsigned_2
97-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
98-
; CHECK-NEXT: b.hi
99-
; CHECK-NOT: cmp
100-
; CHECK: b.hs
121+
; CHECK-LABEL: test_i16_2cmp_unsigned_2:
122+
; CHECK: // %bb.0: // %entry
123+
; CHECK-NEXT: adrp x8, :got:cost_u_i16
124+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_u_i16]
125+
; CHECK-NEXT: ldrh w9, [x8, #2]
126+
; CHECK-NEXT: ldrh w10, [x8, #4]
127+
; CHECK-NEXT: cmp w9, w10
128+
; CHECK-NEXT: b.hi .LBB3_2
129+
; CHECK-NEXT: // %bb.1: // %if.else
130+
; CHECK-NEXT: mov w9, w10
131+
; CHECK-NEXT: b.hs .LBB3_3
132+
; CHECK-NEXT: .LBB3_2: // %if.end8.sink.split
133+
; CHECK-NEXT: strh w9, [x8]
134+
; CHECK-NEXT: .LBB3_3: // %if.end8
135+
; CHECK-NEXT: ret
101136
entry:
102137
%0 = load i16, i16* getelementptr inbounds (%struct.s_unsigned_i16, %struct.s_unsigned_i16* @cost_u_i16, i64 0, i32 1), align 2
103138
%1 = load i16, i16* getelementptr inbounds (%struct.s_unsigned_i16, %struct.s_unsigned_i16* @cost_u_i16, i64 0, i32 2), align 2
@@ -130,11 +165,18 @@ if.end8: ; preds = %if.else, %if.then7,
130165

131166

132167
define void @test_i8_2cmp_signed_1() {
133-
; CHECK-LABEL: test_i8_2cmp_signed_1
134-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
135-
; CHECK-NEXT: b.lt
136-
; CHECK-NOT: cmp
137-
; CHECK: ret
168+
; CHECK-LABEL: test_i8_2cmp_signed_1:
169+
; CHECK: // %bb.0: // %entry
170+
; CHECK-NEXT: adrp x8, :got:cost_s
171+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_s]
172+
; CHECK-NEXT: ldrsb w9, [x8, #1]
173+
; CHECK-NEXT: ldrsb w10, [x8, #2]
174+
; CHECK-NEXT: cmp w9, w10
175+
; CHECK-NEXT: b.lt .LBB4_2
176+
; CHECK-NEXT: // %bb.1: // %if.end8.sink.split
177+
; CHECK-NEXT: strb w9, [x8]
178+
; CHECK-NEXT: .LBB4_2: // %if.end8
179+
; CHECK-NEXT: ret
138180
entry:
139181
%0 = load i8, i8* getelementptr inbounds (%struct.s_signed_i8, %struct.s_signed_i8* @cost_s, i64 0, i32 1), align 2
140182
%1 = load i8, i8* getelementptr inbounds (%struct.s_signed_i8, %struct.s_signed_i8* @cost_s, i64 0, i32 2), align 2
@@ -158,11 +200,21 @@ if.end8: ; preds = %if.else, %if.then7,
158200
}
159201

160202
define void @test_i8_2cmp_signed_2() {
161-
; CHECK-LABEL: test_i8_2cmp_signed_2
162-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
163-
; CHECK-NEXT: b.gt
164-
; CHECK-NOT: cmp
165-
; CHECK: b.ge
203+
; CHECK-LABEL: test_i8_2cmp_signed_2:
204+
; CHECK: // %bb.0: // %entry
205+
; CHECK-NEXT: adrp x8, :got:cost_s
206+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_s]
207+
; CHECK-NEXT: ldrsb w9, [x8, #1]
208+
; CHECK-NEXT: ldrsb w10, [x8, #2]
209+
; CHECK-NEXT: cmp w9, w10
210+
; CHECK-NEXT: b.gt .LBB5_2
211+
; CHECK-NEXT: // %bb.1: // %if.else
212+
; CHECK-NEXT: mov w9, w10
213+
; CHECK-NEXT: b.ge .LBB5_3
214+
; CHECK-NEXT: .LBB5_2: // %if.end8.sink.split
215+
; CHECK-NEXT: strb w9, [x8]
216+
; CHECK-NEXT: .LBB5_3: // %if.end8
217+
; CHECK-NEXT: ret
166218
entry:
167219
%0 = load i8, i8* getelementptr inbounds (%struct.s_signed_i8, %struct.s_signed_i8* @cost_s, i64 0, i32 1), align 2
168220
%1 = load i8, i8* getelementptr inbounds (%struct.s_signed_i8, %struct.s_signed_i8* @cost_s, i64 0, i32 2), align 2
@@ -186,11 +238,18 @@ if.end8: ; preds = %if.else, %if.then7,
186238
}
187239

188240
define void @test_i8_2cmp_unsigned_1() {
189-
; CHECK-LABEL: test_i8_2cmp_unsigned_1
190-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
191-
; CHECK-NEXT: b.lo
192-
; CHECK-NOT: cmp
193-
; CHECK: ret
241+
; CHECK-LABEL: test_i8_2cmp_unsigned_1:
242+
; CHECK: // %bb.0: // %entry
243+
; CHECK-NEXT: adrp x8, :got:cost_u_i8
244+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_u_i8]
245+
; CHECK-NEXT: ldrb w9, [x8, #1]
246+
; CHECK-NEXT: ldrb w10, [x8, #2]
247+
; CHECK-NEXT: cmp w9, w10
248+
; CHECK-NEXT: b.lo .LBB6_2
249+
; CHECK-NEXT: // %bb.1: // %if.end8.sink.split
250+
; CHECK-NEXT: strb w9, [x8]
251+
; CHECK-NEXT: .LBB6_2: // %if.end8
252+
; CHECK-NEXT: ret
194253
entry:
195254
%0 = load i8, i8* getelementptr inbounds (%struct.s_unsigned_i8, %struct.s_unsigned_i8* @cost_u_i8, i64 0, i32 1), align 2
196255
%1 = load i8, i8* getelementptr inbounds (%struct.s_unsigned_i8, %struct.s_unsigned_i8* @cost_u_i8, i64 0, i32 2), align 2
@@ -214,11 +273,21 @@ if.end8: ; preds = %if.else, %if.then7,
214273
}
215274

216275
define void @test_i8_2cmp_unsigned_2() {
217-
; CHECK-LABEL: test_i8_2cmp_unsigned_2
218-
; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
219-
; CHECK-NEXT: b.hi
220-
; CHECK-NOT: cmp
221-
; CHECK: b.hs
276+
; CHECK-LABEL: test_i8_2cmp_unsigned_2:
277+
; CHECK: // %bb.0: // %entry
278+
; CHECK-NEXT: adrp x8, :got:cost_u_i8
279+
; CHECK-NEXT: ldr x8, [x8, :got_lo12:cost_u_i8]
280+
; CHECK-NEXT: ldrb w9, [x8, #1]
281+
; CHECK-NEXT: ldrb w10, [x8, #2]
282+
; CHECK-NEXT: cmp w9, w10
283+
; CHECK-NEXT: b.hi .LBB7_2
284+
; CHECK-NEXT: // %bb.1: // %if.else
285+
; CHECK-NEXT: mov w9, w10
286+
; CHECK-NEXT: b.hs .LBB7_3
287+
; CHECK-NEXT: .LBB7_2: // %if.end8.sink.split
288+
; CHECK-NEXT: strb w9, [x8]
289+
; CHECK-NEXT: .LBB7_3: // %if.end8
290+
; CHECK-NEXT: ret
222291
entry:
223292
%0 = load i8, i8* getelementptr inbounds (%struct.s_unsigned_i8, %struct.s_unsigned_i8* @cost_u_i8, i64 0, i32 1), align 2
224293
%1 = load i8, i8* getelementptr inbounds (%struct.s_unsigned_i8, %struct.s_unsigned_i8* @cost_u_i8, i64 0, i32 2), align 2
@@ -247,6 +316,13 @@ if.end8: ; preds = %if.else, %if.then7,
247316
; the operand of a set_cc is always a TRUNCATE.
248317

249318
define i1 @foo(float %inl, float %inr) {
319+
; CHECK-LABEL: foo:
320+
; CHECK: // %bb.0:
321+
; CHECK-NEXT: fcvtzs w8, s0
322+
; CHECK-NEXT: fcvtzs w9, s1
323+
; CHECK-NEXT: cmp w8, w9
324+
; CHECK-NEXT: cset w0, eq
325+
; CHECK-NEXT: ret
250326
%lval = fptosi float %inl to i8
251327
%rval = fptosi float %inr to i8
252328
%sum = icmp eq i8 %lval, %rval

0 commit comments

Comments
 (0)