mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-08 18:31:23 +00:00
ARM FastISel fix sext/zext fold
Sign- and zero-extension folding was slightly incorrect because it wasn't checking that the shift on extensions was zero. Further, I recently added AND rd, rn, #255 as a form of 8-bit zero extension, and failed to add the folding code for it. This patch fixes both issues. This patch fixes both, and the test should remain the same: test/CodeGen/ARM/fast-isel-fold.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183794 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a85644459c
commit
5ab770417b
@ -20,6 +20,7 @@
|
||||
#include "ARMSubtarget.h"
|
||||
#include "ARMTargetMachine.h"
|
||||
#include "MCTargetDesc/ARMAddressingModes.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/FastISel.h"
|
||||
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
||||
@ -2863,6 +2864,25 @@ bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// This table describes sign- and zero-extend instructions which can be
|
||||
// folded into a preceding load. All of these extends have an immediate
|
||||
// (sometimes a mask and sometimes a shift) that's applied after
|
||||
// extension.
|
||||
const struct FoldableLoadExtendsStruct {
|
||||
uint16_t Opc[2]; // ARM, Thumb.
|
||||
uint8_t ExpectedImm;
|
||||
uint8_t isZExt : 1;
|
||||
uint8_t ExpectedVT : 7;
|
||||
} FoldableLoadExtends[] = {
|
||||
{ { ARM::SXTH, ARM::t2SXTH }, 0, 0, MVT::i16 },
|
||||
{ { ARM::UXTH, ARM::t2UXTH }, 0, 1, MVT::i16 },
|
||||
{ { ARM::ANDri, ARM::t2ANDri }, 255, 1, MVT::i8 },
|
||||
{ { ARM::SXTB, ARM::t2SXTB }, 0, 0, MVT::i8 },
|
||||
{ { ARM::UXTB, ARM::t2UXTB }, 0, 1, MVT::i8 }
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief The specified machine instr operand is a vreg, and that
|
||||
/// vreg is being provided by the specified load instruction. If possible,
|
||||
/// try to fold the load as an operand to the instruction, returning true if
|
||||
@ -2878,26 +2898,23 @@ bool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
|
||||
// ldrb r1, [r0] ldrb r1, [r0]
|
||||
// uxtb r2, r1 =>
|
||||
// mov r3, r2 mov r3, r1
|
||||
bool isZExt = true;
|
||||
switch(MI->getOpcode()) {
|
||||
default: return false;
|
||||
case ARM::SXTH:
|
||||
case ARM::t2SXTH:
|
||||
isZExt = false;
|
||||
case ARM::UXTH:
|
||||
case ARM::t2UXTH:
|
||||
if (VT != MVT::i16)
|
||||
return false;
|
||||
break;
|
||||
case ARM::SXTB:
|
||||
case ARM::t2SXTB:
|
||||
isZExt = false;
|
||||
case ARM::UXTB:
|
||||
case ARM::t2UXTB:
|
||||
if (VT != MVT::i8)
|
||||
return false;
|
||||
break;
|
||||
if (MI->getNumOperands() < 3 || !MI->getOperand(2).isImm())
|
||||
return false;
|
||||
const uint64_t Imm = MI->getOperand(2).getImm();
|
||||
|
||||
bool Found = false;
|
||||
bool isZExt;
|
||||
for (unsigned i = 0, e = array_lengthof(FoldableLoadExtends);
|
||||
i != e; ++i) {
|
||||
if (FoldableLoadExtends[i].Opc[isThumb2] == MI->getOpcode() &&
|
||||
(uint64_t)FoldableLoadExtends[i].ExpectedImm == Imm &&
|
||||
MVT((MVT::SimpleValueType)FoldableLoadExtends[i].ExpectedVT) == VT) {
|
||||
Found = true;
|
||||
isZExt = FoldableLoadExtends[i].isZExt;
|
||||
}
|
||||
}
|
||||
if (!Found) return false;
|
||||
|
||||
// See if we can handle this address.
|
||||
Address Addr;
|
||||
if (!ARMComputeAddress(LI->getOperand(0), Addr)) return false;
|
||||
|
Loading…
Reference in New Issue
Block a user