aboutsummaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-06-27 18:34:17 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-06-27 18:34:17 +0000
commitdbb6490749e2bb2a514a8a305b8fadc3495183e6 (patch)
treedd42cfd6d9813d5640a01083bdc0eedcb3f862c2 /llvm/lib
parent483b61a50e7423b063fc26985325f594560b3f7e (diff)
downloadsrc-vendor/llvm-project/release-10.x.tar.gz
src-vendor/llvm-project/release-10.x.zip
llvmorg-10.0.1-rc2-0-g77d76b71d7d.
Notes
Notes: svn path=/vendor/llvm-project/release-10.x/; revision=362703 svn path=/vendor/llvm-project/llvmorg-10.0.1-0-gef32c611aa2/; revision=363400; tag=vendor/llvm-project/llvmorg-10.0.1-0-gef32c611aa2
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp14
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp26
-rw-r--r--llvm/lib/Target/AArch64/AArch64FrameLowering.cpp101
-rw-r--r--llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp7
-rw-r--r--llvm/lib/Target/RISCV/RISCVFrameLowering.cpp4
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp34
6 files changed, 127 insertions, 59 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 6aed5796acc6..015b3d99fb0f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -271,8 +271,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N,
return Res.getValue(1);
}
- SDValue Op2 = GetPromotedInteger(N->getOperand(2));
+ // Op2 is used for the comparison and thus must be extended according to the
+ // target's atomic operations. Op3 is merely stored and so can be left alone.
+ SDValue Op2 = N->getOperand(2);
SDValue Op3 = GetPromotedInteger(N->getOperand(3));
+ if (TLI.getTargetMachine().getTargetTriple().isRISCV()) {
+ // The comparison argument must be sign-extended for RISC-V. This is
+ // abstracted using a new TargetLowering hook in the main LLVM development
+ // branch, but handled here directly in order to fix the codegen bug for
+ // 10.x without breaking the libLLVM.so ABI.
+ Op2 = SExtPromotedInteger(Op2);
+ } else {
+ Op2 = GetPromotedInteger(Op2);
+ }
+
SDVTList VTs =
DAG.getVTList(Op2.getValueType(), N->getValueType(1), MVT::Other);
SDValue Res = DAG.getAtomicCmpSwap(
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 24ab65171a17..368e2100031f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -5490,9 +5490,20 @@ char TargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG,
EVT VT = Op.getValueType();
const SDNodeFlags Flags = Op->getFlags();
const TargetOptions &Options = DAG.getTarget().Options;
- if (!Op.hasOneUse() && !(Op.getOpcode() == ISD::FP_EXTEND &&
- isFPExtFree(VT, Op.getOperand(0).getValueType())))
- return 0;
+ if (!Op.hasOneUse()) {
+ bool IsFreeExtend = Op.getOpcode() == ISD::FP_EXTEND &&
+ isFPExtFree(VT, Op.getOperand(0).getValueType());
+
+ // If we already have the use of the negated floating constant, it is free
+ // to negate it even it has multiple uses.
+ bool IsFreeConstant =
+ Op.getOpcode() == ISD::ConstantFP &&
+ !getNegatedExpression(Op, DAG, LegalOperations, ForCodeSize)
+ .use_empty();
+
+ if (!IsFreeExtend && !IsFreeConstant)
+ return 0;
+ }
// Don't recurse exponentially.
if (Depth > SelectionDAG::MaxRecursionDepth)
@@ -5687,14 +5698,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
ForCodeSize, Depth + 1);
char V1 = isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations,
ForCodeSize, Depth + 1);
- // TODO: This is a hack. It is possible that costs have changed between now
- // and the initial calls to isNegatibleForFree(). That is because we
- // are rewriting the expression, and that may change the number of
- // uses (and therefore the cost) of values. If the negation costs are
- // equal, only negate this value if it is a constant. Otherwise, try
- // operand 1. A better fix would eliminate uses as a cost factor or
- // track the change in uses as we rewrite the expression.
- if (V0 > V1 || (V0 == V1 && isa<ConstantFPSDNode>(Op.getOperand(0)))) {
+ if (V0 > V1) {
// fold (fneg (fma X, Y, Z)) -> (fma (fneg X), Y, (fneg Z))
SDValue Neg0 = getNegatedExpression(
Op.getOperand(0), DAG, LegalOperations, ForCodeSize, Depth + 1);
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index ea3e800a1ad2..651ad9ad4c83 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -211,6 +211,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() const {
return TargetStackID::SVEVector;
}
+/// Returns the size of the fixed object area (allocated next to sp on entry)
+/// On Win64 this may include a var args area and an UnwindHelp object for EH.
+static unsigned getFixedObjectSize(const MachineFunction &MF,
+ const AArch64FunctionInfo *AFI, bool IsWin64,
+ bool IsFunclet) {
+ if (!IsWin64 || IsFunclet) {
+ // Only Win64 uses fixed objects, and then only for the function (not
+ // funclets)
+ return 0;
+ } else {
+ // Var args are stored here in the primary function.
+ const unsigned VarArgsArea = AFI->getVarArgsGPRSize();
+ // To support EH funclets we allocate an UnwindHelp object
+ const unsigned UnwindHelpObject = (MF.hasEHFunclets() ? 8 : 0);
+ return alignTo(VarArgsArea + UnwindHelpObject, 16);
+ }
+}
+
/// Returns the size of the entire SVE stackframe (calleesaves + spills).
static StackOffset getSVEStackSize(const MachineFunction &MF) {
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
@@ -959,10 +977,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
- // Var args are accounted for in the containing function, so don't
- // include them for funclets.
- unsigned FixedObject = (IsWin64 && !IsFunclet) ?
- alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
+ unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
// All of the remaining stack allocations are for locals.
@@ -993,32 +1008,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
++MBBI;
}
- // The code below is not applicable to funclets. We have emitted all the SEH
- // opcodes that we needed to emit. The FP and BP belong to the containing
- // function.
- if (IsFunclet) {
- if (NeedsWinCFI) {
- HasWinCFI = true;
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
- .setMIFlag(MachineInstr::FrameSetup);
- }
-
- // SEH funclets are passed the frame pointer in X1. If the parent
- // function uses the base register, then the base register is used
- // directly, and is not retrieved from X1.
- if (F.hasPersonalityFn()) {
- EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
- if (isAsynchronousEHPersonality(Per)) {
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP)
- .addReg(AArch64::X1).setMIFlag(MachineInstr::FrameSetup);
- MBB.addLiveIn(AArch64::X1);
- }
- }
-
- return;
- }
-
- if (HasFP) {
+ // For funclets the FP belongs to the containing function.
+ if (!IsFunclet && HasFP) {
// Only set up FP if we actually need to.
int64_t FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16) : 0;
@@ -1161,7 +1152,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// Allocate space for the rest of the frame.
if (NumBytes) {
- const bool NeedsRealignment = RegInfo->needsStackRealignment(MF);
+ // Alignment is required for the parent frame, not the funclet
+ const bool NeedsRealignment =
+ !IsFunclet && RegInfo->needsStackRealignment(MF);
unsigned scratchSPReg = AArch64::SP;
if (NeedsRealignment) {
@@ -1215,7 +1208,8 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// FIXME: Clarify FrameSetup flags here.
// Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
// needed.
- if (RegInfo->hasBasePointer(MF)) {
+ // For funclets the BP belongs to the containing function.
+ if (!IsFunclet && RegInfo->hasBasePointer(MF)) {
TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP,
false);
if (NeedsWinCFI) {
@@ -1232,6 +1226,19 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
.setMIFlag(MachineInstr::FrameSetup);
}
+ // SEH funclets are passed the frame pointer in X1. If the parent
+ // function uses the base register, then the base register is used
+ // directly, and is not retrieved from X1.
+ if (IsFunclet && F.hasPersonalityFn()) {
+ EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
+ if (isAsynchronousEHPersonality(Per)) {
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP)
+ .addReg(AArch64::X1)
+ .setMIFlag(MachineInstr::FrameSetup);
+ MBB.addLiveIn(AArch64::X1);
+ }
+ }
+
if (needsFrameMoves) {
const DataLayout &TD = MF.getDataLayout();
const int StackGrowth = isTargetDarwin(MF)
@@ -1450,10 +1457,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
- // Var args are accounted for in the containing function, so don't
- // include them for funclets.
- unsigned FixedObject =
- (IsWin64 && !IsFunclet) ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
+ unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
uint64_t AfterCSRPopSize = ArgumentPopSize;
auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
@@ -1679,7 +1683,9 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
- unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
+
+ unsigned FixedObject =
+ getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
unsigned FPAdjust = isTargetDarwin(MF)
? 16 : AFI->getCalleeSavedStackSize(MF.getFrameInfo());
return {ObjectOffset + FixedObject + FPAdjust, MVT::i8};
@@ -2632,9 +2638,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
++MBBI;
// Create an UnwindHelp object.
- int UnwindHelpFI =
- MFI.CreateStackObject(/*size*/8, /*alignment*/16, false);
+ // The UnwindHelp object is allocated at the start of the fixed object area
+ int64_t FixedObject =
+ getFixedObjectSize(MF, AFI, /*IsWin64*/ true, /*IsFunclet*/ false);
+ int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8,
+ /*SPOffset*/ -FixedObject,
+ /*IsImmutable=*/false);
EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
+
// We need to store -2 into the UnwindHelp object at the start of the
// function.
DebugLoc DL;
@@ -2656,10 +2667,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
const MachineFunction &MF, int FI, unsigned &FrameReg,
bool IgnoreSPUpdates) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
- LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
- << MFI.getObjectOffset(FI) << "\n");
- FrameReg = AArch64::SP;
- return MFI.getObjectOffset(FI);
+ if (IgnoreSPUpdates) {
+ LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
+ << MFI.getObjectOffset(FI) << "\n");
+ FrameReg = AArch64::SP;
+ return MFI.getObjectOffset(FI);
+ }
+
+ return getFrameIndexReference(MF, FI, FrameReg);
}
/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 4311df5dbeb8..20c5ac7b378a 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -298,6 +298,11 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
+ case 'L': // A memory reference to the upper word of a double word op.
+ O << getDataLayout().getPointerSize() << "(";
+ printOperand(MI, OpNo, O);
+ O << ")";
+ return false;
case 'y': // A memory reference for an X-form instruction
{
const char *RegName = "r0";
@@ -309,7 +314,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
}
case 'U': // Print 'u' for update form.
case 'X': // Print 'x' for indexed form.
- {
// FIXME: Currently for PowerPC memory operands are always loaded
// into a register, so we never get an update or indexed form.
// This is bad even for offset forms, since even if we know we
@@ -319,7 +323,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
assert(MI->getOperand(OpNo).isReg());
return false;
}
- }
}
assert(MI->getOperand(OpNo).isReg());
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index c60fc3fc6b42..f7cd19cbb8e7 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -181,9 +181,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
adjustReg(MBB, MBBI, DL, FPReg, SPReg,
StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup);
- // Emit ".cfi_def_cfa $fp, 0"
+ // Emit ".cfi_def_cfa $fp, -RVFI->getVarArgsSaveSize()"
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
- nullptr, RI->getDwarfRegNum(FPReg, true), 0));
+ nullptr, RI->getDwarfRegNum(FPReg, true), -RVFI->getVarArgsSaveSize()));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 5a2cffbc824c..a1e3e326a97a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -197,6 +197,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setTruncStoreAction(MVT::f64, MVT::f16, Expand);
}
+ if (Subtarget.is64Bit() &&
+ !(Subtarget.hasStdExtD() || Subtarget.hasStdExtF())) {
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
+ }
+
setOperationAction(ISD::GlobalAddress, XLenVT, Custom);
setOperationAction(ISD::BlockAddress, XLenVT, Custom);
setOperationAction(ISD::ConstantPool, XLenVT, Custom);
@@ -876,6 +884,32 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
switch (N->getOpcode()) {
default:
llvm_unreachable("Don't know how to custom type legalize this operation!");
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT: {
+ bool IsStrict = N->isStrictFPOpcode();
+ assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
+ "Unexpected custom legalisation");
+ SDValue Op0 = IsStrict ? N->getOperand(1) : N->getOperand(0);
+ RTLIB::Libcall LC;
+ if (N->getOpcode() == ISD::FP_TO_SINT ||
+ N->getOpcode() == ISD::STRICT_FP_TO_SINT)
+ LC = RTLIB::getFPTOSINT(Op0.getValueType(), N->getValueType(0));
+ else
+ LC = RTLIB::getFPTOUINT(Op0.getValueType(), N->getValueType(0));
+ MakeLibCallOptions CallOptions;
+ EVT OpVT = Op0.getValueType();
+ CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
+ SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+ SDValue Result;
+ std::tie(Result, Chain) =
+ makeLibCall(DAG, LC, N->getValueType(0), Op0, CallOptions, DL, Chain);
+ Results.push_back(Result);
+ if (IsStrict)
+ Results.push_back(Chain);
+ break;
+ }
case ISD::READCYCLECOUNTER: {
assert(!Subtarget.is64Bit() &&
"READCYCLECOUNTER only has custom type legalization on riscv32");