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,40 +28,62 @@ // 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 RegShiftedBody : CheckAll<[IsArithLogicShiftPred, + CheckNot>]>; +def RegShiftedPred : MCSchedPredicate; +def RegShiftedFn : TIIPredicate<"hasShiftedReg", + MCReturnStatement>; + // Identify a load or store using the register offset addressing mode // with an extended or scaled register. -def ScaledIdxBody : CheckAll<[CheckAny<[IsLoadRegOffsetPred, - IsStoreRegOffsetPred]>, - CheckAny<[CheckNot, - CheckMemScaled]>]>; -def ScaledIdxPred : MCSchedPredicate; -def ScaledIdxFn : TIIPredicate<"isScaledAddr", - MCReturnStatement>; +def ScaledIdxBody : CheckAll<[CheckAny<[IsLoadRegOffsetPred, + IsStoreRegOffsetPred]>, + CheckAny<[CheckNot, + CheckMemScaled]>]>; +def ScaledIdxPred : MCSchedPredicate; +def ScaledIdxFn : TIIPredicate<"isScaledAddr", + MCReturnStatement>; 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 =================================================================== --- /dev/null +++ llvm/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s @@ -0,0 +1,25 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -march=aarch64 -mcpu=cortex-a57 -resource-pressure=false < %s | FileCheck %s + + add x0, x1, x2, lsl #3 + +# CHECK: Iterations: 100 +# CHECK-NEXT: Instructions: 100 +# CHECK-NEXT: Total Cycles: 104 +# CHECK-NEXT: Total uOps: 100 + +# CHECK: Dispatch Width: 3 +# 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 +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 2 1.00 add x0, x1, x2, lsl #3