Index: llvm/lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -62,10 +62,6 @@ unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override; - /// Returns true if there is a shiftable register and that the shift value - /// is non-zero. - static bool hasShiftedReg(const MachineInstr &MI); - /// Returns true if there is an extendable register and that the extending /// value is non-zero. static bool hasExtendedReg(const MachineInstr &MI); Index: llvm/lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1938,44 +1938,6 @@ return true; } -/// Return true if this is this instruction has a non-zero immediate -bool AArch64InstrInfo::hasShiftedReg(const MachineInstr &MI) { - switch (MI.getOpcode()) { - default: - break; - case AArch64::ADDSWrs: - case AArch64::ADDSXrs: - case AArch64::ADDWrs: - case AArch64::ADDXrs: - case AArch64::ANDSWrs: - case AArch64::ANDSXrs: - case AArch64::ANDWrs: - case AArch64::ANDXrs: - case AArch64::BICSWrs: - case AArch64::BICSXrs: - case AArch64::BICWrs: - case AArch64::BICXrs: - case AArch64::EONWrs: - case AArch64::EONXrs: - case AArch64::EORWrs: - case AArch64::EORXrs: - case AArch64::ORNWrs: - case AArch64::ORNXrs: - case AArch64::ORRWrs: - case AArch64::ORRXrs: - case AArch64::SUBSWrs: - case AArch64::SUBSXrs: - case AArch64::SUBWrs: - case AArch64::SUBXrs: - if (MI.getOperand(3).isImm()) { - unsigned val = MI.getOperand(3).getImm(); - return (val != 0); - } - break; - } - return false; -} - /// Return true if this is this instruction has a non-zero immediate bool AArch64InstrInfo::hasExtendedReg(const MachineInstr &MI) { switch (MI.getOpcode()) { Index: llvm/lib/Target/AArch64/AArch64SchedPredicates.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SchedPredicates.td +++ llvm/lib/Target/AArch64/AArch64SchedPredicates.td @@ -28,43 +28,68 @@ // Generic predicates. +// Identify arithmetic instructions with shift. +def IsArithShiftPred : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs, + SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>; + +// Identify logic instructions with shift. +def IsLogicShiftPred : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs, + BICWrs, BICXrs, BICSWrs, BICSXrs, + EONWrs, EONXrs, + EORWrs, EORXrs, + ORNWrs, ORNXrs, + ORRWrs, ORRXrs]>; + +// Identify arithmetic and logic instructions with shift. +def IsArithLogicShiftPred : CheckAny<[IsArithShiftPred, IsLogicShiftPred]>; + // Identify whether an instruction is a load // using the register offset addressing mode. -def IsLoadRegOffsetPred : CheckOpcode<[PRFMroW, PRFMroX, - LDRBBroW, LDRBBroX, - LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX, - LDRHHroW, LDRHHroX, - LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX, - LDRWroW, LDRWroX, - LDRSWroW, LDRSWroX, - LDRXroW, LDRXroX, - LDRBroW, LDRBroX, - LDRHroW, LDRHroX, - LDRSroW, LDRSroX, - LDRDroW, LDRDroX]>; +def IsLoadRegOffsetPred : CheckOpcode<[PRFMroW, PRFMroX, + LDRBBroW, LDRBBroX, + LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX, + LDRHHroW, LDRHHroX, + LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX, + LDRWroW, LDRWroX, + LDRSWroW, LDRSWroX, + LDRXroW, LDRXroX, + LDRBroW, LDRBroX, + LDRHroW, LDRHroX, + LDRSroW, LDRSroX, + LDRDroW, LDRDroX]>; // Identify whether an instruction is a load // using the register offset addressing mode. -def IsStoreRegOffsetPred : CheckOpcode<[STRBBroW, STRBBroX, - STRHHroW, STRHHroX, - STRWroW, STRWroX, - STRXroW, STRXroX, - STRBroW, STRBroX, - STRHroW, STRHroX, - STRSroW, STRSroX, - STRDroW, STRDroX]>; +def IsStoreRegOffsetPred : CheckOpcode<[STRBBroW, STRBBroX, + STRHHroW, STRHHroX, + STRWroW, STRWroX, + STRXroW, STRXroX, + STRBroW, STRBroX, + STRHroW, STRHroX, + STRSroW, STRSroX, + STRDroW, STRDroX]>; // Target predicates. +// Identify arithmetic and logic instructions with a shifted register. +def RegShiftedFn : TIIPredicate<"hasShiftedReg", + MCOpcodeSwitchStatement< + [MCOpcodeSwitchCase< + !listconcat(IsArithShiftPred.ValidOpcodes, + IsLogicShiftPred.ValidOpcodes), + MCReturnStatement>>>], + MCReturnStatement>>; +def RegShiftedPred : MCSchedPredicate; + // Identify a load or store using the register offset addressing mode // with an extended or scaled register. -def ScaledIdxFn : TIIPredicate<"isScaledAddr", - MCOpcodeSwitchStatement< - [MCOpcodeSwitchCase< - !listconcat(IsLoadRegOffsetPred.ValidOpcodes, - IsStoreRegOffsetPred.ValidOpcodes), - MCReturnStatement< - CheckAny<[CheckNot, - CheckMemScaled]>>>], - MCReturnStatement>>; -def ScaledIdxPred : MCSchedPredicate; +def ScaledIdxFn : TIIPredicate<"isScaledAddr", + MCOpcodeSwitchStatement< + [MCOpcodeSwitchCase< + !listconcat(IsLoadRegOffsetPred.ValidOpcodes, + IsStoreRegOffsetPred.ValidOpcodes), + MCReturnStatement< + CheckAny<[CheckNot, + CheckMemScaled]>>>], + MCReturnStatement>>; +def ScaledIdxPred : MCSchedPredicate; Index: llvm/lib/Target/AArch64/AArch64Schedule.td =================================================================== --- llvm/lib/Target/AArch64/AArch64Schedule.td +++ llvm/lib/Target/AArch64/AArch64Schedule.td @@ -50,9 +50,6 @@ def WriteSTIdx : SchedWrite; // Store to a register index (maybe scaled). def ReadAdrBase : SchedRead; // Read the base resister of a reg-offset LD/ST. -// Predicate for determining when a shiftable register is shifted. -def RegShiftedPred : SchedPredicate<[{TII->hasShiftedReg(*MI)}]>; - // Predicate for determining when a extendedable register is extended. def RegExtendedPred : SchedPredicate<[{TII->hasExtendedReg(*MI)}]>; Index: llvm/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s =================================================================== --- llvm/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s +++ llvm/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s @@ -5,13 +5,13 @@ # CHECK: Iterations: 100 # CHECK-NEXT: Instructions: 100 -# CHECK-NEXT: Total Cycles: 53 +# CHECK-NEXT: Total Cycles: 104 # CHECK-NEXT: Total uOps: 100 # CHECK: Dispatch Width: 3 -# CHECK-NEXT: uOps Per Cycle: 1.89 -# CHECK-NEXT: IPC: 1.89 -# CHECK-NEXT: Block RThroughput: 0.5 +# CHECK-NEXT: uOps Per Cycle: 0.96 +# CHECK-NEXT: IPC: 0.96 +# CHECK-NEXT: Block RThroughput: 1.0 # CHECK: Instruction Info: # CHECK-NEXT: [1]: #uOps @@ -22,4 +22,4 @@ # CHECK-NEXT: [6]: HasSideEffects (U) # CHECK: [1] [2] [3] [4] [5] [6] Instructions: -# CHECK-NEXT: 1 1 0.50 add x0, x1, x2, lsl #3 +# CHECK-NEXT: 1 2 1.00 add x0, x1, x2, lsl #3