Index: lib/Target/AArch64/AArch64.td =================================================================== --- lib/Target/AArch64/AArch64.td +++ lib/Target/AArch64/AArch64.td @@ -245,6 +245,7 @@ FeatureCRC, FeatureCrypto, FeatureFPARMv8, + FeatureMacroOpFusion, FeatureNEON, FeaturePostRAScheduler, HasV8_1aOps]>; Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1803,6 +1803,79 @@ // Fuse CMN, CMP, TST followed by Bcc. unsigned SecondOpcode = Second.getOpcode(); if (SecondOpcode == AArch64::Bcc) { + if (Subtarget.getProcFamily() == AArch64Subtarget::Vulcan) { + // All simple ALU operations that use one micro-op + // can be fused on Vulcan. This is essentially the + // operations without extend and/or shift. + switch (First.getOpcode()) { + default: + return false; + // ADD(S) + case AArch64::ADDWri: + case AArch64::ADDWrr: + case AArch64::ADDXri: + case AArch64::ADDXrr: + case AArch64::ADDSWri: + case AArch64::ADDSWrr: + case AArch64::ADDSXri: + case AArch64::ADDSXrr: + // SUB(S) + case AArch64::SUBWri: + case AArch64::SUBWrr: + case AArch64::SUBXri: + case AArch64::SUBXrr: + case AArch64::SUBSWri: + case AArch64::SUBSWrr: + case AArch64::SUBSXri: + case AArch64::SUBSXrr: + // ADC(S) + case AArch64::ADCWr: + case AArch64::ADCXr: + case AArch64::ADCSWr: + case AArch64::ADCSXr: + // AND(S) + case AArch64::ANDWri: + case AArch64::ANDWrr: + case AArch64::ANDXri: + case AArch64::ANDXrr: + case AArch64::ANDSXri: + case AArch64::ANDSXrr: + case AArch64::ANDSWri: + case AArch64::ANDSWrr: + // BIC(S) + case AArch64::BICWrr: + case AArch64::BICXrr: + case AArch64::BICSXrr: + case AArch64::BICSWrr: + // EON + case AArch64::EONWrr: + case AArch64::EONXrr: + // EOR + case AArch64::EORWri: + case AArch64::EORWrr: + case AArch64::EORXri: + case AArch64::EORXrr: + // ORN + case AArch64::ORNWrr: + case AArch64::ORNXrr: + // ORR + case AArch64::ORRWri: + case AArch64::ORRWrr: + case AArch64::ORRXri: + case AArch64::ORRXrr: + // CCMN + case AArch64::CCMNWi: + case AArch64::CCMNWr: + case AArch64::CCMNXi: + case AArch64::CCMNXr: + // CCMP + case AArch64::CCMPWi: + case AArch64::CCMPWr: + case AArch64::CCMPXi: + case AArch64::CCMPXr: + return true; + } + } switch (First.getOpcode()) { default: return false;