Pull in r372186 from upstream llvm trunk (by Eli Friedman):
[ARM] VFPv2 only supports 16 D registers. r361845 changed the way we handle "D16" vs. "D32" targets; there used to be a negative "d16" which removed instructions from the instruction set, and now there's a "d32" feature which adds instructions to the instruction set. This is good, but there was an oversight in the implementation: the behavior of VFPv2 was changed. In particular, the "vfp2" feature was changed to imply "d32". This is wrong: VFPv2 only supports 16 D registers. In practice, this means if you specify -mfpu=vfpv2, the compiler will generate illegal instructions. This patch gets rid of "vfp2d16" and "vfp2d16sp", and fixes "vfp2" and "vfp2sp" so they don't imply "d32". Differential Revision: https://reviews.llvm.org/D67375 Pull in r372187 from upstream clang trunk (by Eli Friedman): [ARM] Update clang for removal of vfp2d16 and vfp2d16sp Matching fix for https://reviews.llvm.org/D67375 (r372186). Differential Revision: https://reviews.llvm.org/D67467 This should fix clang generating invalid opcodes for floating point operations on armv6. Requested by: mmel MFC after: 3 days
This commit is contained in:
parent
ecae3df1db
commit
1927000d52
@ -194,7 +194,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
|
||||
default:
|
||||
break;
|
||||
case ARMBuildAttrs::Not_Allowed:
|
||||
Features.AddFeature("vfp2d16sp", false);
|
||||
Features.AddFeature("vfp2sp", false);
|
||||
Features.AddFeature("vfp3d16sp", false);
|
||||
Features.AddFeature("vfp4d16sp", false);
|
||||
break;
|
||||
|
@ -176,10 +176,8 @@ bool ARM::getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features) {
|
||||
// exist).
|
||||
|
||||
{"+fpregs", "-fpregs", FPUVersion::VFPV2, FPURestriction::SP_D16},
|
||||
{"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::None},
|
||||
{"+vfp2d16", "-vfp2d16", FPUVersion::VFPV2, FPURestriction::D16},
|
||||
{"+vfp2d16sp", "-vfp2d16sp", FPUVersion::VFPV2, FPURestriction::SP_D16},
|
||||
{"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::None},
|
||||
{"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16},
|
||||
{"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16},
|
||||
{"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None},
|
||||
{"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16},
|
||||
{"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16},
|
||||
@ -195,7 +193,7 @@ bool ARM::getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features) {
|
||||
{"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None},
|
||||
{"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16},
|
||||
{"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16},
|
||||
{"+d32", "-d32", FPUVersion::VFPV2, FPURestriction::None},
|
||||
{"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None},
|
||||
};
|
||||
|
||||
for (const auto &Info: FPUFeatureInfoList) {
|
||||
|
@ -57,12 +57,15 @@ def FeatureD32 : SubtargetFeature<"d32", "HasD32", "true",
|
||||
"Extend FP to 32 double registers">;
|
||||
|
||||
multiclass VFPver<string name, string query, string description,
|
||||
list<SubtargetFeature> prev = [],
|
||||
list<SubtargetFeature> otherimplies = []> {
|
||||
list<SubtargetFeature> prev,
|
||||
list<SubtargetFeature> otherimplies,
|
||||
list<SubtargetFeature> vfp2prev = []> {
|
||||
def _D16_SP: SubtargetFeature<
|
||||
name#"d16sp", query#"D16SP", "true",
|
||||
description#" with only 16 d-registers and no double precision",
|
||||
!foreach(v, prev, !cast<SubtargetFeature>(v # "_D16_SP")) # otherimplies>;
|
||||
!foreach(v, prev, !cast<SubtargetFeature>(v # "_D16_SP")) #
|
||||
!foreach(v, vfp2prev, !cast<SubtargetFeature>(v # "_SP")) #
|
||||
otherimplies>;
|
||||
def _SP: SubtargetFeature<
|
||||
name#"sp", query#"SP", "true",
|
||||
description#" with no double precision",
|
||||
@ -72,6 +75,7 @@ multiclass VFPver<string name, string query, string description,
|
||||
name#"d16", query#"D16", "true",
|
||||
description#" with only 16 d-registers",
|
||||
!foreach(v, prev, !cast<SubtargetFeature>(v # "_D16")) #
|
||||
vfp2prev #
|
||||
otherimplies # [FeatureFP64, !cast<SubtargetFeature>(NAME # "_D16_SP")]>;
|
||||
def "": SubtargetFeature<
|
||||
name, query, "true", description,
|
||||
@ -80,11 +84,17 @@ multiclass VFPver<string name, string query, string description,
|
||||
!cast<SubtargetFeature>(NAME # "_SP")]>;
|
||||
}
|
||||
|
||||
defm FeatureVFP2: VFPver<"vfp2", "HasVFPv2", "Enable VFP2 instructions",
|
||||
[], [FeatureFPRegs]>;
|
||||
def FeatureVFP2_SP : SubtargetFeature<"vfp2sp", "HasVFPv2SP", "true",
|
||||
"Enable VFP2 instructions with "
|
||||
"no double precision",
|
||||
[FeatureFPRegs]>;
|
||||
|
||||
def FeatureVFP2 : SubtargetFeature<"vfp2", "HasVFPv2", "true",
|
||||
"Enable VFP2 instructions",
|
||||
[FeatureFP64, FeatureVFP2_SP]>;
|
||||
|
||||
defm FeatureVFP3: VFPver<"vfp3", "HasVFPv3", "Enable VFP3 instructions",
|
||||
[FeatureVFP2]>;
|
||||
[], [], [FeatureVFP2]>;
|
||||
|
||||
def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
|
||||
"Enable NEON instructions",
|
||||
@ -98,7 +108,7 @@ defm FeatureVFP4: VFPver<"vfp4", "HasVFPv4", "Enable VFP4 instructions",
|
||||
[FeatureVFP3], [FeatureFP16]>;
|
||||
|
||||
defm FeatureFPARMv8: VFPver<"fp-armv8", "HasFPARMv8", "Enable ARMv8 FP",
|
||||
[FeatureVFP4]>;
|
||||
[FeatureVFP4], []>;
|
||||
|
||||
def FeatureFullFP16 : SubtargetFeature<"fullfp16", "HasFullFP16", "true",
|
||||
"Enable full half-precision "
|
||||
|
@ -71,7 +71,7 @@ def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
|
||||
AssemblerPredicate<"HasV8_5aOps", "armv8.5a">;
|
||||
def NoVFP : Predicate<"!Subtarget->hasVFP2Base()">;
|
||||
def HasVFP2 : Predicate<"Subtarget->hasVFP2Base()">,
|
||||
AssemblerPredicate<"FeatureVFP2_D16_SP", "VFP2">;
|
||||
AssemblerPredicate<"FeatureVFP2_SP", "VFP2">;
|
||||
def HasVFP3 : Predicate<"Subtarget->hasVFP3Base()">,
|
||||
AssemblerPredicate<"FeatureVFP3_D16_SP", "VFP3">;
|
||||
def HasVFP4 : Predicate<"Subtarget->hasVFP4Base()">,
|
||||
|
@ -179,11 +179,9 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
|
||||
bool HasVFPv3SP = false;
|
||||
bool HasVFPv4SP = false;
|
||||
bool HasFPARMv8SP = false;
|
||||
bool HasVFPv2D16 = false;
|
||||
bool HasVFPv3D16 = false;
|
||||
bool HasVFPv4D16 = false;
|
||||
bool HasFPARMv8D16 = false;
|
||||
bool HasVFPv2D16SP = false;
|
||||
bool HasVFPv3D16SP = false;
|
||||
bool HasVFPv4D16SP = false;
|
||||
bool HasFPARMv8D16SP = false;
|
||||
@ -600,7 +598,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
|
||||
|
||||
bool hasARMOps() const { return !NoARM; }
|
||||
|
||||
bool hasVFP2Base() const { return HasVFPv2D16SP; }
|
||||
bool hasVFP2Base() const { return HasVFPv2SP; }
|
||||
bool hasVFP3Base() const { return HasVFPv3D16SP; }
|
||||
bool hasVFP4Base() const { return HasVFPv4D16SP; }
|
||||
bool hasFPARMv8Base() const { return HasFPARMv8D16SP; }
|
||||
|
@ -11694,14 +11694,14 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
|
||||
{ ARM::AEK_CRYPTO, {Feature_HasV8Bit},
|
||||
{ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_FP, {Feature_HasV8Bit},
|
||||
{ARM::FeatureVFP2_D16_SP, ARM::FeatureFPARMv8} },
|
||||
{ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8} },
|
||||
{ (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM),
|
||||
{Feature_HasV7Bit, Feature_IsNotMClassBit},
|
||||
{ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
|
||||
{ ARM::AEK_MP, {Feature_HasV7Bit, Feature_IsNotMClassBit},
|
||||
{ARM::FeatureMP} },
|
||||
{ ARM::AEK_SIMD, {Feature_HasV8Bit},
|
||||
{ARM::FeatureNEON, ARM::FeatureVFP2_D16_SP, ARM::FeatureFPARMv8} },
|
||||
{ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone} },
|
||||
// FIXME: Only available in A-class, isel not predicated
|
||||
{ ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization} },
|
||||
|
@ -249,12 +249,12 @@ void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
|
||||
: ARM::FK_VFPV3_D16)
|
||||
: (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
|
||||
: ARM::FK_VFPV3XD)));
|
||||
else if (STI.hasFeature(ARM::FeatureVFP2_D16_SP))
|
||||
else if (STI.hasFeature(ARM::FeatureVFP2_SP))
|
||||
emitFPU(ARM::FK_VFPV2);
|
||||
}
|
||||
|
||||
// ABI_HardFP_use attribute to indicate single precision FP.
|
||||
if (STI.hasFeature(ARM::FeatureVFP2_D16_SP) && !STI.hasFeature(ARM::FeatureFP64))
|
||||
if (STI.hasFeature(ARM::FeatureVFP2_SP) && !STI.hasFeature(ARM::FeatureFP64))
|
||||
emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
|
||||
ARMBuildAttrs::HardFPSinglePrecision);
|
||||
|
||||
|
@ -427,11 +427,10 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
for (const auto &Feature : Features) {
|
||||
if (Feature == "+soft-float") {
|
||||
SoftFloat = true;
|
||||
} else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
|
||||
Feature == "+vfp2" || Feature == "+vfp2d16") {
|
||||
} else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
|
||||
FPU |= VFP2FPU;
|
||||
HW_FP |= HW_FP_SP;
|
||||
if (Feature == "+vfp2" || Feature == "+vfp2d16")
|
||||
if (Feature == "+vfp2")
|
||||
HW_FP |= HW_FP_DP;
|
||||
} else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
|
||||
Feature == "+vfp3" || Feature == "+vfp3d16") {
|
||||
|
@ -460,7 +460,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
|
||||
// now just be explicit and disable all known dependent features
|
||||
// as well.
|
||||
for (std::string Feature : {
|
||||
"vfp2", "vfp2sp", "vfp2d16", "vfp2d16sp",
|
||||
"vfp2", "vfp2sp",
|
||||
"vfp3", "vfp3sp", "vfp3d16", "vfp3d16sp",
|
||||
"vfp4", "vfp4sp", "vfp4d16", "vfp4d16sp",
|
||||
"fp-armv8", "fp-armv8sp", "fp-armv8d16", "fp-armv8d16sp",
|
||||
|
Loading…
Reference in New Issue
Block a user