Rollup of fixes since the 9.0.0 release.

- Change the default -march for i386 from i486 to i586.  This avoids
  the need for libatomics and had been the defacto default for some
  time. [0]

- Add -m(no)-spe to clang. (powerpc)

- Deduce MIPS specific ELF header flags from `emulation`. (mips)

- Fix a variety of assertions and compile/link errors including crashes
  with CPUTYPE=haswell. [1]

- Switch back to https for downloads. [2]

The new patches were initially committed to FreeBSD src by dim@.

PR:		240918 [0], 240759 [1], 240870 [2]
Reported by:	jbeich [0,1],  Miyashita Touka <imagin8r@protonmail.com> [2]
This commit is contained in:
Brooks Davis 2019-10-09 20:36:04 +00:00
parent d612ae70ed
commit a751f5cd7c
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=514194
7 changed files with 647 additions and 3 deletions

View File

@ -2,12 +2,12 @@
PORTNAME= llvm
DISTVERSION= 9.0.0
PORTREVISION= 0
PORTREVISION= 1
CATEGORIES= devel lang
.if ${DISTVERSION:M*rc*}
MASTER_SITES= http://prereleases.llvm.org/${LLVM_RELEASE}/${RCDIR}
MASTER_SITES= https://prereleases.llvm.org/${LLVM_RELEASE}/${RCDIR}
.else
MASTER_SITES= http://releases.llvm.org/${LLVM_RELEASE}/
MASTER_SITES= https://releases.llvm.org/${LLVM_RELEASE}/
.endif
PKGNAMESUFFIX= ${LLVM_SUFFIX}
DISTNAME= ${PORTNAME}-${DISTVERSION}.src
@ -117,6 +117,7 @@ LIT_DESC= Install lit and FileCheck test tools
LIT_VARS= _USES_PYTHON=python:3.6+
LLD_DESC= Install lld, the LLVM linker
LLD_DISTFILES= lld-${DISTVERSION}.src${EXTRACT_SUFX}
LLD_EXTRA_PATCHES= ${PATCHDIR}/lld
LLD_LINK_DESC= Link ld.lld as ld to clang uses it
LLD_LINK_IMPLIES= LLD
LLDB_BUILD_DEPENDS= swig3.0:devel/swig30 \

View File

@ -0,0 +1,36 @@
commit 5f6a983e7fba98335e2863fe31305e895545ebb2
Author: dim <dim@FreeBSD.org>
Date: Sun Sep 8 10:31:34 2019 +0000
Target i586 by default on the i386 architecture, since after upstream's
change https://reviews.llvm.org/rL356631 ("[X86] Add CMPXCHG8B feature
flag. Set it for all CPUs except i386/i486 including 'generic'. Disable
use of CMPXCHG8B when this flag isn't set"), clang now correctly emits
calls to __atomic_load_8, __atomic_store_8, etc. when targeting i486,
and this means we can no longer link most modern programs, because we do
not have a libatomic, nor support for atomic functions in libc. See
also PR 230888, 220822, 233725, 234976, and more probably duplicates.
Note that in practice, clang has been incorrectly generating cmpxchg8b
instructions for years now, when targeting i486. So de facto nothing
really changes by doing this.
Notes:
svn path=/projects/clang900-import/; revision=352030
diff --git tools/clang/lib/Driver/ToolChains/Arch/X86.cpp tools/clang/lib/Driver/ToolChains/Arch/X86.cpp
index 34be226b69e9..9a5c0aa28c7f 100644
--- tools/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ tools/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -93,10 +93,10 @@ const char *x86::getX86TargetCPU(const ArgList &Args,
return "x86-64";
switch (Triple.getOS()) {
- case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
case llvm::Triple::OpenBSD:
return "i486";
+ case llvm::Triple::FreeBSD:
case llvm::Triple::Haiku:
return "i586";
default:

View File

@ -0,0 +1,102 @@
commit 053368e30489fc77ab06ee7954df3719af2548c2
Author: dim <dim@FreeBSD.org>
Date: Thu Sep 19 19:42:59 2019 +0000
Pull in r371066 from upstream clang trunk (by Justin Hibbits):
Add -m(no)-spe to clang
Summary:
r337347 added support for the Signal Processing Engine (SPE) to LLVM.
This follows that up with the clang side.
This adds -mspe and -mno-spe, to match GCC.
Subscribers: nemanjai, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D49754
Notes:
svn path=/projects/clang900-import/; revision=352539
diff --git tools/clang/include/clang/Driver/Options.td tools/clang/include/clang/Driver/Options.td
index 4ea8bfff0973..508d046dbb91 100644
--- tools/clang/include/clang/Driver/Options.td
+++ tools/clang/include/clang/Driver/Options.td
@@ -2241,6 +2241,8 @@ def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[DriverOption]>;
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>;
def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>;
def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>;
+def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
+def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
def msecure_plt : Flag<["-"], "msecure-plt">, Group<m_ppc_Features_Group>;
diff --git tools/clang/lib/Basic/Targets/PPC.cpp tools/clang/lib/Basic/Targets/PPC.cpp
index 2a773d999286..a40991048873 100644
--- tools/clang/lib/Basic/Targets/PPC.cpp
+++ tools/clang/lib/Basic/Targets/PPC.cpp
@@ -54,6 +54,10 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasFloat128 = true;
} else if (Feature == "+power9-vector") {
HasP9Vector = true;
+ } else if (Feature == "+spe") {
+ HasSPE = true;
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble();
} else if (Feature == "-hard-float") {
FloatABI = SoftFloat;
}
@@ -165,6 +169,10 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__VEC__", "10206");
Builder.defineMacro("__ALTIVEC__");
}
+ if (HasSPE) {
+ Builder.defineMacro("__SPE__");
+ Builder.defineMacro("__NO_FPRS__");
+ }
if (HasVSX)
Builder.defineMacro("__VSX__");
if (HasP8Vector)
@@ -203,7 +211,6 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
// __CMODEL_LARGE__
// _CALL_SYSV
// _CALL_DARWIN
- // __NO_FPRS__
}
// Handle explicit options being passed to the compiler here: if we've
@@ -332,6 +339,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("extdiv", HasExtDiv)
.Case("float128", HasFloat128)
.Case("power9-vector", HasP9Vector)
+ .Case("spe", HasSPE)
.Default(false);
}
diff --git tools/clang/lib/Basic/Targets/PPC.h tools/clang/lib/Basic/Targets/PPC.h
index 6e5df097921b..6c6421c28e23 100644
--- tools/clang/lib/Basic/Targets/PPC.h
+++ tools/clang/lib/Basic/Targets/PPC.h
@@ -66,6 +66,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
bool HasBPERMD = false;
bool HasExtDiv = false;
bool HasP9Vector = false;
+ bool HasSPE = false;
protected:
std::string ABI;
diff --git tools/clang/lib/CodeGen/TargetInfo.cpp tools/clang/lib/CodeGen/TargetInfo.cpp
index 1e1038dbfe95..81f40011f11c 100644
--- tools/clang/lib/CodeGen/TargetInfo.cpp
+++ tools/clang/lib/CodeGen/TargetInfo.cpp
@@ -9716,7 +9716,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::ppc:
return SetCGInfo(
- new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft"));
+ new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft" ||
+ getTarget().hasFeature("spe")));
case llvm::Triple::ppc64:
if (Triple.isOSBinFormatELF()) {
PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;

View File

@ -0,0 +1,300 @@
commit 96f7d6cb2727d1d08e1e460f6606a2a11673b292
Author: dim <dim@FreeBSD.org>
Date: Sat Sep 21 21:01:38 2019 +0000
Pull in r371557 from upstream clang trunk (by Richard Smith):
When evaluating a __builtin_constant_p conditional, always enter
constant-folding mode regardless of the original evaluation mode.
In order for this to be correct, we need to track whether we're
checking for a potential constant expression or checking for
undefined behavior separately from the evaluation mode enum, since we
don't want to clobber those states when entering constant-folding
mode.
This should fix "ld: error: undefined symbol: ix86_isa_flags" (and many
other symbol names) during the initial stages of the lang/gcc* ports.
The issue was that without optimization, the __builtin_constant_p()
expressions generated in gencondmd.c would emit references to global
variables that were undefined, such as ix86_isa_flags.
PR: 240629
Notes:
svn path=/projects/clang900-import/; revision=352586
diff --git tools/clang/lib/AST/ExprConstant.cpp tools/clang/lib/AST/ExprConstant.cpp
index f01b42e7ff76..26163c6143e6 100644
--- tools/clang/lib/AST/ExprConstant.cpp
+++ tools/clang/lib/AST/ExprConstant.cpp
@@ -794,58 +794,47 @@ namespace {
/// constant value.
bool InConstantContext;
+ /// Whether we're checking that an expression is a potential constant
+ /// expression. If so, do not fail on constructs that could become constant
+ /// later on (such as a use of an undefined global).
+ bool CheckingPotentialConstantExpression = false;
+
+ /// Whether we're checking for an expression that has undefined behavior.
+ /// If so, we will produce warnings if we encounter an operation that is
+ /// always undefined.
+ bool CheckingForUndefinedBehavior = false;
+
enum EvaluationMode {
/// Evaluate as a constant expression. Stop if we find that the expression
/// is not a constant expression.
EM_ConstantExpression,
- /// Evaluate as a potential constant expression. Keep going if we hit a
- /// construct that we can't evaluate yet (because we don't yet know the
- /// value of something) but stop if we hit something that could never be
- /// a constant expression.
- EM_PotentialConstantExpression,
+ /// Evaluate as a constant expression. Stop if we find that the expression
+ /// is not a constant expression. Some expressions can be retried in the
+ /// optimizer if we don't constant fold them here, but in an unevaluated
+ /// context we try to fold them immediately since the optimizer never
+ /// gets a chance to look at it.
+ EM_ConstantExpressionUnevaluated,
/// Fold the expression to a constant. Stop if we hit a side-effect that
/// we can't model.
EM_ConstantFold,
- /// Evaluate the expression looking for integer overflow and similar
- /// issues. Don't worry about side-effects, and try to visit all
- /// subexpressions.
- EM_EvaluateForOverflow,
-
/// Evaluate in any way we know how. Don't worry about side-effects that
/// can't be modeled.
EM_IgnoreSideEffects,
-
- /// Evaluate as a constant expression. Stop if we find that the expression
- /// is not a constant expression. Some expressions can be retried in the
- /// optimizer if we don't constant fold them here, but in an unevaluated
- /// context we try to fold them immediately since the optimizer never
- /// gets a chance to look at it.
- EM_ConstantExpressionUnevaluated,
-
- /// Evaluate as a potential constant expression. Keep going if we hit a
- /// construct that we can't evaluate yet (because we don't yet know the
- /// value of something) but stop if we hit something that could never be
- /// a constant expression. Some expressions can be retried in the
- /// optimizer if we don't constant fold them here, but in an unevaluated
- /// context we try to fold them immediately since the optimizer never
- /// gets a chance to look at it.
- EM_PotentialConstantExpressionUnevaluated,
} EvalMode;
/// Are we checking whether the expression is a potential constant
/// expression?
bool checkingPotentialConstantExpression() const {
- return EvalMode == EM_PotentialConstantExpression ||
- EvalMode == EM_PotentialConstantExpressionUnevaluated;
+ return CheckingPotentialConstantExpression;
}
/// Are we checking an expression for overflow?
// FIXME: We should check for any kind of undefined or suspicious behavior
// in such constructs, not just overflow.
- bool checkingForOverflow() { return EvalMode == EM_EvaluateForOverflow; }
+ bool checkingForUndefinedBehavior() { return CheckingForUndefinedBehavior; }
EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
: Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
@@ -932,15 +921,12 @@ namespace {
switch (EvalMode) {
case EM_ConstantFold:
case EM_IgnoreSideEffects:
- case EM_EvaluateForOverflow:
if (!HasFoldFailureDiagnostic)
break;
// We've already failed to fold something. Keep that diagnostic.
LLVM_FALLTHROUGH;
case EM_ConstantExpression:
- case EM_PotentialConstantExpression:
case EM_ConstantExpressionUnevaluated:
- case EM_PotentialConstantExpressionUnevaluated:
HasActiveDiagnostic = false;
return OptionalDiagnostic();
}
@@ -986,8 +972,8 @@ namespace {
/// Diagnose that the evaluation does not produce a C++11 core constant
/// expression.
///
- /// FIXME: Stop evaluating if we're in EM_ConstantExpression or
- /// EM_PotentialConstantExpression mode and we produce one of these.
+ /// FIXME: Stop evaluating if we're in EM_ConstantExpression mode
+ /// and we produce one of these.
OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId
= diag::note_invalid_subexpr_in_const_expr,
unsigned ExtraNotes = 0) {
@@ -1023,16 +1009,16 @@ namespace {
/// couldn't model?
bool keepEvaluatingAfterSideEffect() {
switch (EvalMode) {
- case EM_PotentialConstantExpression:
- case EM_PotentialConstantExpressionUnevaluated:
- case EM_EvaluateForOverflow:
case EM_IgnoreSideEffects:
return true;
case EM_ConstantExpression:
case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
- return false;
+ // By default, assume any side effect might be valid in some other
+ // evaluation of this expression from a different context.
+ return checkingPotentialConstantExpression() ||
+ checkingForUndefinedBehavior();
}
llvm_unreachable("Missed EvalMode case");
}
@@ -1047,16 +1033,13 @@ namespace {
/// Should we continue evaluation after encountering undefined behavior?
bool keepEvaluatingAfterUndefinedBehavior() {
switch (EvalMode) {
- case EM_EvaluateForOverflow:
case EM_IgnoreSideEffects:
case EM_ConstantFold:
return true;
- case EM_PotentialConstantExpression:
- case EM_PotentialConstantExpressionUnevaluated:
case EM_ConstantExpression:
case EM_ConstantExpressionUnevaluated:
- return false;
+ return checkingForUndefinedBehavior();
}
llvm_unreachable("Missed EvalMode case");
}
@@ -1076,16 +1059,12 @@ namespace {
return false;
switch (EvalMode) {
- case EM_PotentialConstantExpression:
- case EM_PotentialConstantExpressionUnevaluated:
- case EM_EvaluateForOverflow:
- return true;
-
case EM_ConstantExpression:
case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
case EM_IgnoreSideEffects:
- return false;
+ return checkingPotentialConstantExpression() ||
+ checkingForUndefinedBehavior();
}
llvm_unreachable("Missed EvalMode case");
}
@@ -1142,9 +1121,7 @@ namespace {
Info.EvalStatus.Diag->empty() &&
!Info.EvalStatus.HasSideEffects),
OldMode(Info.EvalMode) {
- if (Enabled &&
- (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
- Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
+ if (Enabled)
Info.EvalMode = EvalInfo::EM_ConstantFold;
}
void keepDiagnostics() { Enabled = false; }
@@ -1163,8 +1140,7 @@ namespace {
EvalInfo::EvaluationMode OldMode;
explicit IgnoreSideEffectsRAII(EvalInfo &Info)
: Info(Info), OldMode(Info.EvalMode) {
- if (!Info.checkingPotentialConstantExpression())
- Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
+ Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
}
~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
@@ -2323,7 +2299,7 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)), false);
Result = Value.trunc(LHS.getBitWidth());
if (Result.extend(BitWidth) != Value) {
- if (Info.checkingForOverflow())
+ if (Info.checkingForUndefinedBehavior())
Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
diag::warn_integer_constant_overflow)
<< Result.toString(10) << E->getType();
@@ -6047,6 +6023,8 @@ class ExprEvaluatorBase
// Always assume __builtin_constant_p(...) ? ... : ... is a potential
// constant expression; we can't check whether it's potentially foldable.
+ // FIXME: We should instead treat __builtin_constant_p as non-constant if
+ // it would return 'false' in this mode.
if (Info.checkingPotentialConstantExpression() && IsBcpCall)
return false;
@@ -6329,7 +6307,7 @@ class ExprEvaluatorBase
bool VisitStmtExpr(const StmtExpr *E) {
// We will have checked the full-expressions inside the statement expression
// when they were completed, and don't need to check them again now.
- if (Info.checkingForOverflow())
+ if (Info.checkingForUndefinedBehavior())
return Error(E);
BlockScopeRAII Scope(Info);
@@ -9499,14 +9477,11 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
// size of the referenced object.
switch (Info.EvalMode) {
case EvalInfo::EM_ConstantExpression:
- case EvalInfo::EM_PotentialConstantExpression:
case EvalInfo::EM_ConstantFold:
- case EvalInfo::EM_EvaluateForOverflow:
case EvalInfo::EM_IgnoreSideEffects:
// Leave it to IR generation.
return Error(E);
case EvalInfo::EM_ConstantExpressionUnevaluated:
- case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
// Reduce it to a constant now.
return Success((Type & 2) ? 0 : -1, E);
}
@@ -12546,8 +12521,9 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
EvalResult EVResult;
EVResult.Diag = Diag;
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
Info.InConstantContext = true;
+ Info.CheckingForUndefinedBehavior = true;
bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
(void)Result;
@@ -12564,7 +12540,8 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
bool IsConst;
EvalResult EVResult;
if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ Info.CheckingForUndefinedBehavior = true;
(void)::EvaluateAsRValue(Info, this, EVResult.Val);
}
}
@@ -13178,9 +13155,9 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
Expr::EvalStatus Status;
Status.Diag = &Diags;
- EvalInfo Info(FD->getASTContext(), Status,
- EvalInfo::EM_PotentialConstantExpression);
+ EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_ConstantExpression);
Info.InConstantContext = true;
+ Info.CheckingPotentialConstantExpression = true;
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr;
@@ -13219,8 +13196,9 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
Status.Diag = &Diags;
EvalInfo Info(FD->getASTContext(), Status,
- EvalInfo::EM_PotentialConstantExpressionUnevaluated);
+ EvalInfo::EM_ConstantExpressionUnevaluated);
Info.InConstantContext = true;
+ Info.CheckingPotentialConstantExpression = true;
// Fabricate a call stack frame to give the arguments a plausible cover story.
ArrayRef<const Expr*> Args;

View File

@ -0,0 +1,54 @@
commit 2dfd6210dcc3782d0f298b7bb996cc313d53c3a6
Author: dim <dim@FreeBSD.org>
Date: Sun Sep 22 17:31:27 2019 +0000
Pull in r372513 from upstream lld trunk (by Simon Atanasyan):
[mips] Deduce MIPS specific ELF header flags from `emulation`
In case of linking binary blobs which do not have any ELF headers, we
can deduce MIPS ABI ELF header flags from an `emulation` option.
Patch by Kyle Evans.
Requested by: kevans :)
Notes:
svn path=/projects/clang900-import/; revision=352600
diff --git tools/lld/ELF/Arch/MipsArchTree.cpp tools/lld/ELF/Arch/MipsArchTree.cpp
index f64d03756457..20e07e1114eb 100644
--- tools/lld/ELF/Arch/MipsArchTree.cpp
+++ tools/lld/ELF/Arch/MipsArchTree.cpp
@@ -294,12 +294,30 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
return ret;
}
+// If we don't have any input files, we'll have to rely on the information we
+// can derive from emulation information, since this at least gets us ABI.
+static uint32_t getFlagsFromEmulation() {
+ uint32_t ret = 0;
+
+ if (config->emulation.empty())
+ return 0;
+
+ if (config->ekind == ELF32BEKind || config->ekind == ELF32LEKind) {
+ if (config->mipsN32Abi)
+ ret |= EF_MIPS_ABI2;
+ else
+ ret |= EF_MIPS_ABI_O32;
+ }
+
+ return ret;
+}
+
template <class ELFT> uint32_t elf::calcMipsEFlags() {
std::vector<FileFlags> v;
for (InputFile *f : objectFiles)
v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
if (v.empty())
- return 0;
+ return getFlagsFromEmulation();
checkFlags(v);
return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v);
}

View File

@ -0,0 +1,93 @@
commit 24b1a5b926832f68fa0a008b2484d4b44f58ee8e
Author: dim <dim@FreeBSD.org>
Date: Sat Sep 14 10:55:33 2019 +0000
Revert commit from upstream llvm trunk (by Hans Wennborg):
Re-commit r357452 (take 3): "SimplifyCFG
SinkCommonCodeFromPredecessors: Also sink function calls without used
results (PR41259)"
Third time's the charm.
This was reverted in r363220 due to being suspected of an internal
benchmark regression and a test failure, none of which turned out to
be caused by this.
As reported in https://bugs.llvm.org/show_bug.cgi?id=43269, this causes
UNREACHABLE errors when compiling if_malo_pci.c for arm and aarch64.
Notes:
svn path=/projects/clang900-import/; revision=352318
diff --git lib/Transforms/Utils/SimplifyCFG.cpp lib/Transforms/Utils/SimplifyCFG.cpp
index 11651d040dc0..6e2ef67408d9 100644
--- lib/Transforms/Utils/SimplifyCFG.cpp
+++ lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1428,10 +1428,9 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
static bool canSinkInstructions(
ArrayRef<Instruction *> Insts,
DenseMap<Instruction *, SmallVector<Value *, 4>> &PHIOperands) {
- // Prune out obviously bad instructions to move. Each instruction must have
- // exactly zero or one use, and we check later that use is by a single, common
- // PHI instruction in the successor.
- bool HasUse = !Insts.front()->user_empty();
+ // Prune out obviously bad instructions to move. Any non-store instruction
+ // must have exactly one use, and we check later that use is by a single,
+ // common PHI instruction in the successor.
for (auto *I : Insts) {
// These instructions may change or break semantics if moved.
if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
@@ -1445,10 +1444,9 @@ static bool canSinkInstructions(
if (C->isInlineAsm())
return false;
- // Each instruction must have zero or one use.
- if (HasUse && !I->hasOneUse())
- return false;
- if (!HasUse && !I->user_empty())
+ // Everything must have only one use too, apart from stores which
+ // have no uses.
+ if (!isa<StoreInst>(I) && !I->hasOneUse())
return false;
}
@@ -1457,11 +1455,11 @@ static bool canSinkInstructions(
if (!I->isSameOperationAs(I0))
return false;
- // All instructions in Insts are known to be the same opcode. If they have a
- // use, check that the only user is a PHI or in the same block as the
- // instruction, because if a user is in the same block as an instruction we're
- // contemplating sinking, it must already be determined to be sinkable.
- if (HasUse) {
+ // All instructions in Insts are known to be the same opcode. If they aren't
+ // stores, check the only user of each is a PHI or in the same block as the
+ // instruction, because if a user is in the same block as an instruction
+ // we're contemplating sinking, it must already be determined to be sinkable.
+ if (!isa<StoreInst>(I0)) {
auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
auto *Succ = I0->getParent()->getTerminator()->getSuccessor(0);
if (!all_of(Insts, [&PNUse,&Succ](const Instruction *I) -> bool {
@@ -1539,7 +1537,7 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
// it is slightly over-aggressive - it gets confused by commutative instructions
// so double-check it here.
Instruction *I0 = Insts.front();
- if (!I0->user_empty()) {
+ if (!isa<StoreInst>(I0)) {
auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
if (!all_of(Insts, [&PNUse](const Instruction *I) -> bool {
auto *U = cast<Instruction>(*I->user_begin());
@@ -1597,10 +1595,11 @@ static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
I0->andIRFlags(I);
}
- if (!I0->user_empty()) {
+ if (!isa<StoreInst>(I0)) {
// canSinkLastInstruction checked that all instructions were used by
// one and only one PHI node. Find that now, RAUW it to our common
// instruction and nuke it.
+ assert(I0->hasOneUse());
auto *PN = cast<PHINode>(*I0->user_begin());
PN->replaceAllUsesWith(I0);
PN->eraseFromParent();

View File

@ -0,0 +1,58 @@
commit 3538987a800db5e174b3301b9bf70b955a349762
Author: dim <dim@FreeBSD.org>
Date: Mon Sep 23 17:05:46 2019 +0000
Pull in r372606 from upstream llvm trunk (by Sanjay Patel):
[x86] fix assert with horizontal math + broadcast of vector (PR43402)
https://bugs.llvm.org/show_bug.cgi?id=43402
This should fix 'Assertion failed: ((HOp.getValueType() == MVT::v2f64 ||
HOp.getValueType() == MVT::v4f64) && HOp.getValueType() == VT &&
"Unexpected type for h-op"), function foldShuffleOfHorizOp, file
contrib/llvm/lib/Target/X86/X86ISelLowering.cpp, line 33661' when
building the devel/llvm90 port with CPUTYPE=haswell.
PR: 240759
Notes:
svn path=/projects/clang900-import/; revision=352629
diff --git lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.cpp
index 0c5b8a79dd62..1869cc9da017 100644
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -33651,14 +33651,14 @@ static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) {
// When the operands of a horizontal math op are identical, the low half of
// the result is the same as the high half. If a target shuffle is also
- // replicating low and high halves, we don't need the shuffle.
+ // replicating low and high halves (and without changing the type/length of
+ // the vector), we don't need the shuffle.
if (Opcode == X86ISD::MOVDDUP || Opcode == X86ISD::VBROADCAST) {
- if (HOp.getScalarValueSizeInBits() == 64) {
+ if (HOp.getScalarValueSizeInBits() == 64 && HOp.getValueType() == VT) {
// movddup (hadd X, X) --> hadd X, X
// broadcast (extract_vec_elt (hadd X, X), 0) --> hadd X, X
assert((HOp.getValueType() == MVT::v2f64 ||
- HOp.getValueType() == MVT::v4f64) && HOp.getValueType() == VT &&
- "Unexpected type for h-op");
+ HOp.getValueType() == MVT::v4f64) && "Unexpected type for h-op");
return updateHOp(HOp, DAG);
}
return SDValue();
diff --git lib/Target/X86/X86ISelLowering.h lib/Target/X86/X86ISelLowering.h
index db36bcb929e3..d873edb857a8 100644
--- lib/Target/X86/X86ISelLowering.h
+++ lib/Target/X86/X86ISelLowering.h
@@ -422,7 +422,8 @@ namespace llvm {
// Tests Types Of a FP Values for scalar types.
VFPCLASSS,
- // Broadcast scalar to vector.
+ // Broadcast (splat) scalar or element 0 of a vector. If the operand is
+ // a vector, this node may change the vector length as part of the splat.
VBROADCAST,
// Broadcast mask to vector.
VBROADCASTM,