27 changes: 14 additions & 13 deletions cmake/modules/CheckAtomic.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,20 @@ else()
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
endif()

# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
if(HAVE_CXX_LIBATOMICS64)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()
# RUST-SPECIFIC - commented out, see commit message
# # If not, check if the library exists, and atomics work with it.
# if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
# check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
# if(HAVE_CXX_LIBATOMICS64)
# list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
# check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
# if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
# message(FATAL_ERROR "Host compiler must support std::atomic!")
# endif()
# else()
# message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
# endif()
# endif()

## TODO: This define is only used for the legacy atomic operations in
## llvm's Atomic.h, which should be replaced. Other code simply
Expand Down
10 changes: 10 additions & 0 deletions include/llvm/Analysis/TargetLibraryInfo.def
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,16 @@ TLI_DEFINE_STRING_INTERNAL("__powf_finite")
/// long double __powl_finite(long double x, long double y);
TLI_DEFINE_ENUM_INTERNAL(powl_finite)
TLI_DEFINE_STRING_INTERNAL("__powl_finite")

TLI_DEFINE_ENUM_INTERNAL(rust_alloc)
TLI_DEFINE_STRING_INTERNAL("__rust_alloc")

TLI_DEFINE_ENUM_INTERNAL(rust_dealloc)
TLI_DEFINE_STRING_INTERNAL("__rust_dealloc")

TLI_DEFINE_ENUM_INTERNAL(rust_realloc)
TLI_DEFINE_STRING_INTERNAL("__rust_realloc")

/// double __sincospi_stret(double x);
TLI_DEFINE_ENUM_INTERNAL(sincospi_stret)
TLI_DEFINE_STRING_INTERNAL("__sincospi_stret")
Expand Down
9 changes: 9 additions & 0 deletions include/llvm/MC/MCSubtargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,19 @@ class MCSubtargetInfo {
return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
}


/// Returns string representation of scheduler comment
virtual std::string getSchedInfoStr(MCInst const &MCI) const {
return {};
}

ArrayRef<SubtargetFeatureKV> getCPUTable() const {
return ProcDesc;
}

ArrayRef<SubtargetFeatureKV> getFeatureTable() const {
return ProcFeatures;
}
};

} // end namespace llvm
Expand Down
8 changes: 6 additions & 2 deletions lib/Analysis/MemoryBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
{LibFunc_realloc, {ReallocLike, 2, 1, -1}},
{LibFunc_reallocf, {ReallocLike, 2, 1, -1}},
{LibFunc_strdup, {StrDupLike, 1, -1, -1}},
{LibFunc_strndup, {StrDupLike, 2, 1, -1}}
{LibFunc_strndup, {StrDupLike, 2, 1, -1}},

{LibFunc_rust_alloc, {MallocLike, 2, 0, -1}},
{LibFunc_rust_realloc, {ReallocLike, 4, 3, -1}},
// TODO: Handle "int posix_memalign(void **, size_t, size_t)"
};

Expand Down Expand Up @@ -399,7 +402,8 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow)
ExpectedNumParams = 2;
else if (TLIFn == LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t || // delete(void*, align_val_t, nothrow)
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t || // delete[](void*, align_val_t, nothrow)
TLIFn == LibFunc_rust_dealloc)
ExpectedNumParams = 3;
else
return nullptr;
Expand Down
22 changes: 22 additions & 0 deletions lib/Analysis/TargetLibraryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,28 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
else
return false;
}

case LibFunc_rust_alloc:
return (NumParams == 3 && FTy.getReturnType()->isPointerTy() &&
FTy.getParamType(0)->isIntegerTy() &&
FTy.getParamType(1)->isIntegerTy() &&
FTy.getParamType(2)->isPointerTy());

case LibFunc_rust_dealloc:
return (NumParams == 3 && FTy.getReturnType()->isVoidTy() &&
FTy.getParamType(0)->isPointerTy() &&
FTy.getParamType(1)->isIntegerTy() &&
FTy.getParamType(2)->isIntegerTy());

case LibFunc_rust_realloc:
return (NumParams == 6 && FTy.getReturnType()->isPointerTy() &&
FTy.getParamType(0)->isPointerTy() &&
FTy.getParamType(1)->isIntegerTy() &&
FTy.getParamType(2)->isIntegerTy() &&
FTy.getParamType(3)->isIntegerTy() &&
FTy.getParamType(4)->isIntegerTy() &&
FTy.getParamType(5)->isPointerTy());

case LibFunc::NumLibFuncs:
break;
}
Expand Down
9 changes: 6 additions & 3 deletions lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,9 +758,12 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
// instructions (in fact, they get ignored if they *do* exist).
MF->setVariableDbgInfo(DI.getVariable(), DI.getExpression(),
getOrCreateFrameIndex(*AI), DI.getDebugLoc());
} else
MIRBuilder.buildDirectDbgValue(getOrCreateVReg(*Address),
DI.getVariable(), DI.getExpression());
} else {
// A dbg.declare describes the address of a source variable, so lower it
// into an indirect DBG_VALUE.
MIRBuilder.buildIndirectDbgValue(getOrCreateVReg(*Address),
DI.getVariable(), DI.getExpression());
}
return true;
}
case Intrinsic::dbg_label: {
Expand Down
6 changes: 3 additions & 3 deletions lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ RTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) {
if (Name == "stat") return (uint64_t)&stat;
if (Name == "fstat") return (uint64_t)&fstat;
if (Name == "lstat") return (uint64_t)&lstat;
if (Name == "stat64") return (uint64_t)&stat64;
if (Name == "fstat64") return (uint64_t)&fstat64;
if (Name == "lstat64") return (uint64_t)&lstat64;
// if (Name == "stat64") return (uint64_t)&stat64;
// if (Name == "fstat64") return (uint64_t)&fstat64;
// if (Name == "lstat64") return (uint64_t)&lstat64;
if (Name == "atexit") return (uint64_t)&atexit;
if (Name == "mknod") return (uint64_t)&mknod;

Expand Down
2 changes: 1 addition & 1 deletion lib/Support/Unix/Program.inc
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
static long ArgMax = sysconf(_SC_ARG_MAX);
// POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible
// value for ARG_MAX on a POSIX compliant system.
static long ArgMin = _POSIX_ARG_MAX;
static long ArgMin = 4096;

// This the same baseline used by xargs.
long EffectiveArgMax = 128 * 1024;
Expand Down
20 changes: 15 additions & 5 deletions lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3510,9 +3510,14 @@ SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
// Argument stored in memory.
assert(VA.isMemLoc());

// Get the extended size of the argument type in stack
unsigned ArgSize = VA.getLocVT().getStoreSize();
int FI = MFI.CreateFixedObject(ArgSize, VA.getLocMemOffset(),
isImmutable);
// Get the actual size of the argument type
unsigned ObjSize = VA.getValVT().getStoreSize();
unsigned ArgOffset = VA.getLocMemOffset();
// Stack objects in PPC32 are right justified.
ArgOffset += ArgSize - ObjSize;
int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, isImmutable);

// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
Expand Down Expand Up @@ -5467,10 +5472,15 @@ SDValue PPCTargetLowering::LowerCall_32SVR4(
Arg = PtrOff;
}

if (VA.isRegLoc()) {
if (Arg.getValueType() == MVT::i1)
Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Arg);
// When useCRBits() is true, there can be i1 arguments.
// It is because getRegisterType(MVT::i1) => MVT::i1,
// and for other integer types getRegisterType() => MVT::i32.
// Extend i1 and ensure callee will get i32.
if (Arg.getValueType() == MVT::i1)
Arg = DAG.getNode(Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
dl, MVT::i32, Arg);

if (VA.isRegLoc()) {
seenFloatArg |= VA.getLocVT().isFloatingPoint();
// Put argument in a physical register.
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
Expand Down
42 changes: 42 additions & 0 deletions lib/Transforms/Scalar/SROA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3046,6 +3046,42 @@ class llvm::sroa::AllocaSliceRewriter
return true;
}

void fixLoadStoreAlign(Instruction &Root) {
// This algorithm implements the same visitor loop as
// hasUnsafePHIOrSelectUse, and fixes the alignment of each load
// or store found.
SmallPtrSet<Instruction *, 4> Visited;
SmallVector<Instruction *, 4> Uses;
Visited.insert(&Root);
Uses.push_back(&Root);
do {
Instruction *I = Uses.pop_back_val();

if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
unsigned LoadAlign = LI->getAlignment();
if (!LoadAlign)
LoadAlign = DL.getABITypeAlignment(LI->getType());
LI->setAlignment(std::min(LoadAlign, getSliceAlign()));
continue;
}
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
unsigned StoreAlign = SI->getAlignment();
if (!StoreAlign) {
Value *Op = SI->getOperand(0);
StoreAlign = DL.getABITypeAlignment(Op->getType());
}
SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
continue;
}

assert(isa<BitCastInst>(I) || isa<PHINode>(I) ||
isa<SelectInst>(I) || isa<GetElementPtrInst>(I));
for (User *U : I->users())
if (Visited.insert(cast<Instruction>(U)).second)
Uses.push_back(cast<Instruction>(U));
} while (!Uses.empty());
}

bool visitPHINode(PHINode &PN) {
LLVM_DEBUG(dbgs() << " original: " << PN << "\n");
assert(BeginOffset >= NewAllocaBeginOffset && "PHIs are unsplittable");
Expand All @@ -3069,6 +3105,9 @@ class llvm::sroa::AllocaSliceRewriter
LLVM_DEBUG(dbgs() << " to: " << PN << "\n");
deleteIfTriviallyDead(OldPtr);

// Fix the alignment of any loads or stores using this PHI node.
fixLoadStoreAlign(PN);

// PHIs can't be promoted on their own, but often can be speculated. We
// check the speculation outside of the rewriter so that we see the
// fully-rewritten alloca.
Expand All @@ -3093,6 +3132,9 @@ class llvm::sroa::AllocaSliceRewriter
LLVM_DEBUG(dbgs() << " to: " << SI << "\n");
deleteIfTriviallyDead(OldPtr);

// Fix the alignment of any loads or stores using this select.
fixLoadStoreAlign(SI);

// Selects can't be promoted on their own, but often can be speculated. We
// check the speculation outside of the rewriter so that we see the
// fully-rewritten alloca.
Expand Down
67 changes: 67 additions & 0 deletions test/CodeGen/AArch64/GlobalISel/debug-cpp.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
; RUN: llc -global-isel -mtriple=aarch64 %s -stop-after=irtranslator -o - | FileCheck %s
; RUN: llc -mtriple=aarch64 -global-isel --global-isel-abort=0 -o /dev/null

; struct NTCopy {
; NTCopy();
; NTCopy(const NTCopy &);
; int x;
; };
; int foo(NTCopy o) {
; return o.x;
; }

; ModuleID = 'ntcopy.cpp'
source_filename = "ntcopy.cpp"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

%struct.NTCopy = type { i32 }

; CHECK-LABEL: name: _Z3foo6NTCopy
; CHECK: DBG_VALUE debug-use %{{[0-9]+}}(p0), 0, !23, !DIExpression(), debug-location !24
; Function Attrs: noinline nounwind optnone
define dso_local i32 @_Z3foo6NTCopy(%struct.NTCopy* %o) #0 !dbg !7 {
entry:
call void @llvm.dbg.declare(metadata %struct.NTCopy* %o, metadata !23, metadata !DIExpression()), !dbg !24
%x = getelementptr inbounds %struct.NTCopy, %struct.NTCopy* %o, i32 0, i32 0, !dbg !25
%0 = load i32, i32* %x, align 4, !dbg !25
ret i32 %0, !dbg !26
}

; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

attributes #0 = { noinline nounwind optnone }
attributes #1 = { nounwind readnone speculatable }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "ntcopy.cpp", directory: "/tmp")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 8.0.0 "}
!7 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foo6NTCopy", scope: !1, file: !1, line: 6, type: !8, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !11}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NTCopy", file: !1, line: 1, size: 32, flags: DIFlagTypePassByReference, elements: !12, identifier: "_ZTS6NTCopy")
!12 = !{!13, !14, !18}
!13 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !11, file: !1, line: 4, baseType: !10, size: 32)
!14 = !DISubprogram(name: "NTCopy", scope: !11, file: !1, line: 2, type: !15, isLocal: false, isDefinition: false, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false)
!15 = !DISubroutineType(types: !16)
!16 = !{null, !17}
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
!18 = !DISubprogram(name: "NTCopy", scope: !11, file: !1, line: 3, type: !19, isLocal: false, isDefinition: false, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false)
!19 = !DISubroutineType(types: !20)
!20 = !{null, !17, !21}
!21 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !22, size: 64)
!22 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !11)
!23 = !DILocalVariable(name: "o", arg: 1, scope: !7, file: !1, line: 6, type: !11)
!24 = !DILocation(line: 6, column: 16, scope: !7)
!25 = !DILocation(line: 7, column: 12, scope: !7)
!26 = !DILocation(line: 7, column: 3, scope: !7)
4 changes: 1 addition & 3 deletions test/CodeGen/AArch64/GlobalISel/debug-insts.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
; CHECK: - { id: {{.*}}, name: in.addr, type: default, offset: 0, size: {{.*}}, alignment: {{.*}},
; CHECK-NEXT: callee-saved-register: '', callee-saved-restored: true,
; CHECK-NEXT: debug-info-variable: '!11', debug-info-expression: '!DIExpression()',
; CHECK: DBG_VALUE debug-use %0(s32), debug-use $noreg, !11, !DIExpression(), debug-location !12
define void @debug_declare(i32 %in) #0 !dbg !7 {
entry:
%in.addr = alloca i32, align 4
store i32 %in, i32* %in.addr, align 4
call void @llvm.dbg.declare(metadata i32* %in.addr, metadata !11, metadata !DIExpression()), !dbg !12
call void @llvm.dbg.declare(metadata i32 %in, metadata !11, metadata !DIExpression()), !dbg !12
ret void, !dbg !12
}

; CHECK-LABEL: name: debug_declare_vla
; CHECK: DBG_VALUE debug-use %{{[0-9]+}}(p0), debug-use $noreg, !14, !DIExpression(), debug-location !15
; CHECK: DBG_VALUE debug-use %{{[0-9]+}}(p0), 0, !14, !DIExpression(), debug-location !15
define void @debug_declare_vla(i32 %in) #0 !dbg !13 {
entry:
%vla.addr = alloca i32, i32 %in
Expand Down
24 changes: 24 additions & 0 deletions test/CodeGen/PowerPC/ppc32-i1-stack-arguments-abi-bug.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; RUN: llc -verify-machineinstrs < %s -mcpu=ppc32 -mattr=+crbits | FileCheck %s
target triple = "powerpc-unknown-linux-gnu"

define void @check_callee(
i32, i32, i32, i32,
i32, i32, i32, i32,
i1 zeroext %s1
) {
call void @check_caller(
i32 9, i32 9, i32 9, i32 9,
i32 9, i32 9, i32 9, i32 9,
i1 zeroext %s1)
ret void
}

; CHECK-LABEL: @check_callee
; CHECK: lbz {{[0-9]+}}, 27(1)
; CHECK: stw {{[0-9]+}}, 8(1)

declare void @check_caller(
i32, i32, i32, i32,
i32, i32, i32, i32,
i1 zeroext
)
Loading