mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-10 06:24:58 +00:00
[AArch64] Fix handling of zero immediate in fmov instructions
Currently fmov #0 with a vector destination is handle incorrectly and results in fmov #-1.9375 being emitted but should instead give an error. This is due to the way we cope with fmov #0 with a scalar destination being an alias of fmov zr, so fix this by actually doing it through an alias. Differential Revision: https://reviews.llvm.org/D31949 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300830 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f805a0cc2d
commit
82afafa944
@ -2586,6 +2586,11 @@ def FMOVS0 : Pseudo<(outs FPR32:$Rd), (ins), [(set f32:$Rd, (fpimm0))]>,
|
||||
def FMOVD0 : Pseudo<(outs FPR64:$Rd), (ins), [(set f64:$Rd, (fpimm0))]>,
|
||||
Sched<[WriteF]>;
|
||||
}
|
||||
// Similarly add aliases
|
||||
def : InstAlias<"fmov $Rd, #0.0", (FMOVWHr FPR16:$Rd, WZR), 0>,
|
||||
Requires<[HasFullFP16]>;
|
||||
def : InstAlias<"fmov $Rd, #0.0", (FMOVWSr FPR32:$Rd, WZR), 0>;
|
||||
def : InstAlias<"fmov $Rd, #0.0", (FMOVXDr FPR64:$Rd, XZR), 0>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Floating point conversion instruction.
|
||||
|
@ -2116,10 +2116,15 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
|
||||
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
|
||||
Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
|
||||
|
||||
// Check for out of range values. As an exception, we let Zero through,
|
||||
// as we handle that special case in post-processing before matching in
|
||||
// order to use the zero register for it.
|
||||
if (Val == -1 && !RealVal.isPosZero()) {
|
||||
// Check for out of range values. As an exception we let Zero through,
|
||||
// but as tokens instead of an FPImm so that it can be matched by the
|
||||
// appropriate alias if one exists.
|
||||
if (RealVal.isPosZero()) {
|
||||
Parser.Lex(); // Eat the token.
|
||||
Operands.push_back(AArch64Operand::CreateToken("#0", false, S, getContext()));
|
||||
Operands.push_back(AArch64Operand::CreateToken(".0", false, S, getContext()));
|
||||
return MatchOperand_Success;
|
||||
} else if (Val == -1) {
|
||||
TokError("expected compatible register or floating-point constant");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
@ -3646,21 +3651,6 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
}
|
||||
}
|
||||
|
||||
// Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
|
||||
if (NumOperands == 3 && Tok == "fmov") {
|
||||
AArch64Operand &RegOp = static_cast<AArch64Operand &>(*Operands[1]);
|
||||
AArch64Operand &ImmOp = static_cast<AArch64Operand &>(*Operands[2]);
|
||||
if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (unsigned)-1) {
|
||||
unsigned zreg =
|
||||
!AArch64MCRegisterClasses[AArch64::FPR64RegClassID].contains(
|
||||
RegOp.getReg())
|
||||
? AArch64::WZR
|
||||
: AArch64::XZR;
|
||||
Operands[2] = AArch64Operand::CreateReg(zreg, false, Op.getStartLoc(),
|
||||
Op.getEndLoc(), getContext());
|
||||
}
|
||||
}
|
||||
|
||||
MCInst Inst;
|
||||
// First try to match against the secondary set of tables containing the
|
||||
// short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
|
||||
|
@ -1812,11 +1812,11 @@
|
||||
// CHECK-ERROR-NEXT: fmov s15, #0x100
|
||||
// CHECK-ERROR-NEXT: ^
|
||||
|
||||
;; No particular reason, but a striking omission
|
||||
fmov d0, #0.0
|
||||
// CHECK-ERROR-AARCH64: error: expected compatible register or floating-point constant
|
||||
// CHECK-ERROR-AARCH64-NEXT: fmov d0, #0.0
|
||||
// CHECK-ERROR-AARCH64-NEXT: ^
|
||||
;; Not possible to fmov ZR to a whole vector
|
||||
fmov v0.4s, #0.0
|
||||
// CHECK-ERROR: error: invalid operand for instruction
|
||||
// CHECK-ERROR-NEXT: fmov v0.4s, #0.0
|
||||
// CHECK-ERROR-NEXT: ^
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Floating-point <-> integer conversion
|
||||
|
Loading…
x
Reference in New Issue
Block a user