Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.h =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -179,9 +179,6 @@ // CPSR defined in instruction static bool isCPSRDefined(const MachineInstr &MI); - // Load, scaled register offset, not plus LSL2 - bool isLdstScaledRegNotPlusLsl2(const MachineInstr &MI, unsigned Op) const; - /// GetInstSize - Returns the size of the specified MachineInstr. /// unsigned getInstSizeInBytes(const MachineInstr &MI) const override; Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -620,20 +620,6 @@ return false; } -// Load, scaled register offset, not plus LSL2 -bool ARMBaseInstrInfo::isLdstScaledRegNotPlusLsl2(const MachineInstr &MI, - unsigned Op) const { - const MachineOperand &Opc = MI.getOperand(Op + 2); - unsigned OffImm = Opc.getImm(); - - bool isAdd = ARM_AM::getAM2Op(OffImm) == ARM_AM::add; - unsigned Amt = ARM_AM::getAM2Offset(OffImm); - ARM_AM::ShiftOpc ShiftOpc = ARM_AM::getAM2ShiftOpc(OffImm); - if (ShiftOpc == ARM_AM::no_shift) return false; // not scaled - bool SimpleScaled = (isAdd && ShiftOpc == ARM_AM::lsl && Amt == 2); - return !SimpleScaled; -} - static bool isEligibleForITBlock(const MachineInstr *MI) { switch (MI->getOpcode()) { default: return true; Index: llvm/lib/Target/ARM/ARMSchedule.td =================================================================== --- llvm/lib/Target/ARM/ARMSchedule.td +++ llvm/lib/Target/ARM/ARMSchedule.td @@ -166,12 +166,18 @@ let FunctionMapper = "ARM_AM::getAM2ShiftOpc" in { class CheckAM2NoShift : CheckImmOperand_s; + class CheckAM2ShiftLSL : CheckImmOperand_s; } let FunctionMapper = "ARM_AM::getAM2Op" in { + class CheckAM2OpAdd : CheckImmOperand_s {} class CheckAM2OpSub : CheckImmOperand_s {} } +let FunctionMapper = "ARM_AM::getAM2Offset" in { + class CheckAM2Offset : CheckImmOperand {} +} + def IsLDMBaseRegInList : CheckFunctionPredicate< "ARM_MC::isLDMBaseRegInList", "ARM_MC::isLDMBaseRegInList" >; Index: llvm/lib/Target/ARM/ARMScheduleA57.td =================================================================== --- llvm/lib/Target/ARM/ARMScheduleA57.td +++ llvm/lib/Target/ARM/ARMScheduleA57.td @@ -42,12 +42,20 @@ def IsLdrAm3NegRegOffPredX3 : Am3NegativeRegOffset<4>; // Load, scaled register offset, not plus LSL2 -def IsLdstsoScaledNotOptimalPredX0 : - SchedPredicate<[{TII->isLdstScaledRegNotPlusLsl2(*MI, 0)}]>; -def IsLdstsoScaledNotOptimalPred : - SchedPredicate<[{TII->isLdstScaledRegNotPlusLsl2(*MI, 1)}]>; -def IsLdstsoScaledNotOptimalPredX2 : - SchedPredicate<[{TII->isLdstScaledRegNotPlusLsl2(*MI, 2)}]>; +class ScaledRegNotPlusLsl2 : CheckNot< + CheckAny<[ + CheckAM2NoShift, + CheckAll<[ + CheckAM2OpAdd, + CheckAM2ShiftLSL, + CheckAM2Offset + ]> + ]> + >; + +def IsLdstsoScaledNotOptimalPredX0 : MCSchedPredicate>; +def IsLdstsoScaledNotOptimalPred : MCSchedPredicate>; +def IsLdstsoScaledNotOptimalPredX2 : MCSchedPredicate>; def IsLdstsoScaledPredX2 : MCSchedPredicate>>; Index: llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s =================================================================== --- llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s +++ llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s @@ -5,6 +5,7 @@ pld [pc, #8] pldw [pc, #-128] pldw [pc, r0, lsl #2] + pldw [pc, r0, lsl #4] pldw [pc, -r0] ldr r5, [r7] ldr r6, [r3, #63] @@ -176,6 +177,7 @@ # CHECK-NEXT: 1 4 1.00 * * pld [pc, #8] # CHECK-NEXT: 1 4 1.00 * * pldw [pc, #-128] # CHECK-NEXT: 1 4 1.00 * * pldw [pc, r0, lsl #2] +# CHECK-NEXT: 2 5 1.00 * * pldw [pc, r0, lsl #4] # CHECK-NEXT: 2 5 1.00 * * pldw [pc, -r0] # CHECK-NEXT: 1 4 1.00 * ldr r5, [r7] # CHECK-NEXT: 1 4 1.00 * ldr r6, [r3, #63] @@ -184,11 +186,11 @@ # CHECK-NEXT: 2 4 1.00 * ldr r3, [r1], #-30 # CHECK-NEXT: 1 4 1.00 * ldr r3, [r8, r1] # CHECK-NEXT: 1 4 1.00 * ldr r3, [r8, r1, lsl #2] -# CHECK-NEXT: 1 4 1.00 * ldr r3, [r8, r1, asr #2] +# CHECK-NEXT: 2 5 1.00 * ldr r3, [r8, r1, asr #2] # CHECK-NEXT: 2 5 1.00 * ldr r2, [r5, -r3] # CHECK-NEXT: 2 4 1.00 * ldr r1, [r5, r9]! # CHECK-NEXT: 2 4 1.00 * ldr r6, [r7, -r8]! -# CHECK-NEXT: 2 4 1.00 * ldr r1, [r0, r2, lsr #3]! +# CHECK-NEXT: 2 5 1.00 * ldr r1, [r0, r2, lsr #3]! # CHECK-NEXT: 2 4 1.00 * ldr r5, [r9], r2 # CHECK-NEXT: 2 4 1.00 * ldr r4, [r3], -r6 # CHECK-NEXT: 2 5 1.00 * ldr r3, [r8, -r2, lsl #15] @@ -202,7 +204,7 @@ # CHECK-NEXT: 2 5 1.00 * ldrb r1, [r5, -r1] # CHECK-NEXT: 2 4 1.00 * ldrb r3, [r5, r2]! # CHECK-NEXT: 2 4 1.00 * ldrb r3, [r5, r2, lsl #2]! -# CHECK-NEXT: 2 4 1.00 * ldrb r3, [r5, r2, asr #2]! +# CHECK-NEXT: 2 5 1.00 * ldrb r3, [r5, r2, asr #2]! # CHECK-NEXT: 2 4 1.00 * ldrb r6, [r9, -r3]! # CHECK-NEXT: 2 4 1.00 * ldrb r2, [r1], r4 # CHECK-NEXT: 2 4 1.00 * ldrb r8, [r4], -r5 @@ -347,13 +349,14 @@ # CHECK: Resource pressure per iteration: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] -# CHECK-NEXT: - 70.50 70.50 173.00 10.00 57.00 - - +# CHECK-NEXT: - 71.50 71.50 174.00 10.00 57.00 - - # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: - - - 1.00 - - - - pld [pc, #8] # CHECK-NEXT: - - - 1.00 - - - - pldw [pc, #-128] # CHECK-NEXT: - - - 1.00 - - - - pldw [pc, r0, lsl #2] +# CHECK-NEXT: - 0.50 0.50 1.00 - - - - pldw [pc, r0, lsl #4] # CHECK-NEXT: - 0.50 0.50 1.00 - - - - pldw [pc, -r0] # CHECK-NEXT: - - - 1.00 - - - - ldr r5, [r7] # CHECK-NEXT: - - - 1.00 - - - - ldr r6, [r3, #63] @@ -362,7 +365,7 @@ # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldr r3, [r1], #-30 # CHECK-NEXT: - - - 1.00 - - - - ldr r3, [r8, r1] # CHECK-NEXT: - - - 1.00 - - - - ldr r3, [r8, r1, lsl #2] -# CHECK-NEXT: - - - 1.00 - - - - ldr r3, [r8, r1, asr #2] +# CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldr r3, [r8, r1, asr #2] # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldr r2, [r5, -r3] # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldr r1, [r5, r9]! # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldr r6, [r7, -r8]!