diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 89fa5a0f3630..163891a9d012 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -736,6 +736,7 @@ bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const { bool AArch64InstrInfo::isExynosShiftLeftFast(const MachineInstr &MI) const { unsigned Imm, Shift; + AArch64_AM::ShiftExtendType Ext; switch (MI.getOpcode()) { default: @@ -779,8 +780,8 @@ bool AArch64InstrInfo::isExynosShiftLeftFast(const MachineInstr &MI) const { case AArch64::SUBXrs: Imm = MI.getOperand(3).getImm(); Shift = AArch64_AM::getShiftValue(Imm); - return (Shift == 0 || - (Shift <= 3 && AArch64_AM::getShiftType(Imm) == AArch64_AM::LSL)); + Ext = AArch64_AM::getShiftType(Imm); + return (Shift == 0 || (Shift <= 3 && Ext == AArch64_AM::LSL)); // WriteIEReg case AArch64::ADDSWrx: @@ -797,9 +798,62 @@ bool AArch64InstrInfo::isExynosShiftLeftFast(const MachineInstr &MI) const { case AArch64::SUBXrx64: Imm = MI.getOperand(3).getImm(); Shift = AArch64_AM::getArithShiftValue(Imm); - return (Shift == 0 || - (Shift <= 3 && - AArch64_AM::getArithExtendType(Imm) == AArch64_AM::UXTX)); + Ext = AArch64_AM::getArithExtendType(Imm); + return (Shift == 0 || (Shift <= 3 && Ext == AArch64_AM::UXTX)); + + case AArch64::PRFMroW: + case AArch64::PRFMroX: + + // WriteLDIdx + case AArch64::LDRBBroW: + case AArch64::LDRBBroX: + case AArch64::LDRHHroW: + case AArch64::LDRHHroX: + case AArch64::LDRSBWroW: + case AArch64::LDRSBWroX: + case AArch64::LDRSBXroW: + case AArch64::LDRSBXroX: + case AArch64::LDRSHWroW: + case AArch64::LDRSHWroX: + case AArch64::LDRSHXroW: + case AArch64::LDRSHXroX: + case AArch64::LDRSWroW: + case AArch64::LDRSWroX: + case AArch64::LDRWroW: + case AArch64::LDRWroX: + case AArch64::LDRXroW: + case AArch64::LDRXroX: + + case AArch64::LDRBroW: + case AArch64::LDRBroX: + case AArch64::LDRDroW: + case AArch64::LDRDroX: + case AArch64::LDRHroW: + case AArch64::LDRHroX: + case AArch64::LDRSroW: + case AArch64::LDRSroX: + + // WriteSTIdx + case AArch64::STRBBroW: + case AArch64::STRBBroX: + case AArch64::STRHHroW: + case AArch64::STRHHroX: + case AArch64::STRWroW: + case AArch64::STRWroX: + case AArch64::STRXroW: + case AArch64::STRXroX: + + case AArch64::STRBroW: + case AArch64::STRBroX: + case AArch64::STRDroW: + case AArch64::STRDroX: + case AArch64::STRHroW: + case AArch64::STRHroX: + case AArch64::STRSroW: + case AArch64::STRSroX: + Imm = MI.getOperand(3).getImm(); + Ext = AArch64_AM::getMemExtendType(Imm); + return (Ext == AArch64_AM::SXTX || Ext == AArch64_AM::UXTX); } } diff --git a/llvm/lib/Target/AArch64/AArch64SchedM1.td b/llvm/lib/Target/AArch64/AArch64SchedM1.td index 5327f8f5c53e..041894dcc27b 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedM1.td +++ b/llvm/lib/Target/AArch64/AArch64SchedM1.td @@ -88,16 +88,19 @@ def M1WriteBX : SchedWriteVariant<[SchedVar]>; def M1WriteL5 : SchedWriteRes<[M1UnitL]> { let Latency = 5; } -def M1WriteLX : SchedWriteVariant<[SchedVar, - SchedVar]>; +def M1WriteLX : SchedWriteVariant<[SchedVar, + SchedVar]>; def M1WriteS1 : SchedWriteRes<[M1UnitS]> { let Latency = 1; } def M1WriteS2 : SchedWriteRes<[M1UnitS]> { let Latency = 2; } def M1WriteS4 : SchedWriteRes<[M1UnitS]> { let Latency = 4; } -def M1WriteSX : SchedWriteVariant<[SchedVar, - SchedVar]>; +def M1WriteSX : SchedWriteVariant<[SchedVar, + SchedVar]>; +def M1WriteSY : SchedWriteVariant<[SchedVar, + SchedVar]>; def M1ReadAdrBase : SchedReadVariant<[SchedVar, SchedVar]>; @@ -369,6 +372,8 @@ def : InstRW<[WriteLD, WriteLDHi, WriteAdr, M1WriteA1], (instregex "^LDP(SW|W|X)(post|pre)")>; +def : InstRW<[M1WriteLX, + ReadAdrBase], (instregex "^PRFMro[WX]")>; // Store instructions. @@ -401,20 +406,30 @@ def : InstRW<[M1WriteNEONI], (instregex "^FMOV[DS][WX](High)?r")>; // FP load instructions. def : InstRW<[WriteVLD, WriteAdr, - M1WriteA1], (instregex "^LDP[DS](post|pre)")>; + M1WriteA1], (instregex "^LDP[DS](post|pre)")>; def : InstRW<[WriteVLD, WriteVLD, WriteAdr, - M1WriteA1], (instregex "^LDPQ(post|pre)")>; + M1WriteA1], (instregex "^LDPQ(post|pre)")>; +def : InstRW<[M1WriteLX, + ReadAdrBase], (instregex "^LDR[BDHS]ro[WX]")>; +def : InstRW<[M1WriteA1, + M1WriteL5, + ReadAdrBase], (instregex "^LDRQro[WX]")>; // FP store instructions. def : InstRW<[WriteVST, WriteAdr, - M1WriteA1], (instregex "^STP[DS](post|pre)")>; + M1WriteA1], (instregex "^STP[DS](post|pre)")>; def : InstRW<[WriteVST, WriteVST, WriteAdr, - M1WriteA1], (instregex "^STPQ(post|pre)")>; + M1WriteA1], (instregex "^STPQ(post|pre)")>; +def : InstRW<[M1WriteSY, + ReadAdrBase], (instregex "^STR[BDHS]ro[WX]")>; +def : InstRW<[M1WriteA1, + M1WriteS2, + ReadAdrBase], (instregex "^STRQro[WX]")>; // ASIMD instructions. def : InstRW<[M1WriteNMISC3], (instregex "^[SU]ABAL?v")>;