Skip to content

Commit b4e3376

Browse files
author
git apple-llvm automerger
committed
Merge commit '74570a7b19b8' from apple/stable/20200714 into swift/main
2 parents 075e1be + 74570a7 commit b4e3376

File tree

6 files changed

+145
-93
lines changed

6 files changed

+145
-93
lines changed

llvm/lib/Support/Windows/Path.inc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "llvm/Support/ConvertUTF.h"
2020
#include "llvm/Support/WindowsError.h"
2121
#include <fcntl.h>
22-
#include <io.h>
2322
#include <sys/stat.h>
2423
#include <sys/types.h>
2524

@@ -352,13 +351,13 @@ std::error_code is_local(const Twine &path, bool &result) {
352351
static std::error_code realPathFromHandle(HANDLE H,
353352
SmallVectorImpl<wchar_t> &Buffer) {
354353
DWORD CountChars = ::GetFinalPathNameByHandleW(
355-
H, Buffer.begin(), Buffer.capacity() - 1, FILE_NAME_NORMALIZED);
356-
if (CountChars > Buffer.capacity()) {
354+
H, Buffer.begin(), Buffer.capacity(), FILE_NAME_NORMALIZED);
355+
if (CountChars && CountChars >= Buffer.capacity()) {
357356
// The buffer wasn't big enough, try again. In this case the return value
358357
// *does* indicate the size of the null terminator.
359358
Buffer.reserve(CountChars);
360359
CountChars = ::GetFinalPathNameByHandleW(
361-
H, Buffer.data(), Buffer.capacity() - 1, FILE_NAME_NORMALIZED);
360+
H, Buffer.begin(), Buffer.capacity(), FILE_NAME_NORMALIZED);
362361
}
363362
if (CountChars == 0)
364363
return mapWindowsError(GetLastError());
@@ -403,6 +402,20 @@ std::error_code is_local(int FD, bool &Result) {
403402
}
404403

405404
static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
405+
// First, check if the file is on a network (non-local) drive. If so, don't
406+
// set DeleteFile to true, since it prevents opening the file for writes.
407+
SmallVector<wchar_t, 128> FinalPath;
408+
if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
409+
return EC;
410+
411+
bool IsLocal;
412+
if (std::error_code EC = is_local_internal(FinalPath, IsLocal))
413+
return EC;
414+
415+
if (!IsLocal)
416+
return std::error_code();
417+
418+
// The file is on a local drive, set the DeleteFile to true.
406419
FILE_DISPOSITION_INFO Disposition;
407420
Disposition.DeleteFile = Delete;
408421
if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,

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

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,15 @@ class AArch64InstructionSelector : public InstructionSelector {
289289
getExtendTypeForInst(MachineInstr &MI, MachineRegisterInfo &MRI,
290290
bool IsLoadStore = false) const;
291291

292-
/// Instructions that accept extend modifiers like UXTW expect the register
293-
/// being extended to be a GPR32. Narrow ExtReg to a 32-bit register using a
294-
/// subregister copy if necessary. Return either ExtReg, or the result of the
295-
/// new copy.
296-
Register narrowExtendRegIfNeeded(Register ExtReg,
297-
MachineIRBuilder &MIB) const;
298-
Register widenGPRBankRegIfNeeded(Register Reg, unsigned Size,
299-
MachineIRBuilder &MIB) const;
292+
/// Move \p Reg to \p RC if \p Reg is not already on \p RC.
293+
///
294+
/// \returns Either \p Reg if no change was necessary, or the new register
295+
/// created by moving \p Reg.
296+
///
297+
/// Note: This uses emitCopy right now.
298+
Register moveScalarRegClass(Register Reg, const TargetRegisterClass &RC,
299+
MachineIRBuilder &MIB) const;
300+
300301
ComplexRendererFns selectArithExtendedRegister(MachineOperand &Root) const;
301302

302303
void renderTruncImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
@@ -1195,10 +1196,10 @@ MachineInstr *AArch64InstructionSelector::emitTestBit(
11951196
// TBNZW work.
11961197
bool UseWReg = Bit < 32;
11971198
unsigned NecessarySize = UseWReg ? 32 : 64;
1198-
if (Size < NecessarySize)
1199-
TestReg = widenGPRBankRegIfNeeded(TestReg, NecessarySize, MIB);
1200-
else if (Size > NecessarySize)
1201-
TestReg = narrowExtendRegIfNeeded(TestReg, MIB);
1199+
if (Size != NecessarySize)
1200+
TestReg = moveScalarRegClass(
1201+
TestReg, UseWReg ? AArch64::GPR32RegClass : AArch64::GPR64RegClass,
1202+
MIB);
12021203

12031204
static const unsigned OpcTable[2][2] = {{AArch64::TBZX, AArch64::TBNZX},
12041205
{AArch64::TBZW, AArch64::TBNZW}};
@@ -4907,9 +4908,19 @@ AArch64InstructionSelector::selectExtendedSHL(
49074908
return None;
49084909

49094910
unsigned OffsetOpc = OffsetInst->getOpcode();
4910-
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
4911-
return None;
4911+
bool LookedThroughZExt = false;
4912+
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL) {
4913+
// Try to look through a ZEXT.
4914+
if (OffsetOpc != TargetOpcode::G_ZEXT || !WantsExt)
4915+
return None;
4916+
4917+
OffsetInst = MRI.getVRegDef(OffsetInst->getOperand(1).getReg());
4918+
OffsetOpc = OffsetInst->getOpcode();
4919+
LookedThroughZExt = true;
49124920

4921+
if (OffsetOpc != TargetOpcode::G_SHL && OffsetOpc != TargetOpcode::G_MUL)
4922+
return None;
4923+
}
49134924
// Make sure that the memory op is a valid size.
49144925
int64_t LegalShiftVal = Log2_32(SizeInBytes);
49154926
if (LegalShiftVal == 0)
@@ -4960,21 +4971,24 @@ AArch64InstructionSelector::selectExtendedSHL(
49604971

49614972
unsigned SignExtend = 0;
49624973
if (WantsExt) {
4963-
// Check if the offset is defined by an extend.
4964-
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
4965-
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
4966-
if (Ext == AArch64_AM::InvalidShiftExtend)
4967-
return None;
4974+
// Check if the offset is defined by an extend, unless we looked through a
4975+
// G_ZEXT earlier.
4976+
if (!LookedThroughZExt) {
4977+
MachineInstr *ExtInst = getDefIgnoringCopies(OffsetReg, MRI);
4978+
auto Ext = getExtendTypeForInst(*ExtInst, MRI, true);
4979+
if (Ext == AArch64_AM::InvalidShiftExtend)
4980+
return None;
49684981

4969-
SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
4970-
// We only support SXTW for signed extension here.
4971-
if (SignExtend && Ext != AArch64_AM::SXTW)
4972-
return None;
4982+
SignExtend = isSignExtendShiftType(Ext) ? 1 : 0;
4983+
// We only support SXTW for signed extension here.
4984+
if (SignExtend && Ext != AArch64_AM::SXTW)
4985+
return None;
4986+
OffsetReg = ExtInst->getOperand(1).getReg();
4987+
}
49734988

49744989
// Need a 32-bit wide register here.
49754990
MachineIRBuilder MIB(*MRI.getVRegDef(Root.getReg()));
4976-
OffsetReg = ExtInst->getOperand(1).getReg();
4977-
OffsetReg = narrowExtendRegIfNeeded(OffsetReg, MIB);
4991+
OffsetReg = moveScalarRegClass(OffsetReg, AArch64::GPR32RegClass, MIB);
49784992
}
49794993

49804994
// We can use the LHS of the GEP as the base, and the LHS of the shift as an
@@ -5146,8 +5160,8 @@ AArch64InstructionSelector::selectAddrModeWRO(MachineOperand &Root,
51465160

51475161
// Need a 32-bit wide register.
51485162
MachineIRBuilder MIB(*PtrAdd);
5149-
Register ExtReg =
5150-
narrowExtendRegIfNeeded(OffsetInst->getOperand(1).getReg(), MIB);
5163+
Register ExtReg = moveScalarRegClass(OffsetInst->getOperand(1).getReg(),
5164+
AArch64::GPR32RegClass, MIB);
51515165
unsigned SignExtend = Ext == AArch64_AM::SXTW;
51525166

51535167
// Base is LHS, offset is ExtReg.
@@ -5421,67 +5435,21 @@ AArch64_AM::ShiftExtendType AArch64InstructionSelector::getExtendTypeForInst(
54215435
}
54225436
}
54235437

5424-
Register AArch64InstructionSelector::narrowExtendRegIfNeeded(
5425-
Register ExtReg, MachineIRBuilder &MIB) const {
5438+
Register AArch64InstructionSelector::moveScalarRegClass(
5439+
Register Reg, const TargetRegisterClass &RC, MachineIRBuilder &MIB) const {
54265440
MachineRegisterInfo &MRI = *MIB.getMRI();
5427-
if (MRI.getType(ExtReg).getSizeInBits() == 32)
5428-
return ExtReg;
5429-
5430-
// Insert a copy to move ExtReg to GPR32.
5431-
Register NarrowReg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
5432-
auto Copy = MIB.buildCopy({NarrowReg}, {ExtReg});
5441+
auto Ty = MRI.getType(Reg);
5442+
assert(!Ty.isVector() && "Expected scalars only!");
5443+
if (Ty.getSizeInBits() == TRI.getRegSizeInBits(RC))
5444+
return Reg;
54335445

5434-
// Select the copy into a subregister copy.
5446+
// Create a copy and immediately select it.
5447+
// FIXME: We should have an emitCopy function?
5448+
auto Copy = MIB.buildCopy({&RC}, {Reg});
54355449
selectCopy(*Copy, TII, MRI, TRI, RBI);
54365450
return Copy.getReg(0);
54375451
}
54385452

5439-
Register AArch64InstructionSelector::widenGPRBankRegIfNeeded(
5440-
Register Reg, unsigned WideSize, MachineIRBuilder &MIB) const {
5441-
assert(WideSize >= 8 && "WideSize is smaller than all possible registers?");
5442-
MachineRegisterInfo &MRI = *MIB.getMRI();
5443-
unsigned NarrowSize = MRI.getType(Reg).getSizeInBits();
5444-
assert(WideSize >= NarrowSize &&
5445-
"WideSize cannot be smaller than NarrowSize!");
5446-
5447-
// If the sizes match, just return the register.
5448-
//
5449-
// If NarrowSize is an s1, then we can select it to any size, so we'll treat
5450-
// it as a don't care.
5451-
if (NarrowSize == WideSize || NarrowSize == 1)
5452-
return Reg;
5453-
5454-
// Now check the register classes.
5455-
const RegisterBank *RB = RBI.getRegBank(Reg, MRI, TRI);
5456-
const TargetRegisterClass *OrigRC = getMinClassForRegBank(*RB, NarrowSize);
5457-
const TargetRegisterClass *WideRC = getMinClassForRegBank(*RB, WideSize);
5458-
assert(OrigRC && "Could not determine narrow RC?");
5459-
assert(WideRC && "Could not determine wide RC?");
5460-
5461-
// If the sizes differ, but the register classes are the same, there is no
5462-
// need to insert a SUBREG_TO_REG.
5463-
//
5464-
// For example, an s8 that's supposed to be a GPR will be selected to either
5465-
// a GPR32 or a GPR64 register. Note that this assumes that the s8 will
5466-
// always end up on a GPR32.
5467-
if (OrigRC == WideRC)
5468-
return Reg;
5469-
5470-
// We have two different register classes. Insert a SUBREG_TO_REG.
5471-
unsigned SubReg = 0;
5472-
getSubRegForClass(OrigRC, TRI, SubReg);
5473-
assert(SubReg && "Couldn't determine subregister?");
5474-
5475-
// Build the SUBREG_TO_REG and return the new, widened register.
5476-
auto SubRegToReg =
5477-
MIB.buildInstr(AArch64::SUBREG_TO_REG, {WideRC}, {})
5478-
.addImm(0)
5479-
.addUse(Reg)
5480-
.addImm(SubReg);
5481-
constrainSelectedInstRegOperands(*SubRegToReg, TII, TRI, RBI);
5482-
return SubRegToReg.getReg(0);
5483-
}
5484-
54855453
/// Select an "extended register" operand. This operand folds in an extend
54865454
/// followed by an optional left shift.
54875455
InstructionSelector::ComplexRendererFns
@@ -5542,7 +5510,7 @@ AArch64InstructionSelector::selectArithExtendedRegister(
55425510
// We require a GPR32 here. Narrow the ExtReg if needed using a subregister
55435511
// copy.
55445512
MachineIRBuilder MIB(*RootDef);
5545-
ExtReg = narrowExtendRegIfNeeded(ExtReg, MIB);
5513+
ExtReg = moveScalarRegClass(ExtReg, AArch64::GPR32RegClass, MIB);
55465514

55475515
return {{[=](MachineInstrBuilder &MIB) { MIB.addUse(ExtReg); },
55485516
[=](MachineInstrBuilder &MIB) {

llvm/test/CodeGen/AArch64/GlobalISel/load-wro-addressing-modes.mir

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,39 @@ body: |
428428
$x1 = COPY %load(s64)
429429
RET_ReallyLR implicit $x1
430430
...
431+
---
432+
name: zext_shl_LDRWroW
433+
alignment: 4
434+
legalized: true
435+
regBankSelected: true
436+
tracksRegLiveness: true
437+
liveins:
438+
- { reg: '$w0' }
439+
- { reg: '$x1' }
440+
body: |
441+
bb.1:
442+
liveins: $w0, $x1
443+
444+
; We try to look through the G_ZEXT of the SHL here.
445+
446+
; CHECK-LABEL: name: zext_shl_LDRWroW
447+
; CHECK: liveins: $w0, $x1
448+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
449+
; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1
450+
; CHECK: [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY]], 7
451+
; CHECK: [[LDRWroW:%[0-9]+]]:gpr32 = LDRWroW [[COPY1]], [[ANDWri]], 0, 1 :: (load 4)
452+
; CHECK: $w0 = COPY [[LDRWroW]]
453+
; CHECK: RET_ReallyLR implicit $w0
454+
%0:gpr(s32) = COPY $w0
455+
%1:gpr(p0) = COPY $x1
456+
%2:gpr(s32) = G_CONSTANT i32 255
457+
%3:gpr(s32) = G_AND %0, %2
458+
%13:gpr(s64) = G_CONSTANT i64 2
459+
%12:gpr(s32) = G_SHL %3, %13(s64)
460+
%6:gpr(s64) = G_ZEXT %12(s32)
461+
%7:gpr(p0) = G_PTR_ADD %1, %6(s64)
462+
%9:gpr(s32) = G_LOAD %7(p0) :: (load 4)
463+
$w0 = COPY %9(s32)
464+
RET_ReallyLR implicit $w0
465+
466+
...

llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-ext-tbz-tbnz.mir

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ body: |
7878
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
7979
; CHECK: liveins: $h0
8080
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG 0, $h0, %subreg.hsub
81-
; CHECK: %copy:gpr32 = COPY [[SUBREG_TO_REG]]
82-
; CHECK: TBNZW %copy, 3, %bb.1
81+
; CHECK: %copy:gpr32all = COPY [[SUBREG_TO_REG]]
82+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY %copy
83+
; CHECK: TBNZW [[COPY]], 3, %bb.1
8384
; CHECK: B %bb.0
8485
; CHECK: bb.1:
8586
; CHECK: RET_ReallyLR

llvm/test/CodeGen/AArch64/GlobalISel/subreg-copy.mir

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,35 @@ body: |
3434
bb.1:
3535
RET_ReallyLR
3636
...
37+
---
38+
name: no_trunc
39+
alignment: 4
40+
legalized: true
41+
regBankSelected: true
42+
tracksRegLiveness: true
43+
body: |
44+
; CHECK-LABEL: name: no_trunc
45+
; CHECK: bb.0:
46+
; CHECK: successors: %bb.1(0x80000000)
47+
; CHECK: liveins: $x0
48+
; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
49+
; CHECK: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load 16)
50+
; CHECK: [[COPY1:%[0-9]+]]:gpr64all = COPY [[LDRQui]].dsub
51+
; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]]
52+
; CHECK: TBNZX [[COPY2]], 33, %bb.1
53+
; CHECK: bb.1:
54+
; CHECK: RET_ReallyLR
55+
bb.0:
56+
liveins: $x0
57+
%1:gpr(p0) = COPY $x0
58+
%3:gpr(s64) = G_CONSTANT i64 8589934592
59+
%5:gpr(s64) = G_CONSTANT i64 0
60+
%0:fpr(s128) = G_LOAD %1:gpr(p0) :: (load 16)
61+
%2:fpr(s64) = G_TRUNC %0:fpr(s128)
62+
%8:gpr(s64) = COPY %2:fpr(s64)
63+
%4:gpr(s64) = G_AND %8:gpr, %3:gpr
64+
%7:gpr(s32) = G_ICMP intpred(ne), %4:gpr(s64), %5:gpr
65+
%6:gpr(s1) = G_TRUNC %7:gpr(s32)
66+
G_BRCOND %6:gpr(s1), %bb.1
67+
bb.1:
68+
RET_ReallyLR

llvm/test/CodeGen/AArch64/GlobalISel/widen-narrow-tbz-tbnz.mir

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ body: |
106106
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
107107
; CHECK: liveins: $w0
108108
; CHECK: %reg:gpr32all = COPY $w0
109-
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, %reg, %subreg.sub_32
110-
; CHECK: TBZX [[SUBREG_TO_REG]], 33, %bb.1
109+
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, %reg, %subreg.sub_32
110+
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
111+
; CHECK: TBZX [[COPY]], 33, %bb.1
111112
; CHECK: B %bb.0
112113
; CHECK: bb.1:
113114
; CHECK: RET_ReallyLR
@@ -140,8 +141,9 @@ body: |
140141
; CHECK: bb.0:
141142
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
142143
; CHECK: %reg:gpr32 = IMPLICIT_DEF
143-
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, %reg, %subreg.sub_32
144-
; CHECK: TBZX [[SUBREG_TO_REG]], 33, %bb.1
144+
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, %reg, %subreg.sub_32
145+
; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
146+
; CHECK: TBZX [[COPY]], 33, %bb.1
145147
; CHECK: B %bb.0
146148
; CHECK: bb.1:
147149
; CHECK: RET_ReallyLR

0 commit comments

Comments
 (0)