if (!Subtarget.hasCustomCheapAsMoveHandling())
return MI.isAsCheapAsAMove();
+ const unsigned Opcode = MI.getOpcode();
+
+ // Firstly, check cases gated by features.
+
+ if (Subtarget.hasZeroCycleZeroingFP()) {
+ if (Opcode == AArch64::FMOVH0 ||
+ Opcode == AArch64::FMOVS0 ||
+ Opcode == AArch64::FMOVD0)
+ return true;
+ }
+
+ if (Subtarget.hasZeroCycleZeroingGP()) {
+ if (Opcode == TargetOpcode::COPY &&
+ (MI.getOperand(1).getReg() == AArch64::WZR ||
+ MI.getOperand(1).getReg() == AArch64::XZR))
+ return true;
+ }
+
+ // Secondly, check cases specific to sub-targets.
+
if (Subtarget.hasExynosCheapAsMoveHandling()) {
if (isExynosResetFast(MI) || isExynosShiftLeftFast(MI))
return true;
return MI.isAsCheapAsAMove();
}
- switch (MI.getOpcode()) {
+ // Finally, check generic cases.
+
+ switch (Opcode) {
default:
return false;
return canBeExpandedToORR(MI, 32);
case AArch64::MOVi64imm:
return canBeExpandedToORR(MI, 64);
-
- // It is cheap to zero out registers if the subtarget has ZeroCycleZeroing
- // feature.
- case AArch64::FMOVH0:
- case AArch64::FMOVS0:
- case AArch64::FMOVD0:
- return Subtarget.hasZeroCycleZeroingFP();
- case TargetOpcode::COPY:
- return (Subtarget.hasZeroCycleZeroingGP() &&
- (MI.getOperand(1).getReg() == AArch64::WZR ||
- MI.getOperand(1).getReg() == AArch64::XZR));
}
llvm_unreachable("Unknown opcode to check as cheap as a move!");