use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt;
use std::io::{self, Write};
use std::path::PathBuf;
use super::diagnostics::{
ClangSourceLocation, DiagSeverity, DiagnosticNote, DiagnosticOptions, FixItHint, SourceRange,
StructuredDiagnostic,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum X86DiagID {
BackendISelFail = 0,
BackendCannotSelect = 1,
BackendUnsupportedType = 2,
BackendIllegalType = 3,
BackendCannotLower = 4,
BackendCannotLegalize = 5,
BackendNoPattern = 6,
BackendRegallocSpill = 8,
BackendRegallocFail = 9,
BackendOutOfRegisters = 10,
BackendPhysRegUnavailable = 11,
BackendVirtRegUnmapped = 12,
BackendLiveInConflict = 13,
BackendStackSlotTooLarge = 14,
BackendFrameTooLarge = 20,
BackendStackRealignLimit = 21,
BackendCannotEliminateFrameIndex = 22,
BackendFrameOffsetOverflow = 23,
BackendRedZoneViolation = 24,
BackendPrologueEmissionFailed = 25,
BackendEpilogueEmissionFailed = 26,
BackendEncodingFail = 30,
BackendImmediateTooLarge = 31,
BackendDisplacementOverflow = 32,
BackendAddressModeInvalid = 33,
BackendRexPrefixConflict = 34,
BackendVexEncodingFail = 35,
BackendEvexEncodingFail = 36,
BackendOpcodeNotSupported = 37,
BackendRelaxationFail = 38,
BackendEmissionFail = 40,
BackendObjectEmissionFail = 41,
BackendAsmPrinterFail = 42,
BackendDwarfEmissionFail = 43,
BackendUnwindInfoFail = 44,
BackendELFStubFail = 45,
BackendCOFFStubFail = 46,
BackendMachOStubFail = 47,
BackendBranchTargetTooFar = 50,
BackendJumpTableFail = 51,
BackendIndirectBranchFail = 52,
BackendTailMergeFail = 53,
BackendConditionalTailCallFail = 54,
BackendUnsupportedIndirectCall = 55,
BackendScheduleConflict = 60,
BackendBundleFail = 61,
BackendResourceConflict = 62,
BackendDependencyCycle = 63,
BackendBlockPlacementFail = 70,
BackendLayoutConflict = 71,
BackendAlignmentConflict = 72,
BackendFastISelFail = 80,
BackendFastISelUnsupportedType = 81,
BackendFastISelUnsupportedOp = 82,
BackendFastISelNoVreg = 83,
BackendGISelFail = 90,
BackendGISelUnsupported = 91,
BackendGISelNoLegalizer = 92,
BackendGISelNoRegBank = 93,
FeatureMissingSSE = 1000,
FeatureMissingSSE2 = 1001,
FeatureMissingSSE3 = 1002,
FeatureMissingSSSE3 = 1003,
FeatureMissingSSE41 = 1004,
FeatureMissingSSE42 = 1005,
FeatureMissingAVX = 1006,
FeatureMissingAVX2 = 1007,
FeatureMissingAVX512F = 1008,
FeatureMissingAVX512BW = 1009,
FeatureMissingAVX512DQ = 1010,
FeatureMissingAVX512VL = 1011,
FeatureMissingAVX512CD = 1012,
FeatureMissingAVX512ER = 1013,
FeatureMissingAVX512PF = 1014,
FeatureMissingAVX512BF16 = 1015,
FeatureMissingAVX512FP16 = 1016,
FeatureMissingAVX512VBMI = 1017,
FeatureMissingAVX512VBMI2 = 1018,
FeatureMissingAVX512VNNI = 1019,
FeatureMissingAVX512BITALG = 1020,
FeatureMissingAVX512VPOPCNTDQ = 1021,
FeatureMissingAVX5124FMAPS = 1022,
FeatureMissingAVX5124VNNIW = 1023,
FeatureMissingAVX512VP2INTERSECT = 1024,
FeatureMissingAVX512IFMA = 1025,
FeatureMissingAVX512FP16Conv = 1026,
FeatureMissingAVX10_1_256 = 1027,
FeatureMissingAVX10_1_512 = 1028,
FeatureMissingAVX10_2 = 1029,
FeatureMissingFMA = 1030,
FeatureMissingFMA4 = 1031,
FeatureMissingF16C = 1032,
FeatureMissingXOP = 1033,
FeatureMissingMMX = 1034,
FeatureMissing3DNOW = 1035,
FeatureMissing3DNOWA = 1036,
FeatureMissingBMI = 1037,
FeatureMissingBMI2 = 1038,
FeatureMissingLZCNT = 1039,
FeatureMissingPOPCNT = 1040,
FeatureMissingTBM = 1041,
FeatureMissingAES = 1042,
FeatureMissingPCLMUL = 1043,
FeatureMissingSHA = 1044,
FeatureMissingSHA512 = 1045,
FeatureMissingSM3 = 1046,
FeatureMissingSM4 = 1047,
FeatureMissingGFNI = 1048,
FeatureMissingVAES = 1049,
FeatureMissingVPCLMULQDQ = 1050,
FeatureMissingRDRAND = 1051,
FeatureMissingRDSEED = 1052,
FeatureMissingADX = 1053,
FeatureMissingRTM = 1054,
FeatureMissingHLE = 1055,
FeatureMissingSGX = 1056,
FeatureMissingCET = 1057,
FeatureMissingXSAVE = 1058,
FeatureMissingXSAVEOPT = 1059,
FeatureMissingXSAVEC = 1060,
FeatureMissingXSAVES = 1061,
FeatureMissingFSGSBASE = 1062,
FeatureMissingMOVBE = 1063,
FeatureMissingMOVDIRI = 1064,
FeatureMissingMOVDIR64B = 1065,
FeatureMissingENQCMD = 1066,
FeatureMissingSERIALIZE = 1067,
FeatureMissingTSXLDTRK = 1068,
FeatureMissingWAITPKG = 1069,
FeatureMissingCLDEMOTE = 1070,
FeatureMissingCLFLUSHOPT = 1071,
FeatureMissingCLWB = 1072,
FeatureMissingCLZERO = 1073,
FeatureMissingMWAITX = 1074,
FeatureMissingMONITORX = 1075,
FeatureMissingPKU = 1076,
FeatureMissingSMAP = 1077,
FeatureMissingSMEP = 1078,
FeatureMissingMPX = 1079,
FeatureMissingPTWRITE = 1080,
FeatureMissingINVPCID = 1081,
FeatureMissingPREFETCHWT1 = 1082,
FeatureMissingPREFETCHW = 1083,
FeatureMissingPREFETCHI = 1084,
FeatureMissingAMX_BF16 = 1085,
FeatureMissingAMX_INT8 = 1086,
FeatureMissingAMX_TILE = 1087,
FeatureMissingAMX_FP16 = 1088,
FeatureMissingAMX_COMPLEX = 1089,
FeatureMissingX87 = 1090,
FeatureMissingCMOV = 1091,
FeatureMissingSAHF = 1092,
FeatureMissingRDPID = 1093,
FeatureMissingRDPRU = 1094,
FeatureMissingHRESET = 1095,
FeatureMissingUINTR = 1096,
FeatureMissingKL = 1097,
FeatureMissingWIDEKL = 1098,
FeatureMissingCMPCCXADD = 1099,
FeatureMissingRAOINT = 1100,
FeatureMissingAVX_NE_CONVERT = 1101,
FeatureMissingAVX_VNNI = 1102,
FeatureMissingAVX_VNNI_INT8 = 1103,
FeatureNeedsX86_64V2 = 1120,
FeatureNeedsX86_64V3 = 1121,
FeatureNeedsX86_64V4 = 1122,
FeatureDeprecated = 1123,
FeatureRemoved = 1124,
FeatureExperimental = 1125,
FeatureConflicting = 1126,
FeatureMissingForCPU = 1127,
FeatureNotAvailableOnCPU = 1128,
FeatureRequires64Bit = 1129,
FeatureRequires32Bit = 1130,
FeatureMismatchedTuning = 1140,
FeatureGenericTuning = 1141,
FeatureSuboptimalTuning = 1142,
ABIStructTooLarge = 2000,
ABIStructPassedInMem = 2001,
ABIStructSplitAcrossRegs = 2002,
ABIReturnTooLarge = 2003,
ABIHiddenPointerReturn = 2004,
ABIParamTooLarge = 2005,
ABITooManyParams = 2006,
ABIMismatchedCallingConv = 2007,
ABIUnknownCallingConv = 2008,
ABICallingConvNotSupported = 2009,
ABIFastcallTooManyArgs = 2010,
ABIVectorcallAlignment = 2011,
ABIVectorcallTypeUnsupported = 2012,
ABIRegcallNotEnoughRegs = 2013,
ABIThiscallNonMember = 2014,
ABIStdCallVarArgs = 2015,
ABICdeclMismatch = 2016,
ABIStackAlignmentViolation = 2020,
ABIRedZoneViolation = 2021,
ABIArgOverlap = 2022,
ABIRegisterClassMismatch = 2023,
ABIHomogeneousAggregate = 2024,
ABIFloatArgsInIntegerReg = 2025,
ABIIntegerArgsInFloatReg = 2026,
ABIX87Return = 2027,
ABIComplexReturn = 2028,
ABISysVClassificationFailed = 2030,
ABIMicrosoftClassificationFailed = 2031,
ABIRegCallClassificationFailed = 2032,
ABIUnclassifiedType = 2033,
ABIMemClassTooMany = 2034,
ABIEmptyStructPass = 2035,
ABIZeroWidthBitfield = 2036,
ABIUnalignedFieldPass = 2037,
ABIPackedStructPass = 2038,
ABIUnionPass = 2039,
ABIBitfieldStraddle = 2040,
SizeFunctionTooLarge = 3000,
SizeBasicBlockTooLarge = 3001,
SizeAlignmentExcessive = 3002,
SizeNopPaddingExcessive = 3003,
SizeJumpTableTooLarge = 3004,
SizeELFTextOverflow = 3005,
SizeCOFFTextOverflow = 3006,
SizeSectionOverflow = 3007,
SizeDisplacementOverflowRelax = 3008,
SizeCallDisplacementError = 3009,
SizeJumpDisplacementError = 3010,
SizeLoopAlignmentHint = 3011,
SizeFunctionAlignmentHint = 3012,
SizeBranchRelaxRequired = 3013,
SizeRelaxationLoop = 3014,
SizeColdSectionSplit = 3015,
SizeUnlikelyBranch = 3016,
SizeHotColdPadding = 3017,
SizeOptNoneHint = 3020,
SizeOptSizeHint = 3021,
SizeMinSizeHint = 3022,
SizeBlockPlacementHint = 3023,
SizeTailDuplicationHint = 3024,
AlignUnalignedAccess = 4000,
AlignUnalignedStackAccess = 4001,
AlignUnalignedLoad = 4002,
AlignUnalignedStore = 4003,
AlignMisalignedAtomics = 4004,
AlignLockPrefixAlign = 4005,
AlignSIMDUnalignedAccess = 4006,
AlignAVXUnalignedAccess = 4007,
AlignAVX512UnalignedAccess = 4008,
AlignDataAlign = 4009,
AlignCodeAlign = 4010,
AlignStackAlign = 4011,
AlignStructAlign = 4012,
AlignCacheLineBoundary = 4013,
AlignPageBoundary = 4014,
AlignFunctionEntryAlign = 4015,
AlignLoopAlign = 4016,
AlignUnalignedBranchTarget = 4017,
AlignMisalignedReturnAddress = 4018,
AlignStackRealignNeeded = 4020,
AlignStackProbeNeeded = 4021,
AlignVariableAlignment = 4022,
AlignNopSledNeeded = 4023,
AlignOverAlignedAlloca = 4024,
AlignUnderAlignedAlloca = 4025,
InlineAsmParseError = 5000,
InlineAsmInvalidInstruction = 5001,
InlineAsmInvalidOperand = 5002,
InlineAsmInvalidConstraint = 5003,
InlineAsmClobberConflict = 5004,
InlineAsmRegisterClobbered = 5005,
InlineAsmTooManyOperands = 5006,
InlineAsmSizeMismatch = 5007,
InlineAsmUnsupportedConstraint = 5008,
InlineAsmImmediateConstraint = 5009,
InlineAsmMemoryConstraint = 5010,
InlineAsmFloatConstraint = 5011,
InlineAsmMultipleAlternative = 5012,
InlineAsmInvalidTiedOperand = 5013,
InlineAsmDuplicateConstraint = 5014,
InlineAsmInputOutputMismatch = 5015,
InlineAsmGlobalRegister = 5016,
InlineAsmFramePointerClobber = 5017,
InlineAsmStackPointerClobber = 5018,
InlineAsmReservedRegister = 5019,
InlineAsmIPRegisterClobber = 5020,
InlineAsmFlagsRegisterClobber = 5021,
InlineAsmAVX512MaskOperand = 5030,
InlineAsmAVX512BroadcastOperand = 5031,
InlineAsmAVX512RoundingOperand = 5032,
InlineAsmAVX512SAEOperand = 5033,
InlineAsmAVX512ZeroMasking = 5034,
InlineAsmAMXTileOperand = 5035,
InlineAsmAMXConfigNeeded = 5036,
InlineAsmGotoLabel = 5040,
InlineAsmGotoTooManyLabels = 5041,
InlineAsmGotoIndirectBranch = 5042,
InlineAsmIntelSyntaxWarning = 5050,
InlineAsmATTDirectiveWarning = 5051,
InlineAsmIntelDirectiveWarning = 5052,
InlineAsmSplitOperandType = 5053,
InlineAsmUndefinedSymbol = 5060,
InlineAsmRelocationOverflow = 5061,
InlineAsmAbsoluteAddress = 5062,
InlineAsmTLSRelocation = 5063,
InlineAsmGOTPCREL = 5064,
InlineAsmPLTRelocation = 5065,
InlineAsmSegmentOverride = 5070,
InlineAsmAddressSizeOverride = 5071,
InlineAsmOperandSizeOverride = 5072,
InlineAsmREXPrefixUnused = 5073,
InlineAsmLockPrefixWrong = 5074,
InlineAsmRepPrefixWrong = 5075,
InlineAsmVEXPrefixInvalid = 5076,
InlineAsmEVEXPrefixInvalid = 5077,
VectorWidthMismatch = 6000,
VectorTypeMismatch = 6001,
VectorElementCountMismatch = 6002,
VectorShuffleMaskInvalid = 6003,
VectorShuffleMaskOutOfRange = 6004,
VectorInsertIndexOutOfRange = 6005,
VectorExtractIndexOutOfRange = 6006,
VectorGatherScatterAlign = 6007,
VectorMaskOperandMissing = 6008,
VectorMaskTypeMismatch = 6009,
VectorZeroMaskNotSupported = 6010,
VectorMergeMaskNotSupported = 6011,
VectorBroadcastUnsupported = 6020,
VectorBroadcastMemSource = 6021,
VectorBroadcastWidth = 6022,
VectorPermuteUnsupported = 6023,
VectorInterleaveUnsupported = 6024,
VectorDeinterleaveUnsupported = 6025,
VectorLoadUnaligned = 6030,
VectorStoreUnaligned = 6031,
VectorLoadNonTemporal = 6032,
VectorStoreNonTemporal = 6033,
VectorGatherUnsupported = 6040,
VectorScatterUnsupported = 6041,
VectorGather4Unsupported = 6042,
VectorScatter4Unsupported = 6043,
VectorCompressUnsupported = 6044,
VectorExpandUnsupported = 6045,
VectorReduceUnsupported = 6050,
VectorHorizontalAddSub = 6051,
VectorDotProductUnsupported = 6052,
VectorFMAUnsupported = 6053,
VectorFP16Unsupported = 6054,
VectorBF16Unsupported = 6055,
VectorINT8Unsupported = 6056,
VectorINT4Unsupported = 6057,
VectorFPUnsupportedForWidth = 6060,
VectorIntegerUnsupportedForWidth = 6061,
VectorConversionRounding = 6062,
VectorConvertOverflow = 6063,
VectorConvertSaturation = 6064,
VectorAbsUnsupported = 6070,
VectorMinMaxUnsupported = 6071,
VectorRoundUnsupported = 6072,
VectorSqrtUnsupported = 6073,
VectorRcpUnsupported = 6074,
VectorRsqrtUnsupported = 6075,
VectorPopcountUnsupported = 6076,
VectorLZCNTUnsupported = 6077,
VectorRotateUnsupported = 6078,
VectorShiftImmOutOfRange = 6080,
VectorShiftAmountMismatch = 6081,
VectorBlendMaskInvalid = 6082,
VectorComparePredicateInvalid = 6083,
VectorSelectConditionInvalid = 6084,
VectorAMXLoadStore = 6090,
VectorAMXTileShape = 6091,
VectorAMXConfig = 6092,
VectorAMXZero = 6093,
VectorAMXTilePair = 6094,
VectorSSEUpgradeHint = 6100,
VectorAVXUpgradeHint = 6101,
VectorAVX512UpgradeHint = 6102,
VectorAVX10UpgradeHint = 6103,
VectorUsePackedHint = 6110,
VectorUseScalarHint = 6111,
VectorUseGatherHint = 6112,
VectorUseScatterHint = 6113,
OptX86ISelSuccess = 7000,
OptX86ISelFailure = 7001,
OptX86PeepholeApplied = 7010,
OptX86PeepholeSkipped = 7011,
OptX86MacroFusion = 7020,
OptX86MicroFusion = 7021,
OptX86NopInsertion = 7022,
OptX86PrefixOptimization = 7023,
OptX86LEAUsesAG = 7024,
OptX86LEAUsesLEA = 7025,
OptX86CMOVConversion = 7030,
OptX86SETCCConversion = 7031,
OptX86BranchAvoidance = 7032,
OptX86FlagCopyEliminated = 7033,
OptX86ConditionalMove = 7034,
OptX86LoadFoldIntoInstr = 7040,
OptX86StoreFoldIntoInstr = 7041,
OptX86ImmediateFold = 7042,
OptX86AddressFold = 7043,
OptX86ConstantPoolFold = 7044,
OptX86TwoAddressPass = 7045,
OptX86FixupBWInst = 7050,
OptX86FixupLEA = 7051,
OptX86AvoidStoreForwarding = 7052,
OptX86AvoidPartialRegStall = 7053,
OptX86AvoidPartialFlagStall = 7054,
OptX86DomainCrossing = 7055,
OptX86VZeroupperInserted = 7060,
OptX86VZeroupperNotNeeded = 7061,
OptX86TileConfigInserted = 7062,
OptX86X87Stackify = 7063,
OptX86CallFrameOptimization = 7064,
OptX86StackColoring = 7065,
OptX86ShrinkWrapping = 7066,
OptX86TailDuplicate = 7070,
OptX86TailMerge = 7071,
OptX86MachineLICM = 7072,
OptX86MachineCSE = 7073,
OptX86MachineSink = 7074,
OptX86LoopAlignment = 7075,
OptX86BranchFolding = 7080,
OptX86IfConversion = 7081,
OptX86MachineBlockPlacement = 7082,
OptX86EarlyIfConversion = 7083,
OptX86SpeculativeLoadHardening = 7084,
OptX86IndirectBranchTracking = 7085,
OptX86Scheduler = 7090,
OptX86PostRAScheduler = 7091,
OptX86PreRAScheduler = 7092,
OptX86MachinePipeliner = 7093,
OptX86RegisterCoalescing = 7100,
OptX86VirtualRegisterRewrite = 7101,
OptX86LiveRangeShrink = 7102,
OptX86DeadMachineInstructionElim = 7103,
OptX86PrologEpilogInsertion = 7110,
OptX86FrameLowering = 7111,
OptX86RedZone = 7112,
OptX86ShadowStack = 7113,
OptX86PatchableFunction = 7114,
OptX86FunctionSections = 7120,
OptX86DataSections = 7121,
OptX86NoOmitFramePointer = 7122,
OptX86OmitFramePointer = 7123,
OptX86HotColdSplit = 7124,
LinkerRelocationOverflow = 8000,
LinkerGOTOverflow = 8001,
LinkerPLTOverflow = 8002,
LinkerTLSOverflow = 8003,
LinkerUnresolvedSymbol = 8004,
LinkerSectionMismatch = 8005,
LinkerTrampolineNeeded = 8006,
LinkerRelaxationNeeded = 8007,
LinkerThreadLocalModel = 8010,
LinkerTLSLocalExec = 8011,
LinkerTLSInitialExec = 8012,
LinkerTLSLocalDynamic = 8013,
LinkerTLSGlobalDynamic = 8014,
MiscStackProbe = 9000,
MiscAllocaProbe = 9001,
MiscVLAProbe = 9002,
MiscSegmentedStack = 9003,
MiscSplitStack = 9004,
MiscXRayInstrumentation = 9005,
MiscCFIInstruction = 9006,
MiscUnwindOpcode = 9007,
MiscSEHUnwind = 9008,
MiscCETEndBranch = 9010,
MiscShadowCallStack = 9011,
MiscSafeStack = 9012,
MiscControlFlowGuard = 9013,
MiscKCFI = 9014,
MiscFineIBT = 9015,
MiscMemoryTagging = 9016,
MiscHardwareEnforcedSP = 9017,
MiscZeroCallUsedRegs = 9020,
MiscFEntryInsertion = 9021,
MiscDirectEmission = 9022,
MiscDelaySlotFill = 9023,
MiscConstantIsland = 9024,
}
pub struct X86DiagnosticCatalog;
impl X86DiagnosticCatalog {
pub fn default_severity(id: X86DiagID) -> DiagSeverity {
match id {
X86DiagID::BackendISelFail
| X86DiagID::BackendCannotSelect
| X86DiagID::BackendUnsupportedType
| X86DiagID::BackendIllegalType
| X86DiagID::BackendCannotLower
| X86DiagID::BackendCannotLegalize
| X86DiagID::BackendNoPattern
| X86DiagID::BackendRegallocSpill
| X86DiagID::BackendRegallocFail
| X86DiagID::BackendOutOfRegisters
| X86DiagID::BackendPhysRegUnavailable
| X86DiagID::BackendVirtRegUnmapped
| X86DiagID::BackendLiveInConflict
| X86DiagID::BackendStackSlotTooLarge
| X86DiagID::BackendFrameTooLarge
| X86DiagID::BackendStackRealignLimit
| X86DiagID::BackendCannotEliminateFrameIndex
| X86DiagID::BackendFrameOffsetOverflow
| X86DiagID::BackendPrologueEmissionFailed
| X86DiagID::BackendEpilogueEmissionFailed
| X86DiagID::BackendEncodingFail
| X86DiagID::BackendImmediateTooLarge
| X86DiagID::BackendDisplacementOverflow
| X86DiagID::BackendAddressModeInvalid
| X86DiagID::BackendRexPrefixConflict
| X86DiagID::BackendVexEncodingFail
| X86DiagID::BackendEvexEncodingFail
| X86DiagID::BackendOpcodeNotSupported
| X86DiagID::BackendRelaxationFail
| X86DiagID::BackendEmissionFail
| X86DiagID::BackendObjectEmissionFail
| X86DiagID::BackendAsmPrinterFail
| X86DiagID::BackendDwarfEmissionFail
| X86DiagID::BackendUnwindInfoFail
| X86DiagID::BackendELFStubFail
| X86DiagID::BackendCOFFStubFail
| X86DiagID::BackendMachOStubFail
| X86DiagID::BackendBranchTargetTooFar
| X86DiagID::BackendJumpTableFail
| X86DiagID::BackendIndirectBranchFail
| X86DiagID::BackendTailMergeFail
| X86DiagID::BackendConditionalTailCallFail
| X86DiagID::BackendUnsupportedIndirectCall
| X86DiagID::BackendScheduleConflict
| X86DiagID::BackendBundleFail
| X86DiagID::BackendResourceConflict
| X86DiagID::BackendDependencyCycle
| X86DiagID::BackendBlockPlacementFail
| X86DiagID::BackendLayoutConflict
| X86DiagID::BackendGISelFail
| X86DiagID::BackendGISelUnsupported
| X86DiagID::BackendGISelNoLegalizer
| X86DiagID::BackendGISelNoRegBank => DiagSeverity::Error,
X86DiagID::LinkerRelocationOverflow
| X86DiagID::LinkerGOTOverflow
| X86DiagID::LinkerUnresolvedSymbol
| X86DiagID::LinkerSectionMismatch
| X86DiagID::LinkerTrampolineNeeded
| X86DiagID::LinkerRelaxationNeeded => DiagSeverity::Error,
X86DiagID::FeatureMissingSSE
| X86DiagID::FeatureMissingSSE2
| X86DiagID::FeatureMissingSSE3
| X86DiagID::FeatureMissingSSSE3
| X86DiagID::FeatureMissingSSE41
| X86DiagID::FeatureMissingSSE42
| X86DiagID::FeatureMissingAVX
| X86DiagID::FeatureMissingAVX2
| X86DiagID::FeatureMissingAVX512F
| X86DiagID::FeatureMissingAVX512BW
| X86DiagID::FeatureMissingAVX512DQ
| X86DiagID::FeatureMissingAVX512VL
| X86DiagID::FeatureMissingAVX512CD
| X86DiagID::FeatureMissingAVX512ER
| X86DiagID::FeatureMissingAVX512PF
| X86DiagID::FeatureMissingAVX512BF16
| X86DiagID::FeatureMissingAVX512FP16
| X86DiagID::FeatureMissingAVX512VBMI
| X86DiagID::FeatureMissingAVX512VNNI
| X86DiagID::FeatureMissingAVX512BITALG
| X86DiagID::FeatureMissingAVX512VPOPCNTDQ
| X86DiagID::FeatureMissingAVX5124FMAPS
| X86DiagID::FeatureMissingAVX5124VNNIW
| X86DiagID::FeatureMissingAVX512VP2INTERSECT
| X86DiagID::FeatureMissingAVX512IFMA
| X86DiagID::FeatureMissingAVX10_1_256
| X86DiagID::FeatureMissingAVX10_1_512
| X86DiagID::FeatureMissingAVX10_2
| X86DiagID::FeatureMissingFMA
| X86DiagID::FeatureMissingFMA4
| X86DiagID::FeatureMissingF16C
| X86DiagID::FeatureMissingXOP
| X86DiagID::FeatureMissingMMX
| X86DiagID::FeatureMissing3DNOW
| X86DiagID::FeatureMissing3DNOWA
| X86DiagID::FeatureMissingBMI
| X86DiagID::FeatureMissingBMI2
| X86DiagID::FeatureMissingLZCNT
| X86DiagID::FeatureMissingPOPCNT
| X86DiagID::FeatureMissingTBM
| X86DiagID::FeatureMissingAES
| X86DiagID::FeatureMissingPCLMUL
| X86DiagID::FeatureMissingSHA
| X86DiagID::FeatureMissingSHA512
| X86DiagID::FeatureMissingSM3
| X86DiagID::FeatureMissingSM4
| X86DiagID::FeatureMissingGFNI
| X86DiagID::FeatureMissingVAES
| X86DiagID::FeatureMissingVPCLMULQDQ
| X86DiagID::FeatureMissingRDRAND
| X86DiagID::FeatureMissingRDSEED
| X86DiagID::FeatureMissingADX
| X86DiagID::FeatureMissingRTM
| X86DiagID::FeatureMissingHLE
| X86DiagID::FeatureMissingSGX
| X86DiagID::FeatureMissingCET
| X86DiagID::FeatureMissingXSAVE
| X86DiagID::FeatureMissingXSAVEOPT
| X86DiagID::FeatureMissingXSAVEC
| X86DiagID::FeatureMissingXSAVES
| X86DiagID::FeatureMissingFSGSBASE
| X86DiagID::FeatureMissingMOVBE
| X86DiagID::FeatureMissingMOVDIRI
| X86DiagID::FeatureMissingMOVDIR64B
| X86DiagID::FeatureMissingENQCMD
| X86DiagID::FeatureMissingSERIALIZE
| X86DiagID::FeatureMissingTSXLDTRK
| X86DiagID::FeatureMissingWAITPKG
| X86DiagID::FeatureMissingCLDEMOTE
| X86DiagID::FeatureMissingCLFLUSHOPT
| X86DiagID::FeatureMissingCLWB
| X86DiagID::FeatureMissingCLZERO
| X86DiagID::FeatureMissingMWAITX
| X86DiagID::FeatureMissingMONITORX
| X86DiagID::FeatureMissingPKU
| X86DiagID::FeatureMissingSMAP
| X86DiagID::FeatureMissingSMEP
| X86DiagID::FeatureMissingMPX
| X86DiagID::FeatureMissingPTWRITE
| X86DiagID::FeatureMissingINVPCID
| X86DiagID::FeatureMissingPREFETCHWT1
| X86DiagID::FeatureMissingPREFETCHW
| X86DiagID::FeatureMissingPREFETCHI
| X86DiagID::FeatureMissingAMX_BF16
| X86DiagID::FeatureMissingAMX_INT8
| X86DiagID::FeatureMissingAMX_TILE
| X86DiagID::FeatureMissingAMX_FP16
| X86DiagID::FeatureMissingAMX_COMPLEX
| X86DiagID::FeatureMissingX87
| X86DiagID::FeatureMissingCMOV
| X86DiagID::FeatureMissingSAHF
| X86DiagID::FeatureMissingRDPID
| X86DiagID::FeatureMissingRDPRU
| X86DiagID::FeatureMissingHRESET
| X86DiagID::FeatureMissingUINTR
| X86DiagID::FeatureMissingKL
| X86DiagID::FeatureMissingWIDEKL
| X86DiagID::FeatureMissingCMPCCXADD
| X86DiagID::FeatureMissingRAOINT
| X86DiagID::FeatureMissingAVX_NE_CONVERT
| X86DiagID::FeatureMissingAVX_VNNI
| X86DiagID::FeatureMissingAVX_VNNI_INT8
| X86DiagID::FeatureNeedsX86_64V2
| X86DiagID::FeatureNeedsX86_64V3
| X86DiagID::FeatureNeedsX86_64V4
| X86DiagID::FeatureDeprecated
| X86DiagID::FeatureRemoved
| X86DiagID::FeatureExperimental
| X86DiagID::FeatureConflicting
| X86DiagID::FeatureMissingForCPU
| X86DiagID::FeatureNotAvailableOnCPU
| X86DiagID::FeatureRequires64Bit
| X86DiagID::FeatureRequires32Bit
| X86DiagID::FeatureMismatchedTuning
| X86DiagID::FeatureGenericTuning
| X86DiagID::FeatureSuboptimalTuning => DiagSeverity::Warning,
X86DiagID::ABIStructTooLarge
| X86DiagID::ABIStructPassedInMem
| X86DiagID::ABIStructSplitAcrossRegs
| X86DiagID::ABIReturnTooLarge
| X86DiagID::ABIHiddenPointerReturn
| X86DiagID::ABIParamTooLarge
| X86DiagID::ABITooManyParams
| X86DiagID::ABIMismatchedCallingConv
| X86DiagID::ABIFastcallTooManyArgs
| X86DiagID::ABIVectorcallAlignment
| X86DiagID::ABIVectorcallTypeUnsupported
| X86DiagID::ABIRegcallNotEnoughRegs
| X86DiagID::ABIThiscallNonMember
| X86DiagID::ABIStdCallVarArgs
| X86DiagID::ABICdeclMismatch
| X86DiagID::ABIStackAlignmentViolation
| X86DiagID::ABIRedZoneViolation
| X86DiagID::ABIArgOverlap
| X86DiagID::ABIRegisterClassMismatch
| X86DiagID::ABIHomogeneousAggregate
| X86DiagID::ABIFloatArgsInIntegerReg
| X86DiagID::ABIIntegerArgsInFloatReg
| X86DiagID::ABIX87Return
| X86DiagID::ABIComplexReturn
| X86DiagID::ABISysVClassificationFailed
| X86DiagID::ABIMicrosoftClassificationFailed
| X86DiagID::ABIRegCallClassificationFailed
| X86DiagID::ABIUnclassifiedType
| X86DiagID::ABIMemClassTooMany
| X86DiagID::ABIEmptyStructPass
| X86DiagID::ABIZeroWidthBitfield
| X86DiagID::ABIUnalignedFieldPass
| X86DiagID::ABIPackedStructPass
| X86DiagID::ABIUnionPass
| X86DiagID::ABIBitfieldStraddle => DiagSeverity::Warning,
X86DiagID::ABIUnknownCallingConv | X86DiagID::ABICallingConvNotSupported => {
DiagSeverity::Error
}
X86DiagID::SizeFunctionTooLarge
| X86DiagID::SizeBasicBlockTooLarge
| X86DiagID::SizeAlignmentExcessive
| X86DiagID::SizeNopPaddingExcessive
| X86DiagID::SizeSectionOverflow
| X86DiagID::SizeDisplacementOverflowRelax
| X86DiagID::SizeCallDisplacementError
| X86DiagID::SizeJumpDisplacementError
| X86DiagID::SizeBranchRelaxRequired
| X86DiagID::SizeELFTextOverflow
| X86DiagID::SizeCOFFTextOverflow => DiagSeverity::Error,
X86DiagID::SizeJumpTableTooLarge => DiagSeverity::Warning,
X86DiagID::SizeLoopAlignmentHint
| X86DiagID::SizeFunctionAlignmentHint
| X86DiagID::SizeRelaxationLoop
| X86DiagID::SizeColdSectionSplit
| X86DiagID::SizeUnlikelyBranch
| X86DiagID::SizeHotColdPadding
| X86DiagID::SizeOptNoneHint
| X86DiagID::SizeOptSizeHint
| X86DiagID::SizeMinSizeHint
| X86DiagID::SizeBlockPlacementHint
| X86DiagID::SizeTailDuplicationHint => DiagSeverity::Remark,
X86DiagID::AlignUnalignedAccess
| X86DiagID::AlignUnalignedStackAccess
| X86DiagID::AlignUnalignedLoad
| X86DiagID::AlignUnalignedStore
| X86DiagID::AlignMisalignedAtomics
| X86DiagID::AlignLockPrefixAlign
| X86DiagID::AlignSIMDUnalignedAccess
| X86DiagID::AlignAVXUnalignedAccess
| X86DiagID::AlignAVX512UnalignedAccess
| X86DiagID::AlignDataAlign
| X86DiagID::AlignCodeAlign
| X86DiagID::AlignStackAlign
| X86DiagID::AlignStructAlign
| X86DiagID::AlignCacheLineBoundary
| X86DiagID::AlignPageBoundary => DiagSeverity::Warning,
X86DiagID::AlignFunctionEntryAlign
| X86DiagID::AlignLoopAlign
| X86DiagID::AlignUnalignedBranchTarget
| X86DiagID::AlignMisalignedReturnAddress
| X86DiagID::AlignStackRealignNeeded
| X86DiagID::AlignStackProbeNeeded
| X86DiagID::AlignVariableAlignment
| X86DiagID::AlignNopSledNeeded
| X86DiagID::AlignOverAlignedAlloca
| X86DiagID::AlignUnderAlignedAlloca => DiagSeverity::Remark,
X86DiagID::InlineAsmParseError
| X86DiagID::InlineAsmInvalidInstruction
| X86DiagID::InlineAsmInvalidOperand
| X86DiagID::InlineAsmInvalidConstraint
| X86DiagID::InlineAsmClobberConflict
| X86DiagID::InlineAsmRegisterClobbered
| X86DiagID::InlineAsmTooManyOperands
| X86DiagID::InlineAsmSizeMismatch
| X86DiagID::InlineAsmUnsupportedConstraint
| X86DiagID::InlineAsmImmediateConstraint
| X86DiagID::InlineAsmInvalidTiedOperand
| X86DiagID::InlineAsmInputOutputMismatch
| X86DiagID::InlineAsmGlobalRegister
| X86DiagID::InlineAsmFramePointerClobber
| X86DiagID::InlineAsmStackPointerClobber
| X86DiagID::InlineAsmReservedRegister
| X86DiagID::InlineAsmIPRegisterClobber
| X86DiagID::InlineAsmFlagsRegisterClobber
| X86DiagID::InlineAsmAMXConfigNeeded
| X86DiagID::InlineAsmGotoTooManyLabels
| X86DiagID::InlineAsmGotoIndirectBranch
| X86DiagID::InlineAsmRelocationOverflow
| X86DiagID::InlineAsmAbsoluteAddress
| X86DiagID::InlineAsmSegmentOverride
| X86DiagID::InlineAsmLockPrefixWrong
| X86DiagID::InlineAsmRepPrefixWrong => DiagSeverity::Error,
X86DiagID::InlineAsmMemoryConstraint
| X86DiagID::InlineAsmFloatConstraint
| X86DiagID::InlineAsmMultipleAlternative
| X86DiagID::InlineAsmDuplicateConstraint
| X86DiagID::InlineAsmAVX512MaskOperand
| X86DiagID::InlineAsmAVX512BroadcastOperand
| X86DiagID::InlineAsmAVX512RoundingOperand
| X86DiagID::InlineAsmAVX512SAEOperand
| X86DiagID::InlineAsmAVX512ZeroMasking
| X86DiagID::InlineAsmAMXTileOperand
| X86DiagID::InlineAsmIntelSyntaxWarning
| X86DiagID::InlineAsmATTDirectiveWarning
| X86DiagID::InlineAsmIntelDirectiveWarning
| X86DiagID::InlineAsmSplitOperandType
| X86DiagID::InlineAsmUndefinedSymbol
| X86DiagID::InlineAsmTLSRelocation
| X86DiagID::InlineAsmGOTPCREL
| X86DiagID::InlineAsmPLTRelocation
| X86DiagID::InlineAsmAddressSizeOverride
| X86DiagID::InlineAsmOperandSizeOverride
| X86DiagID::InlineAsmREXPrefixUnused
| X86DiagID::InlineAsmVEXPrefixInvalid
| X86DiagID::InlineAsmEVEXPrefixInvalid => DiagSeverity::Warning,
X86DiagID::InlineAsmGotoLabel => DiagSeverity::Note,
X86DiagID::VectorWidthMismatch
| X86DiagID::VectorTypeMismatch
| X86DiagID::VectorElementCountMismatch
| X86DiagID::VectorShuffleMaskInvalid
| X86DiagID::VectorShuffleMaskOutOfRange
| X86DiagID::VectorInsertIndexOutOfRange
| X86DiagID::VectorExtractIndexOutOfRange
| X86DiagID::VectorGatherScatterAlign
| X86DiagID::VectorMaskOperandMissing
| X86DiagID::VectorMaskTypeMismatch
| X86DiagID::VectorZeroMaskNotSupported
| X86DiagID::VectorMergeMaskNotSupported
| X86DiagID::VectorBroadcastUnsupported
| X86DiagID::VectorBroadcastMemSource
| X86DiagID::VectorBroadcastWidth
| X86DiagID::VectorPermuteUnsupported
| X86DiagID::VectorInterleaveUnsupported
| X86DiagID::VectorDeinterleaveUnsupported
| X86DiagID::VectorGatherUnsupported
| X86DiagID::VectorScatterUnsupported
| X86DiagID::VectorGather4Unsupported
| X86DiagID::VectorScatter4Unsupported
| X86DiagID::VectorCompressUnsupported
| X86DiagID::VectorExpandUnsupported
| X86DiagID::VectorReduceUnsupported
| X86DiagID::VectorHorizontalAddSub
| X86DiagID::VectorDotProductUnsupported
| X86DiagID::VectorFMAUnsupported
| X86DiagID::VectorFP16Unsupported
| X86DiagID::VectorBF16Unsupported
| X86DiagID::VectorINT8Unsupported
| X86DiagID::VectorINT4Unsupported
| X86DiagID::VectorFPUnsupportedForWidth
| X86DiagID::VectorIntegerUnsupportedForWidth
| X86DiagID::VectorConversionRounding
| X86DiagID::VectorConvertOverflow
| X86DiagID::VectorConvertSaturation
| X86DiagID::VectorAbsUnsupported
| X86DiagID::VectorMinMaxUnsupported
| X86DiagID::VectorRoundUnsupported
| X86DiagID::VectorSqrtUnsupported
| X86DiagID::VectorRcpUnsupported
| X86DiagID::VectorRsqrtUnsupported
| X86DiagID::VectorPopcountUnsupported
| X86DiagID::VectorLZCNTUnsupported
| X86DiagID::VectorRotateUnsupported
| X86DiagID::VectorShiftImmOutOfRange
| X86DiagID::VectorShiftAmountMismatch
| X86DiagID::VectorBlendMaskInvalid
| X86DiagID::VectorComparePredicateInvalid
| X86DiagID::VectorSelectConditionInvalid
| X86DiagID::VectorAMXLoadStore
| X86DiagID::VectorAMXTileShape
| X86DiagID::VectorAMXConfig
| X86DiagID::VectorAMXZero
| X86DiagID::VectorAMXTilePair => DiagSeverity::Warning,
X86DiagID::VectorSSEUpgradeHint
| X86DiagID::VectorAVXUpgradeHint
| X86DiagID::VectorAVX512UpgradeHint
| X86DiagID::VectorAVX10UpgradeHint
| X86DiagID::VectorUsePackedHint
| X86DiagID::VectorUseScalarHint
| X86DiagID::VectorUseGatherHint
| X86DiagID::VectorUseScatterHint
| X86DiagID::VectorLoadUnaligned
| X86DiagID::VectorStoreUnaligned
| X86DiagID::VectorLoadNonTemporal
| X86DiagID::VectorStoreNonTemporal => DiagSeverity::Remark,
_ if Self::is_optimization_remark(id) => DiagSeverity::Remark,
X86DiagID::LinkerTLSOverflow
| X86DiagID::LinkerPLTOverflow
| X86DiagID::LinkerThreadLocalModel
| X86DiagID::LinkerTLSLocalExec
| X86DiagID::LinkerTLSInitialExec
| X86DiagID::LinkerTLSLocalDynamic
| X86DiagID::LinkerTLSGlobalDynamic => DiagSeverity::Warning,
_ => DiagSeverity::Note,
}
}
pub fn is_optimization_remark(id: X86DiagID) -> bool {
let raw = id as u32;
raw >= 7000 && raw < 8000
}
pub fn is_error(id: X86DiagID) -> bool {
Self::default_severity(id).is_error()
}
pub fn is_warning(id: X86DiagID) -> bool {
matches!(Self::default_severity(id), DiagSeverity::Warning)
}
pub fn category(id: X86DiagID) -> &'static str {
match id {
_ if (id as u32) < 1000 => "x86-backend",
_ if (id as u32) < 2000 => "x86-target-features",
_ if (id as u32) < 3000 => "x86-abi",
_ if (id as u32) < 4000 => "x86-code-size",
_ if (id as u32) < 5000 => "x86-alignment",
_ if (id as u32) < 6000 => "x86-inline-asm",
_ if (id as u32) < 7000 => "x86-vector",
_ if (id as u32) < 8000 => "x86-optimization",
_ if (id as u32) < 9000 => "x86-linker",
_ => "x86-misc",
}
}
pub fn flag_name(id: X86DiagID) -> &'static str {
match id {
X86DiagID::BackendISelFail => "-Wx86-backend-isel-fail",
X86DiagID::BackendCannotSelect => "-Wx86-backend-cannot-select",
X86DiagID::BackendUnsupportedType => "-Wx86-backend-unsupported-type",
X86DiagID::BackendIllegalType => "-Wx86-backend-illegal-type",
X86DiagID::BackendCannotLower => "-Wx86-backend-cannot-lower",
X86DiagID::BackendCannotLegalize => "-Wx86-backend-cannot-legalize",
X86DiagID::BackendNoPattern => "-Wx86-backend-no-pattern",
X86DiagID::BackendRegallocSpill => "-Wx86-backend-regalloc-spill",
X86DiagID::BackendRegallocFail => "-Wx86-backend-regalloc-fail",
X86DiagID::BackendOutOfRegisters => "-Wx86-backend-out-of-registers",
X86DiagID::BackendPhysRegUnavailable => "-Wx86-backend-physreg-unavailable",
X86DiagID::BackendVirtRegUnmapped => "-Wx86-backend-vreg-unmapped",
X86DiagID::BackendLiveInConflict => "-Wx86-backend-livein-conflict",
X86DiagID::BackendStackSlotTooLarge => "-Wx86-backend-stackslot-too-large",
X86DiagID::BackendFrameTooLarge => "-Wx86-backend-frame-too-large",
X86DiagID::BackendStackRealignLimit => "-Wx86-backend-stack-realign-limit",
X86DiagID::BackendCannotEliminateFrameIndex => {
"-Wx86-backend-cannot-eliminate-frame-index"
}
X86DiagID::BackendFrameOffsetOverflow => "-Wx86-backend-frame-offset-overflow",
X86DiagID::BackendRedZoneViolation => "-Wx86-backend-redzone-violation",
X86DiagID::BackendPrologueEmissionFailed => "-Wx86-backend-prologue-emission-failed",
X86DiagID::BackendEpilogueEmissionFailed => "-Wx86-backend-epilogue-emission-failed",
X86DiagID::BackendEncodingFail => "-Wx86-backend-encoding-fail",
X86DiagID::BackendImmediateTooLarge => "-Wx86-backend-imm-too-large",
X86DiagID::BackendDisplacementOverflow => "-Wx86-backend-disp-overflow",
X86DiagID::BackendAddressModeInvalid => "-Wx86-backend-addr-mode-invalid",
X86DiagID::BackendRexPrefixConflict => "-Wx86-backend-rex-conflict",
X86DiagID::BackendVexEncodingFail => "-Wx86-backend-vex-encoding-fail",
X86DiagID::BackendEvexEncodingFail => "-Wx86-backend-evex-encoding-fail",
X86DiagID::BackendOpcodeNotSupported => "-Wx86-backend-opcode-not-supported",
X86DiagID::BackendRelaxationFail => "-Wx86-backend-relaxation-fail",
X86DiagID::BackendEmissionFail => "-Wx86-backend-emission-fail",
X86DiagID::BackendObjectEmissionFail => "-Wx86-backend-object-emission-fail",
X86DiagID::BackendAsmPrinterFail => "-Wx86-backend-asm-printer-fail",
X86DiagID::BackendDwarfEmissionFail => "-Wx86-backend-dwarf-emission-fail",
X86DiagID::BackendUnwindInfoFail => "-Wx86-backend-unwind-info-fail",
X86DiagID::BackendELFStubFail => "-Wx86-backend-elf-stub-fail",
X86DiagID::BackendCOFFStubFail => "-Wx86-backend-coff-stub-fail",
X86DiagID::BackendMachOStubFail => "-Wx86-backend-macho-stub-fail",
X86DiagID::BackendBranchTargetTooFar => "-Wx86-backend-branch-too-far",
X86DiagID::BackendJumpTableFail => "-Wx86-backend-jump-table-fail",
X86DiagID::BackendIndirectBranchFail => "-Wx86-backend-indirect-branch-fail",
X86DiagID::BackendTailMergeFail => "-Wx86-backend-tail-merge-fail",
X86DiagID::BackendConditionalTailCallFail => "-Wx86-backend-conditional-tail-call-fail",
X86DiagID::BackendUnsupportedIndirectCall => "-Wx86-backend-unsupported-indirect-call",
X86DiagID::BackendScheduleConflict => "-Wx86-backend-schedule-conflict",
X86DiagID::BackendBundleFail => "-Wx86-backend-bundle-fail",
X86DiagID::BackendResourceConflict => "-Wx86-backend-resource-conflict",
X86DiagID::BackendDependencyCycle => "-Wx86-backend-dependency-cycle",
X86DiagID::BackendBlockPlacementFail => "-Wx86-backend-block-placement-fail",
X86DiagID::BackendLayoutConflict => "-Wx86-backend-layout-conflict",
X86DiagID::BackendAlignmentConflict => "-Wx86-backend-alignment-conflict",
X86DiagID::BackendFastISelFail => "-Wx86-backend-fast-isel-fail",
X86DiagID::BackendFastISelUnsupportedType => "-Wx86-backend-fast-isel-unsupported-type",
X86DiagID::BackendFastISelUnsupportedOp => "-Wx86-backend-fast-isel-unsupported-op",
X86DiagID::BackendFastISelNoVreg => "-Wx86-backend-fast-isel-no-vreg",
X86DiagID::BackendGISelFail => "-Wx86-backend-gisel-fail",
X86DiagID::BackendGISelUnsupported => "-Wx86-backend-gisel-unsupported",
X86DiagID::BackendGISelNoLegalizer => "-Wx86-backend-gisel-no-legalizer",
X86DiagID::BackendGISelNoRegBank => "-Wx86-backend-gisel-no-regbank",
X86DiagID::FeatureMissingSSE => "-Wx86-missing-sse",
X86DiagID::FeatureMissingSSE2 => "-Wx86-missing-sse2",
X86DiagID::FeatureMissingSSE3 => "-Wx86-missing-sse3",
X86DiagID::FeatureMissingSSSE3 => "-Wx86-missing-ssse3",
X86DiagID::FeatureMissingSSE41 => "-Wx86-missing-sse4.1",
X86DiagID::FeatureMissingSSE42 => "-Wx86-missing-sse4.2",
X86DiagID::FeatureMissingAVX => "-Wx86-missing-avx",
X86DiagID::FeatureMissingAVX2 => "-Wx86-missing-avx2",
X86DiagID::FeatureMissingAVX512F => "-Wx86-missing-avx512f",
X86DiagID::FeatureMissingAVX512BW => "-Wx86-missing-avx512bw",
X86DiagID::FeatureMissingAVX512DQ => "-Wx86-missing-avx512dq",
X86DiagID::FeatureMissingAVX512VL => "-Wx86-missing-avx512vl",
X86DiagID::FeatureMissingAVX512CD => "-Wx86-missing-avx512cd",
X86DiagID::FeatureMissingAVX512ER => "-Wx86-missing-avx512er",
X86DiagID::FeatureMissingAVX512PF => "-Wx86-missing-avx512pf",
X86DiagID::FeatureMissingAVX512BF16 => "-Wx86-missing-avx512bf16",
X86DiagID::FeatureMissingAVX512FP16 => "-Wx86-missing-avx512fp16",
X86DiagID::FeatureMissingAVX512VBMI => "-Wx86-missing-avx512vbmi",
X86DiagID::FeatureMissingAVX512VBMI2 => "-Wx86-missing-avx512vbmi2",
X86DiagID::FeatureMissingAVX512VNNI => "-Wx86-missing-avx512vnni",
X86DiagID::FeatureMissingAVX512BITALG => "-Wx86-missing-avx512bitalg",
X86DiagID::FeatureMissingAVX512VPOPCNTDQ => "-Wx86-missing-avx512vpopcntdq",
X86DiagID::FeatureMissingAVX5124FMAPS => "-Wx86-missing-avx5124fmaps",
X86DiagID::FeatureMissingAVX5124VNNIW => "-Wx86-missing-avx5124vnniw",
X86DiagID::FeatureMissingAVX512VP2INTERSECT => "-Wx86-missing-avx512vp2intersect",
X86DiagID::FeatureMissingAVX512IFMA => "-Wx86-missing-avx512ifma",
X86DiagID::FeatureMissingAVX10_1_256 => "-Wx86-missing-avx10.1-256",
X86DiagID::FeatureMissingAVX10_1_512 => "-Wx86-missing-avx10.1-512",
X86DiagID::FeatureMissingAVX10_2 => "-Wx86-missing-avx10.2",
X86DiagID::FeatureMissingFMA => "-Wx86-missing-fma",
X86DiagID::FeatureMissingFMA4 => "-Wx86-missing-fma4",
X86DiagID::FeatureMissingF16C => "-Wx86-missing-f16c",
X86DiagID::FeatureMissingXOP => "-Wx86-missing-xop",
X86DiagID::FeatureMissingMMX => "-Wx86-missing-mmx",
X86DiagID::FeatureMissing3DNOW => "-Wx86-missing-3dnow",
X86DiagID::FeatureMissing3DNOWA => "-Wx86-missing-3dnowa",
X86DiagID::FeatureMissingBMI => "-Wx86-missing-bmi",
X86DiagID::FeatureMissingBMI2 => "-Wx86-missing-bmi2",
X86DiagID::FeatureMissingLZCNT => "-Wx86-missing-lzcnt",
X86DiagID::FeatureMissingPOPCNT => "-Wx86-missing-popcnt",
X86DiagID::FeatureMissingTBM => "-Wx86-missing-tbm",
X86DiagID::FeatureMissingAES => "-Wx86-missing-aes",
X86DiagID::FeatureMissingPCLMUL => "-Wx86-missing-pclmul",
X86DiagID::FeatureMissingSHA => "-Wx86-missing-sha",
X86DiagID::FeatureMissingSHA512 => "-Wx86-missing-sha512",
X86DiagID::FeatureMissingSM3 => "-Wx86-missing-sm3",
X86DiagID::FeatureMissingSM4 => "-Wx86-missing-sm4",
X86DiagID::FeatureMissingGFNI => "-Wx86-missing-gfni",
X86DiagID::FeatureMissingVAES => "-Wx86-missing-vaes",
X86DiagID::FeatureMissingVPCLMULQDQ => "-Wx86-missing-vpclmulqdq",
X86DiagID::FeatureMissingRDRAND => "-Wx86-missing-rdrand",
X86DiagID::FeatureMissingRDSEED => "-Wx86-missing-rdseed",
X86DiagID::FeatureMissingADX => "-Wx86-missing-adx",
X86DiagID::FeatureMissingRTM => "-Wx86-missing-rtm",
X86DiagID::FeatureMissingHLE => "-Wx86-missing-hle",
X86DiagID::FeatureMissingSGX => "-Wx86-missing-sgx",
X86DiagID::FeatureMissingCET => "-Wx86-missing-cet",
X86DiagID::FeatureMissingXSAVE => "-Wx86-missing-xsave",
X86DiagID::FeatureMissingXSAVEOPT => "-Wx86-missing-xsaveopt",
X86DiagID::FeatureMissingXSAVEC => "-Wx86-missing-xsavec",
X86DiagID::FeatureMissingXSAVES => "-Wx86-missing-xsaves",
X86DiagID::FeatureMissingFSGSBASE => "-Wx86-missing-fsgsbase",
X86DiagID::FeatureMissingMOVBE => "-Wx86-missing-movbe",
X86DiagID::FeatureMissingMOVDIRI => "-Wx86-missing-movdiri",
X86DiagID::FeatureMissingMOVDIR64B => "-Wx86-missing-movdir64b",
X86DiagID::FeatureMissingENQCMD => "-Wx86-missing-enqcmd",
X86DiagID::FeatureMissingSERIALIZE => "-Wx86-missing-serialize",
X86DiagID::FeatureMissingTSXLDTRK => "-Wx86-missing-tsxldtrk",
X86DiagID::FeatureMissingWAITPKG => "-Wx86-missing-waitpkg",
X86DiagID::FeatureMissingCLDEMOTE => "-Wx86-missing-cldemote",
X86DiagID::FeatureMissingCLFLUSHOPT => "-Wx86-missing-clflushopt",
X86DiagID::FeatureMissingCLWB => "-Wx86-missing-clwb",
X86DiagID::FeatureMissingCLZERO => "-Wx86-missing-clzero",
X86DiagID::FeatureMissingMWAITX => "-Wx86-missing-mwaitx",
X86DiagID::FeatureMissingMONITORX => "-Wx86-missing-monitorx",
X86DiagID::FeatureMissingPKU => "-Wx86-missing-pku",
X86DiagID::FeatureMissingSMAP => "-Wx86-missing-smap",
X86DiagID::FeatureMissingSMEP => "-Wx86-missing-smep",
X86DiagID::FeatureMissingMPX => "-Wx86-missing-mpx",
X86DiagID::FeatureMissingPTWRITE => "-Wx86-missing-ptwrite",
X86DiagID::FeatureMissingINVPCID => "-Wx86-missing-invpcid",
X86DiagID::FeatureMissingPREFETCHWT1 => "-Wx86-missing-prefetchwt1",
X86DiagID::FeatureMissingPREFETCHW => "-Wx86-missing-prefetchw",
X86DiagID::FeatureMissingPREFETCHI => "-Wx86-missing-prefetchi",
X86DiagID::FeatureMissingAMX_BF16 => "-Wx86-missing-amx-bf16",
X86DiagID::FeatureMissingAMX_INT8 => "-Wx86-missing-amx-int8",
X86DiagID::FeatureMissingAMX_TILE => "-Wx86-missing-amx-tile",
X86DiagID::FeatureMissingAMX_FP16 => "-Wx86-missing-amx-fp16",
X86DiagID::FeatureMissingAMX_COMPLEX => "-Wx86-missing-amx-complex",
X86DiagID::FeatureMissingX87 => "-Wx86-missing-x87",
X86DiagID::FeatureMissingCMOV => "-Wx86-missing-cmov",
X86DiagID::FeatureMissingSAHF => "-Wx86-missing-sahf",
X86DiagID::FeatureMissingRDPID => "-Wx86-missing-rdpid",
X86DiagID::FeatureMissingRDPRU => "-Wx86-missing-rdpru",
X86DiagID::FeatureMissingHRESET => "-Wx86-missing-hreset",
X86DiagID::FeatureMissingUINTR => "-Wx86-missing-uintr",
X86DiagID::FeatureMissingKL => "-Wx86-missing-kl",
X86DiagID::FeatureMissingWIDEKL => "-Wx86-missing-widekl",
X86DiagID::FeatureMissingCMPCCXADD => "-Wx86-missing-cmpccxadd",
X86DiagID::FeatureMissingRAOINT => "-Wx86-missing-raoint",
X86DiagID::FeatureMissingAVX_NE_CONVERT => "-Wx86-missing-avx-ne-convert",
X86DiagID::FeatureMissingAVX_VNNI => "-Wx86-missing-avx-vnni",
X86DiagID::FeatureMissingAVX_VNNI_INT8 => "-Wx86-missing-avx-vnni-int8",
X86DiagID::FeatureNeedsX86_64V2 => "-Wx86-needs-x86-64-v2",
X86DiagID::FeatureNeedsX86_64V3 => "-Wx86-needs-x86-64-v3",
X86DiagID::FeatureNeedsX86_64V4 => "-Wx86-needs-x86-64-v4",
X86DiagID::FeatureDeprecated => "-Wx86-deprecated-feature",
X86DiagID::FeatureRemoved => "-Wx86-removed-feature",
X86DiagID::FeatureExperimental => "-Wx86-experimental-feature",
X86DiagID::FeatureConflicting => "-Wx86-conflicting-features",
X86DiagID::FeatureMissingForCPU => "-Wx86-missing-for-cpu",
X86DiagID::FeatureNotAvailableOnCPU => "-Wx86-not-available-on-cpu",
X86DiagID::FeatureRequires64Bit => "-Wx86-requires-64bit",
X86DiagID::FeatureRequires32Bit => "-Wx86-requires-32bit",
X86DiagID::FeatureMismatchedTuning => "-Wx86-mismatched-tuning",
X86DiagID::FeatureGenericTuning => "-Wx86-generic-tuning",
X86DiagID::FeatureSuboptimalTuning => "-Wx86-suboptimal-tuning",
X86DiagID::ABIStructTooLarge => "-Wx86-abi-struct-too-large",
X86DiagID::ABIStructPassedInMem => "-Wx86-abi-struct-passed-in-mem",
X86DiagID::ABIStructSplitAcrossRegs => "-Wx86-abi-struct-split-across-regs",
X86DiagID::ABIReturnTooLarge => "-Wx86-abi-return-too-large",
X86DiagID::ABIHiddenPointerReturn => "-Wx86-abi-hidden-pointer-return",
X86DiagID::ABIParamTooLarge => "-Wx86-abi-param-too-large",
X86DiagID::ABITooManyParams => "-Wx86-abi-too-many-params",
X86DiagID::ABIMismatchedCallingConv => "-Wx86-abi-mismatched-calling-conv",
X86DiagID::ABIUnknownCallingConv => "-Wx86-abi-unknown-calling-conv",
X86DiagID::ABICallingConvNotSupported => "-Wx86-abi-calling-conv-not-supported",
X86DiagID::ABIFastcallTooManyArgs => "-Wx86-abi-fastcall-too-many-args",
X86DiagID::ABIVectorcallAlignment => "-Wx86-abi-vectorcall-alignment",
X86DiagID::ABIVectorcallTypeUnsupported => "-Wx86-abi-vectorcall-type-unsupported",
X86DiagID::ABIRegcallNotEnoughRegs => "-Wx86-abi-regcall-not-enough-regs",
X86DiagID::ABIThiscallNonMember => "-Wx86-abi-thiscall-non-member",
X86DiagID::ABIStdCallVarArgs => "-Wx86-abi-stdcall-varargs",
X86DiagID::ABICdeclMismatch => "-Wx86-abi-cdecl-mismatch",
X86DiagID::ABIStackAlignmentViolation => "-Wx86-abi-stack-alignment-violation",
X86DiagID::ABIRedZoneViolation => "-Wx86-abi-red-zone-violation",
X86DiagID::ABIArgOverlap => "-Wx86-abi-arg-overlap",
X86DiagID::ABIRegisterClassMismatch => "-Wx86-abi-register-class-mismatch",
X86DiagID::ABIHomogeneousAggregate => "-Wx86-abi-homogeneous-aggregate",
X86DiagID::ABIFloatArgsInIntegerReg => "-Wx86-abi-float-args-in-int-reg",
X86DiagID::ABIIntegerArgsInFloatReg => "-Wx86-abi-int-args-in-float-reg",
X86DiagID::ABIX87Return => "-Wx86-abi-x87-return",
X86DiagID::ABIComplexReturn => "-Wx86-abi-complex-return",
X86DiagID::ABISysVClassificationFailed => "-Wx86-abi-sysv-classification-failed",
X86DiagID::ABIMicrosoftClassificationFailed => {
"-Wx86-abi-microsoft-classification-failed"
}
X86DiagID::ABIRegCallClassificationFailed => "-Wx86-abi-regcall-classification-failed",
X86DiagID::ABIUnclassifiedType => "-Wx86-abi-unclassified-type",
X86DiagID::ABIMemClassTooMany => "-Wx86-abi-memclass-too-many",
X86DiagID::ABIEmptyStructPass => "-Wx86-abi-empty-struct-pass",
X86DiagID::ABIZeroWidthBitfield => "-Wx86-abi-zero-width-bitfield",
X86DiagID::ABIUnalignedFieldPass => "-Wx86-abi-unaligned-field-pass",
X86DiagID::ABIPackedStructPass => "-Wx86-abi-packed-struct-pass",
X86DiagID::ABIUnionPass => "-Wx86-abi-union-pass",
X86DiagID::ABIBitfieldStraddle => "-Wx86-abi-bitfield-straddle",
X86DiagID::SizeFunctionTooLarge => "-Wx86-size-function-too-large",
X86DiagID::SizeBasicBlockTooLarge => "-Wx86-size-basic-block-too-large",
X86DiagID::SizeAlignmentExcessive => "-Wx86-size-alignment-excessive",
X86DiagID::SizeNopPaddingExcessive => "-Wx86-size-nop-padding-excessive",
X86DiagID::SizeJumpTableTooLarge => "-Wx86-size-jump-table-too-large",
X86DiagID::SizeELFTextOverflow => "-Wx86-size-elf-text-overflow",
X86DiagID::SizeCOFFTextOverflow => "-Wx86-size-coff-text-overflow",
X86DiagID::SizeSectionOverflow => "-Wx86-size-section-overflow",
X86DiagID::SizeDisplacementOverflowRelax => "-Wx86-size-disp-overflow-relax",
X86DiagID::SizeCallDisplacementError => "-Wx86-size-call-disp-error",
X86DiagID::SizeJumpDisplacementError => "-Wx86-size-jump-disp-error",
X86DiagID::SizeLoopAlignmentHint => "-Rpass-analysis=x86-loop-align",
X86DiagID::SizeFunctionAlignmentHint => "-Rpass-analysis=x86-func-align",
X86DiagID::SizeBranchRelaxRequired => "-Wx86-size-branch-relax-required",
X86DiagID::SizeRelaxationLoop => "-Rpass-analysis=x86-relaxation",
X86DiagID::SizeColdSectionSplit => "-Rpass=x86-cold-section-split",
X86DiagID::SizeUnlikelyBranch => "-Rpass-analysis=x86-unlikely-branch",
X86DiagID::SizeHotColdPadding => "-Rpass-analysis=x86-hot-cold-padding",
X86DiagID::SizeOptNoneHint => "-Rpass-analysis=x86-optnone",
X86DiagID::SizeOptSizeHint => "-Rpass-analysis=x86-optsize",
X86DiagID::SizeMinSizeHint => "-Rpass-analysis=x86-minsize",
X86DiagID::SizeBlockPlacementHint => "-Rpass-analysis=x86-block-placement",
X86DiagID::SizeTailDuplicationHint => "-Rpass-analysis=x86-tail-dup",
X86DiagID::AlignUnalignedAccess => "-Wx86-align-unaligned-access",
X86DiagID::AlignUnalignedStackAccess => "-Wx86-align-unaligned-stack-access",
X86DiagID::AlignUnalignedLoad => "-Wx86-align-unaligned-load",
X86DiagID::AlignUnalignedStore => "-Wx86-align-unaligned-store",
X86DiagID::AlignMisalignedAtomics => "-Wx86-align-misaligned-atomics",
X86DiagID::AlignLockPrefixAlign => "-Wx86-align-lock-prefix-align",
X86DiagID::AlignSIMDUnalignedAccess => "-Wx86-align-simd-unaligned-access",
X86DiagID::AlignAVXUnalignedAccess => "-Wx86-align-avx-unaligned-access",
X86DiagID::AlignAVX512UnalignedAccess => "-Wx86-align-avx512-unaligned-access",
X86DiagID::AlignDataAlign => "-Wx86-align-data-align",
X86DiagID::AlignCodeAlign => "-Wx86-align-code-align",
X86DiagID::AlignStackAlign => "-Wx86-align-stack-align",
X86DiagID::AlignStructAlign => "-Wx86-align-struct-align",
X86DiagID::AlignCacheLineBoundary => "-Wx86-align-cache-line-boundary",
X86DiagID::AlignPageBoundary => "-Wx86-align-page-boundary",
X86DiagID::AlignFunctionEntryAlign => "-Rpass-analysis=x86-function-entry-align",
X86DiagID::AlignLoopAlign => "-Rpass-analysis=x86-loop-align",
X86DiagID::AlignUnalignedBranchTarget => "-Rpass-analysis=x86-unaligned-branch",
X86DiagID::AlignMisalignedReturnAddress => "-Rpass-analysis=x86-misaligned-ret",
X86DiagID::AlignStackRealignNeeded => "-Rpass-analysis=x86-stack-realign",
X86DiagID::AlignStackProbeNeeded => "-Rpass-analysis=x86-stack-probe",
X86DiagID::AlignVariableAlignment => "-Rpass-analysis=x86-var-align",
X86DiagID::AlignNopSledNeeded => "-Rpass-analysis=x86-nop-sled",
X86DiagID::AlignOverAlignedAlloca => "-Rpass-analysis=x86-overaligned-alloca",
X86DiagID::AlignUnderAlignedAlloca => "-Rpass-analysis=x86-underaligned-alloca",
X86DiagID::InlineAsmParseError => "-Wx86-inline-asm-parse-error",
X86DiagID::InlineAsmInvalidInstruction => "-Wx86-inline-asm-invalid-instruction",
X86DiagID::InlineAsmInvalidOperand => "-Wx86-inline-asm-invalid-operand",
X86DiagID::InlineAsmInvalidConstraint => "-Wx86-inline-asm-invalid-constraint",
X86DiagID::InlineAsmClobberConflict => "-Wx86-inline-asm-clobber-conflict",
X86DiagID::InlineAsmRegisterClobbered => "-Wx86-inline-asm-register-clobbered",
X86DiagID::InlineAsmTooManyOperands => "-Wx86-inline-asm-too-many-operands",
X86DiagID::InlineAsmSizeMismatch => "-Wx86-inline-asm-size-mismatch",
X86DiagID::InlineAsmUnsupportedConstraint => "-Wx86-inline-asm-unsupported-constraint",
X86DiagID::InlineAsmImmediateConstraint => "-Wx86-inline-asm-imm-constraint",
X86DiagID::InlineAsmMemoryConstraint => "-Wx86-inline-asm-memory-constraint",
X86DiagID::InlineAsmFloatConstraint => "-Wx86-inline-asm-float-constraint",
X86DiagID::InlineAsmMultipleAlternative => "-Wx86-inline-asm-multiple-alternative",
X86DiagID::InlineAsmInvalidTiedOperand => "-Wx86-inline-asm-invalid-tied-operand",
X86DiagID::InlineAsmDuplicateConstraint => "-Wx86-inline-asm-duplicate-constraint",
X86DiagID::InlineAsmInputOutputMismatch => "-Wx86-inline-asm-input-output-mismatch",
X86DiagID::InlineAsmGlobalRegister => "-Wx86-inline-asm-global-register",
X86DiagID::InlineAsmFramePointerClobber => "-Wx86-inline-asm-frame-pointer-clobber",
X86DiagID::InlineAsmStackPointerClobber => "-Wx86-inline-asm-stack-pointer-clobber",
X86DiagID::InlineAsmReservedRegister => "-Wx86-inline-asm-reserved-register",
X86DiagID::InlineAsmIPRegisterClobber => "-Wx86-inline-asm-ip-register-clobber",
X86DiagID::InlineAsmFlagsRegisterClobber => "-Wx86-inline-asm-flags-register-clobber",
X86DiagID::InlineAsmAVX512MaskOperand => "-Wx86-inline-asm-avx512-mask-operand",
X86DiagID::InlineAsmAVX512BroadcastOperand => {
"-Wx86-inline-asm-avx512-broadcast-operand"
}
X86DiagID::InlineAsmAVX512RoundingOperand => "-Wx86-inline-asm-avx512-rounding-operand",
X86DiagID::InlineAsmAVX512SAEOperand => "-Wx86-inline-asm-avx512-sae-operand",
X86DiagID::InlineAsmAVX512ZeroMasking => "-Wx86-inline-asm-avx512-zero-masking",
X86DiagID::InlineAsmAMXTileOperand => "-Wx86-inline-asm-amx-tile-operand",
X86DiagID::InlineAsmAMXConfigNeeded => "-Wx86-inline-asm-amx-config-needed",
X86DiagID::InlineAsmGotoLabel => "-Wx86-inline-asm-goto-label",
X86DiagID::InlineAsmGotoTooManyLabels => "-Wx86-inline-asm-goto-too-many-labels",
X86DiagID::InlineAsmGotoIndirectBranch => "-Wx86-inline-asm-goto-indirect-branch",
X86DiagID::InlineAsmIntelSyntaxWarning => "-Wx86-inline-asm-intel-syntax",
X86DiagID::InlineAsmATTDirectiveWarning => "-Wx86-inline-asm-att-directive",
X86DiagID::InlineAsmIntelDirectiveWarning => "-Wx86-inline-asm-intel-directive",
X86DiagID::InlineAsmSplitOperandType => "-Wx86-inline-asm-split-operand-type",
X86DiagID::InlineAsmUndefinedSymbol => "-Wx86-inline-asm-undefined-symbol",
X86DiagID::InlineAsmRelocationOverflow => "-Wx86-inline-asm-relocation-overflow",
X86DiagID::InlineAsmAbsoluteAddress => "-Wx86-inline-asm-absolute-address",
X86DiagID::InlineAsmTLSRelocation => "-Wx86-inline-asm-tls-relocation",
X86DiagID::InlineAsmGOTPCREL => "-Wx86-inline-asm-gotpcrel",
X86DiagID::InlineAsmPLTRelocation => "-Wx86-inline-asm-plt-relocation",
X86DiagID::InlineAsmSegmentOverride => "-Wx86-inline-asm-segment-override",
X86DiagID::InlineAsmAddressSizeOverride => "-Wx86-inline-asm-address-size-override",
X86DiagID::InlineAsmOperandSizeOverride => "-Wx86-inline-asm-operand-size-override",
X86DiagID::InlineAsmREXPrefixUnused => "-Wx86-inline-asm-rex-prefix-unused",
X86DiagID::InlineAsmLockPrefixWrong => "-Wx86-inline-asm-lock-prefix-wrong",
X86DiagID::InlineAsmRepPrefixWrong => "-Wx86-inline-asm-rep-prefix-wrong",
X86DiagID::InlineAsmVEXPrefixInvalid => "-Wx86-inline-asm-vex-prefix-invalid",
X86DiagID::InlineAsmEVEXPrefixInvalid => "-Wx86-inline-asm-evex-prefix-invalid",
X86DiagID::VectorWidthMismatch => "-Wx86-vector-width-mismatch",
X86DiagID::VectorTypeMismatch => "-Wx86-vector-type-mismatch",
X86DiagID::VectorElementCountMismatch => "-Wx86-vector-element-count-mismatch",
X86DiagID::VectorShuffleMaskInvalid => "-Wx86-vector-shuffle-mask-invalid",
X86DiagID::VectorShuffleMaskOutOfRange => "-Wx86-vector-shuffle-mask-out-of-range",
X86DiagID::VectorInsertIndexOutOfRange => "-Wx86-vector-insert-index-out-of-range",
X86DiagID::VectorExtractIndexOutOfRange => "-Wx86-vector-extract-index-out-of-range",
X86DiagID::VectorGatherScatterAlign => "-Wx86-vector-gather-scatter-align",
X86DiagID::VectorMaskOperandMissing => "-Wx86-vector-mask-operand-missing",
X86DiagID::VectorMaskTypeMismatch => "-Wx86-vector-mask-type-mismatch",
X86DiagID::VectorZeroMaskNotSupported => "-Wx86-vector-zero-mask-not-supported",
X86DiagID::VectorMergeMaskNotSupported => "-Wx86-vector-merge-mask-not-supported",
X86DiagID::VectorBroadcastUnsupported => "-Wx86-vector-broadcast-unsupported",
X86DiagID::VectorBroadcastMemSource => "-Wx86-vector-broadcast-mem-source",
X86DiagID::VectorBroadcastWidth => "-Wx86-vector-broadcast-width",
X86DiagID::VectorPermuteUnsupported => "-Wx86-vector-permute-unsupported",
X86DiagID::VectorInterleaveUnsupported => "-Wx86-vector-interleave-unsupported",
X86DiagID::VectorDeinterleaveUnsupported => "-Wx86-vector-deinterleave-unsupported",
X86DiagID::VectorLoadUnaligned => "-Rpass-analysis=x86-vector-load-unaligned",
X86DiagID::VectorStoreUnaligned => "-Rpass-analysis=x86-vector-store-unaligned",
X86DiagID::VectorLoadNonTemporal => "-Rpass-analysis=x86-vector-load-nt",
X86DiagID::VectorStoreNonTemporal => "-Rpass-analysis=x86-vector-store-nt",
X86DiagID::VectorGatherUnsupported => "-Wx86-vector-gather-unsupported",
X86DiagID::VectorScatterUnsupported => "-Wx86-vector-scatter-unsupported",
X86DiagID::VectorGather4Unsupported => "-Wx86-vector-gather4-unsupported",
X86DiagID::VectorScatter4Unsupported => "-Wx86-vector-scatter4-unsupported",
X86DiagID::VectorCompressUnsupported => "-Wx86-vector-compress-unsupported",
X86DiagID::VectorExpandUnsupported => "-Wx86-vector-expand-unsupported",
X86DiagID::VectorReduceUnsupported => "-Wx86-vector-reduce-unsupported",
X86DiagID::VectorHorizontalAddSub => "-Wx86-vector-horizontal-add-sub",
X86DiagID::VectorDotProductUnsupported => "-Wx86-vector-dot-product-unsupported",
X86DiagID::VectorFMAUnsupported => "-Wx86-vector-fma-unsupported",
X86DiagID::VectorFP16Unsupported => "-Wx86-vector-fp16-unsupported",
X86DiagID::VectorBF16Unsupported => "-Wx86-vector-bf16-unsupported",
X86DiagID::VectorINT8Unsupported => "-Wx86-vector-int8-unsupported",
X86DiagID::VectorINT4Unsupported => "-Wx86-vector-int4-unsupported",
X86DiagID::VectorFPUnsupportedForWidth => "-Wx86-vector-fp-unsupported-for-width",
X86DiagID::VectorIntegerUnsupportedForWidth => "-Wx86-vector-int-unsupported-for-width",
X86DiagID::VectorConversionRounding => "-Wx86-vector-conversion-rounding",
X86DiagID::VectorConvertOverflow => "-Wx86-vector-convert-overflow",
X86DiagID::VectorConvertSaturation => "-Wx86-vector-convert-saturation",
X86DiagID::VectorAbsUnsupported => "-Wx86-vector-abs-unsupported",
X86DiagID::VectorMinMaxUnsupported => "-Wx86-vector-minmax-unsupported",
X86DiagID::VectorRoundUnsupported => "-Wx86-vector-round-unsupported",
X86DiagID::VectorSqrtUnsupported => "-Wx86-vector-sqrt-unsupported",
X86DiagID::VectorRcpUnsupported => "-Wx86-vector-rcp-unsupported",
X86DiagID::VectorRsqrtUnsupported => "-Wx86-vector-rsqrt-unsupported",
X86DiagID::VectorPopcountUnsupported => "-Wx86-vector-popcount-unsupported",
X86DiagID::VectorLZCNTUnsupported => "-Wx86-vector-lzcnt-unsupported",
X86DiagID::VectorRotateUnsupported => "-Wx86-vector-rotate-unsupported",
X86DiagID::VectorShiftImmOutOfRange => "-Wx86-vector-shift-imm-out-of-range",
X86DiagID::VectorShiftAmountMismatch => "-Wx86-vector-shift-amount-mismatch",
X86DiagID::VectorBlendMaskInvalid => "-Wx86-vector-blend-mask-invalid",
X86DiagID::VectorComparePredicateInvalid => "-Wx86-vector-compare-predicate-invalid",
X86DiagID::VectorSelectConditionInvalid => "-Wx86-vector-select-condition-invalid",
X86DiagID::VectorAMXLoadStore => "-Wx86-vector-amx-load-store",
X86DiagID::VectorAMXTileShape => "-Wx86-vector-amx-tile-shape",
X86DiagID::VectorAMXConfig => "-Wx86-vector-amx-config",
X86DiagID::VectorAMXZero => "-Wx86-vector-amx-zero",
X86DiagID::VectorAMXTilePair => "-Wx86-vector-amx-tile-pair",
X86DiagID::VectorSSEUpgradeHint => "-Rpass-analysis=x86-sse-upgrade-hint",
X86DiagID::VectorAVXUpgradeHint => "-Rpass-analysis=x86-avx-upgrade-hint",
X86DiagID::VectorAVX512UpgradeHint => "-Rpass-analysis=x86-avx512-upgrade-hint",
X86DiagID::VectorAVX10UpgradeHint => "-Rpass-analysis=x86-avx10-upgrade-hint",
X86DiagID::VectorUsePackedHint => "-Rpass-analysis=x86-use-packed-hint",
X86DiagID::VectorUseScalarHint => "-Rpass-analysis=x86-use-scalar-hint",
X86DiagID::VectorUseGatherHint => "-Rpass-analysis=x86-use-gather-hint",
X86DiagID::VectorUseScatterHint => "-Rpass-analysis=x86-use-scatter-hint",
X86DiagID::OptX86ISelSuccess => "-Rpass=x86-isel",
X86DiagID::OptX86ISelFailure => "-Rpass-missed=x86-isel",
X86DiagID::OptX86PeepholeApplied => "-Rpass=x86-peephole",
X86DiagID::OptX86PeepholeSkipped => "-Rpass-missed=x86-peephole",
X86DiagID::OptX86MacroFusion => "-Rpass=x86-macro-fusion",
X86DiagID::OptX86MicroFusion => "-Rpass=x86-micro-fusion",
X86DiagID::OptX86NopInsertion => "-Rpass=x86-nop-insertion",
X86DiagID::OptX86PrefixOptimization => "-Rpass=x86-prefix-opt",
X86DiagID::OptX86LEAUsesAG => "-Rpass=x86-lea-uses-ag",
X86DiagID::OptX86LEAUsesLEA => "-Rpass=x86-lea-uses-lea",
X86DiagID::OptX86CMOVConversion => "-Rpass=x86-cmov-conversion",
X86DiagID::OptX86SETCCConversion => "-Rpass=x86-setcc-conversion",
X86DiagID::OptX86BranchAvoidance => "-Rpass=x86-branch-avoidance",
X86DiagID::OptX86FlagCopyEliminated => "-Rpass=x86-flag-copy-eliminated",
X86DiagID::OptX86ConditionalMove => "-Rpass=x86-conditional-move",
X86DiagID::OptX86LoadFoldIntoInstr => "-Rpass=x86-load-fold",
X86DiagID::OptX86StoreFoldIntoInstr => "-Rpass=x86-store-fold",
X86DiagID::OptX86ImmediateFold => "-Rpass=x86-imm-fold",
X86DiagID::OptX86AddressFold => "-Rpass=x86-addr-fold",
X86DiagID::OptX86ConstantPoolFold => "-Rpass=x86-constpool-fold",
X86DiagID::OptX86TwoAddressPass => "-Rpass=x86-two-address",
X86DiagID::OptX86FixupBWInst => "-Rpass=x86-fixup-bwinst",
X86DiagID::OptX86FixupLEA => "-Rpass=x86-fixup-lea",
X86DiagID::OptX86AvoidStoreForwarding => "-Rpass=x86-avoid-store-forwarding",
X86DiagID::OptX86AvoidPartialRegStall => "-Rpass=x86-avoid-partial-reg-stall",
X86DiagID::OptX86AvoidPartialFlagStall => "-Rpass=x86-avoid-partial-flag-stall",
X86DiagID::OptX86DomainCrossing => "-Rpass=x86-domain-crossing",
X86DiagID::OptX86VZeroupperInserted => "-Rpass=x86-vzeroupper",
X86DiagID::OptX86VZeroupperNotNeeded => "-Rpass=x86-vzeroupper-not-needed",
X86DiagID::OptX86TileConfigInserted => "-Rpass=x86-tile-config",
X86DiagID::OptX86X87Stackify => "-Rpass=x86-x87-stackify",
X86DiagID::OptX86CallFrameOptimization => "-Rpass=x86-call-frame-opt",
X86DiagID::OptX86StackColoring => "-Rpass=x86-stack-coloring",
X86DiagID::OptX86ShrinkWrapping => "-Rpass=x86-shrink-wrapping",
X86DiagID::OptX86TailDuplicate => "-Rpass=x86-tail-duplicate",
X86DiagID::OptX86TailMerge => "-Rpass=x86-tail-merge",
X86DiagID::OptX86MachineLICM => "-Rpass=x86-machine-licm",
X86DiagID::OptX86MachineCSE => "-Rpass=x86-machine-cse",
X86DiagID::OptX86MachineSink => "-Rpass=x86-machine-sink",
X86DiagID::OptX86LoopAlignment => "-Rpass=x86-loop-alignment",
X86DiagID::OptX86BranchFolding => "-Rpass=x86-branch-folding",
X86DiagID::OptX86IfConversion => "-Rpass=x86-if-conversion",
X86DiagID::OptX86MachineBlockPlacement => "-Rpass=x86-block-placement",
X86DiagID::OptX86EarlyIfConversion => "-Rpass=x86-early-if-conversion",
X86DiagID::OptX86SpeculativeLoadHardening => "-Rpass=x86-speculative-load-hardening",
X86DiagID::OptX86IndirectBranchTracking => "-Rpass=x86-indirect-branch-tracking",
X86DiagID::OptX86Scheduler => "-Rpass=x86-scheduler",
X86DiagID::OptX86PostRAScheduler => "-Rpass=x86-postra-scheduler",
X86DiagID::OptX86PreRAScheduler => "-Rpass=x86-prera-scheduler",
X86DiagID::OptX86MachinePipeliner => "-Rpass=x86-machine-pipeliner",
X86DiagID::OptX86RegisterCoalescing => "-Rpass=x86-register-coalescing",
X86DiagID::OptX86VirtualRegisterRewrite => "-Rpass=x86-vreg-rewrite",
X86DiagID::OptX86LiveRangeShrink => "-Rpass=x86-live-range-shrink",
X86DiagID::OptX86DeadMachineInstructionElim => "-Rpass=x86-dead-mi-elim",
X86DiagID::OptX86PrologEpilogInsertion => "-Rpass=x86-prolog-epilog",
X86DiagID::OptX86FrameLowering => "-Rpass=x86-frame-lowering",
X86DiagID::OptX86RedZone => "-Rpass=x86-red-zone",
X86DiagID::OptX86ShadowStack => "-Rpass=x86-shadow-stack",
X86DiagID::OptX86PatchableFunction => "-Rpass=x86-patchable-function",
X86DiagID::OptX86FunctionSections => "-Rpass=x86-function-sections",
X86DiagID::OptX86DataSections => "-Rpass=x86-data-sections",
X86DiagID::OptX86NoOmitFramePointer => "-Rpass=x86-no-omit-frame-pointer",
X86DiagID::OptX86OmitFramePointer => "-Rpass=x86-omit-frame-pointer",
X86DiagID::OptX86HotColdSplit => "-Rpass=x86-hot-cold-split",
X86DiagID::LinkerRelocationOverflow => "-Wx86-linker-relocation-overflow",
X86DiagID::LinkerGOTOverflow => "-Wx86-linker-got-overflow",
X86DiagID::LinkerPLTOverflow => "-Wx86-linker-plt-overflow",
X86DiagID::LinkerTLSOverflow => "-Wx86-linker-tls-overflow",
X86DiagID::LinkerUnresolvedSymbol => "-Wx86-linker-unresolved-symbol",
X86DiagID::LinkerSectionMismatch => "-Wx86-linker-section-mismatch",
X86DiagID::LinkerTrampolineNeeded => "-Wx86-linker-trampoline-needed",
X86DiagID::LinkerRelaxationNeeded => "-Wx86-linker-relaxation-needed",
X86DiagID::LinkerThreadLocalModel => "-Wx86-linker-tls-model",
X86DiagID::LinkerTLSLocalExec => "-Wx86-linker-tls-local-exec",
X86DiagID::LinkerTLSInitialExec => "-Wx86-linker-tls-initial-exec",
X86DiagID::LinkerTLSLocalDynamic => "-Wx86-linker-tls-local-dynamic",
X86DiagID::LinkerTLSGlobalDynamic => "-Wx86-linker-tls-global-dynamic",
X86DiagID::MiscStackProbe => "-Wx86-misc-stack-probe",
X86DiagID::MiscAllocaProbe => "-Wx86-misc-alloca-probe",
X86DiagID::MiscVLAProbe => "-Wx86-misc-vla-probe",
X86DiagID::MiscSegmentedStack => "-Wx86-misc-segmented-stack",
X86DiagID::MiscSplitStack => "-Wx86-misc-split-stack",
X86DiagID::MiscXRayInstrumentation => "-Wx86-misc-xray",
X86DiagID::MiscCFIInstruction => "-Wx86-misc-cfi",
X86DiagID::MiscUnwindOpcode => "-Wx86-misc-unwind-opcode",
X86DiagID::MiscSEHUnwind => "-Wx86-misc-seh-unwind",
X86DiagID::MiscCETEndBranch => "-Wx86-misc-cet-endbranch",
X86DiagID::MiscShadowCallStack => "-Wx86-misc-shadow-call-stack",
X86DiagID::MiscSafeStack => "-Wx86-misc-safe-stack",
X86DiagID::MiscControlFlowGuard => "-Wx86-misc-control-flow-guard",
X86DiagID::MiscKCFI => "-Wx86-misc-kcfi",
X86DiagID::MiscFineIBT => "-Wx86-misc-fineibt",
X86DiagID::MiscMemoryTagging => "-Wx86-misc-memory-tagging",
X86DiagID::MiscHardwareEnforcedSP => "-Wx86-misc-hw-enforced-sp",
X86DiagID::MiscZeroCallUsedRegs => "-Wx86-misc-zero-call-used-regs",
X86DiagID::MiscFEntryInsertion => "-Wx86-misc-fentry-insertion",
X86DiagID::MiscDirectEmission => "-Wx86-misc-direct-emission",
X86DiagID::MiscDelaySlotFill => "-Wx86-misc-delay-slot-fill",
X86DiagID::MiscConstantIsland => "-Wx86-misc-constant-island",
_ => "-Wx86-unknown",
}
}
pub fn message_for(id: X86DiagID) -> &'static str {
match id {
X86DiagID::BackendISelFail => "instruction selection failed for '{}' in function '{}'",
X86DiagID::BackendCannotSelect => "cannot select: {} (node: {}) in function '{}'",
X86DiagID::BackendUnsupportedType => "unsupported type '{}' in instruction selection for function '{}'",
X86DiagID::BackendIllegalType => "illegal type '{}' encountered during legalization",
X86DiagID::BackendCannotLower => "cannot lower operation '{}' to target machine code",
X86DiagID::BackendCannotLegalize => "cannot legalize operation '{}' for X86 target",
X86DiagID::BackendNoPattern => "no matching pattern found for instruction '{}'",
X86DiagID::BackendRegallocSpill => "register allocator spilled virtual register vreg{} in function '{}'",
X86DiagID::BackendRegallocFail => "register allocation failed: unable to find a valid assignment for function '{}'",
X86DiagID::BackendOutOfRegisters => "ran out of registers during register allocation for function '{}': need {} but only {} available",
X86DiagID::BackendPhysRegUnavailable => "physical register {} is unavailable for allocation in function '{}'",
X86DiagID::BackendVirtRegUnmapped => "virtual register vreg{} was never mapped to a physical register in '{}'",
X86DiagID::BackendLiveInConflict => "live-in register conflict at basic block '{}': register {} already assigned",
X86DiagID::BackendStackSlotTooLarge => "stack slot size {} exceeds maximum supported size {}",
X86DiagID::BackendFrameTooLarge => "frame size {} exceeds maximum of {} bytes for function '{}'",
X86DiagID::BackendStackRealignLimit => "stack realignment requires {} bytes but remaining stack is only {} bytes",
X86DiagID::BackendCannotEliminateFrameIndex => "cannot eliminate frame index {}: target does not support this address mode",
X86DiagID::BackendFrameOffsetOverflow => "frame offset {} exceeds 32-bit signed displacement limit",
X86DiagID::BackendRedZoneViolation => "access below the stack pointer in function '{}' may overwrite the red zone",
X86DiagID::BackendPrologueEmissionFailed => "failed to emit prologue for function '{}'",
X86DiagID::BackendEpilogueEmissionFailed => "failed to emit epilogue for function '{}'",
X86DiagID::BackendEncodingFail => "failed to encode instruction '{}': {}",
X86DiagID::BackendImmediateTooLarge => "immediate value {} is too large for the operand field (max {})",
X86DiagID::BackendDisplacementOverflow => "displacement {} exceeds the maximum relative offset of {} bytes",
X86DiagID::BackendAddressModeInvalid => "invalid addressing mode: {}",
X86DiagID::BackendRexPrefixConflict => "REX prefix conflicts with register encoding for instruction '{}'",
X86DiagID::BackendVexEncodingFail => "VEX encoding failed for instruction '{}': invalid operand combination",
X86DiagID::BackendEvexEncodingFail => "EVEX encoding failed for instruction '{}': invalid mask/rounding combination",
X86DiagID::BackendOpcodeNotSupported => "opcode '{}' is not supported on this target CPU",
X86DiagID::BackendRelaxationFail => "branch relaxation failed for function '{}': cannot fit branches in available encoding space",
X86DiagID::BackendEmissionFail => "code emission failed: {}",
X86DiagID::BackendObjectEmissionFail => "object file emission failed: {}",
X86DiagID::BackendAsmPrinterFail => "assembly printer failed: {}",
X86DiagID::BackendDwarfEmissionFail => "DWARF debug information emission failed: {}",
X86DiagID::BackendUnwindInfoFail => "unwind information emission failed for function '{}'",
X86DiagID::BackendELFStubFail => "ELF stub emission failed for symbol '{}'",
X86DiagID::BackendCOFFStubFail => "COFF stub emission failed for symbol '{}'",
X86DiagID::BackendMachOStubFail => "Mach-O stub emission failed for symbol '{}'",
X86DiagID::BackendBranchTargetTooFar => "branch target at offset {} is too far: requires {} bytes but only {} bytes available",
X86DiagID::BackendJumpTableFail => "failed to generate jump table for switch in function '{}'",
X86DiagID::BackendIndirectBranchFail => "failed to resolve indirect branch target in function '{}'",
X86DiagID::BackendTailMergeFail => "tail merge failed for blocks {} and {}: incompatible epilogues",
X86DiagID::BackendConditionalTailCallFail => "tail call from function '{}' to '{}' cannot be converted to unconditional branch",
X86DiagID::BackendUnsupportedIndirectCall => "indirect call not supported for this target configuration",
X86DiagID::BackendScheduleConflict => "instruction scheduling conflict: resource '{}' over-subscribed at cycle {}",
X86DiagID::BackendBundleFail => "failed to bundle instructions in function '{}': {}",
X86DiagID::BackendResourceConflict => "microarchitectural resource conflict: '{}' and '{}' cannot be co-issued",
X86DiagID::BackendDependencyCycle => "instruction dependency cycle detected in function '{}'",
X86DiagID::BackendBlockPlacementFail => "failed to compute optimal block placement for function '{}'",
X86DiagID::BackendLayoutConflict => "function layout conflict: cannot satisfy both alignment and placement constraints",
X86DiagID::BackendAlignmentConflict => "alignment conflict: requested alignment {} not compatible with existing alignment {}",
X86DiagID::BackendFastISelFail => "fast instruction selection failed for '{}': falling back to SelectionDAG",
X86DiagID::BackendFastISelUnsupportedType => "fast instruction selection does not support type '{}'",
X86DiagID::BackendFastISelUnsupportedOp => "fast instruction selection does not support operation '{}'",
X86DiagID::BackendFastISelNoVreg => "fast instruction selection could not create virtual register for value {}",
X86DiagID::BackendGISelFail => "global instruction selection failed for function '{}': {}",
X86DiagID::BackendGISelUnsupported => "global instruction selection is not supported for this target",
X86DiagID::BackendGISelNoLegalizer => "no legalizer available for generic instruction '{}'",
X86DiagID::BackendGISelNoRegBank => "no register bank assigned for virtual register vreg{}",
X86DiagID::FeatureMissingSSE => "SSE vector instructions are required but not enabled; use -msse",
X86DiagID::FeatureMissingSSE2 => "SSE2 vector instructions are required but not enabled; use -msse2",
X86DiagID::FeatureMissingSSE3 => "SSE3 instructions are required but not enabled; use -msse3",
X86DiagID::FeatureMissingSSSE3 => "SSSE3 instructions are required but not enabled; use -mssse3",
X86DiagID::FeatureMissingSSE41 => "SSE4.1 instructions are required but not enabled; use -msse4.1",
X86DiagID::FeatureMissingSSE42 => "SSE4.2 instructions are required but not enabled; use -msse4.2",
X86DiagID::FeatureMissingAVX => "AVX instructions are required but not enabled; use -mavx",
X86DiagID::FeatureMissingAVX2 => "AVX2 instructions are required but not enabled; use -mavx2",
X86DiagID::FeatureMissingAVX512F => "AVX-512 Foundation instructions are required but not enabled; use -mavx512f",
X86DiagID::FeatureMissingAVX512BW => "AVX-512 Byte/Word instructions are required but not enabled; use -mavx512bw",
X86DiagID::FeatureMissingAVX512DQ => "AVX-512 Doubleword/Quadword instructions are required but not enabled; use -mavx512dq",
X86DiagID::FeatureMissingAVX512VL => "AVX-512 Vector Length extensions are required but not enabled; use -mavx512vl",
X86DiagID::FeatureMissingAVX512CD => "AVX-512 Conflict Detection instructions are required but not enabled; use -mavx512cd",
X86DiagID::FeatureMissingAVX512ER => "AVX-512 Exponential & Reciprocal instructions are required but not enabled; use -mavx512er",
X86DiagID::FeatureMissingAVX512PF => "AVX-512 Prefetch instructions are required but not enabled; use -mavx512pf",
X86DiagID::FeatureMissingAVX512BF16 => "AVX-512 BF16 instructions are required but not enabled; use -mavx512bf16",
X86DiagID::FeatureMissingAVX512FP16 => "AVX-512 FP16 instructions are required but not enabled; use -mavx512fp16",
X86DiagID::FeatureMissingAVX512VBMI => "AVX-512 VBMI instructions are required but not enabled; use -mavx512vbmi",
X86DiagID::FeatureMissingAVX512VBMI2 => "AVX-512 VBMI2 instructions are required but not enabled; use -mavx512vbmi2",
X86DiagID::FeatureMissingAVX512VNNI => "AVX-512 VNNI instructions are required but not enabled; use -mavx512vnni",
X86DiagID::FeatureMissingAVX512BITALG => "AVX-512 BITALG instructions are required but not enabled; use -mavx512bitalg",
X86DiagID::FeatureMissingAVX512VPOPCNTDQ => "AVX-512 VPOPCNTDQ instructions are required but not enabled; use -mavx512vpopcntdq",
X86DiagID::FeatureMissingAVX5124FMAPS => "AVX-512 4FMAPS instructions are required but not enabled; use -mavx5124fmaps",
X86DiagID::FeatureMissingAVX5124VNNIW => "AVX-512 4VNNIW instructions are required but not enabled; use -mavx5124vnniw",
X86DiagID::FeatureMissingAVX512VP2INTERSECT => "AVX-512 VP2INTERSECT instructions are required but not enabled; use -mavx512vp2intersect",
X86DiagID::FeatureMissingAVX512IFMA => "AVX-512 IFMA instructions are required but not enabled; use -mavx512ifma",
X86DiagID::FeatureMissingAVX10_1_256 => "AVX10.1/256 instructions are required but not enabled; use -mavx10.1-256",
X86DiagID::FeatureMissingAVX10_1_512 => "AVX10.1/512 instructions are required but not enabled; use -mavx10.1-512",
X86DiagID::FeatureMissingAVX10_2 => "AVX10.2 instructions are required but not enabled; use -mavx10.2",
X86DiagID::FeatureMissingFMA => "FMA instructions are required but not enabled; use -mfma",
X86DiagID::FeatureMissingFMA4 => "FMA4 (AMD) instructions are required but not enabled; use -mfma4",
X86DiagID::FeatureMissingF16C => "F16C instructions are required but not enabled; use -mf16c",
X86DiagID::FeatureMissingXOP => "XOP (AMD) instructions are required but not enabled; use -mxop",
X86DiagID::FeatureMissingMMX => "MMX instructions are required but not enabled; use -mmmx",
X86DiagID::FeatureMissing3DNOW => "3DNow! instructions are required but not enabled; use -m3dnow",
X86DiagID::FeatureMissing3DNOWA => "3DNow! (extended) instructions are required but not enabled; use -m3dnowa",
X86DiagID::FeatureMissingBMI => "BMI instructions are required but not enabled; use -mbmi",
X86DiagID::FeatureMissingBMI2 => "BMI2 instructions are required but not enabled; use -mbmi2",
X86DiagID::FeatureMissingLZCNT => "LZCNT instruction is required but not enabled; use -mlzcnt",
X86DiagID::FeatureMissingPOPCNT => "POPCNT instruction is required but not enabled; use -mpopcnt",
X86DiagID::FeatureMissingTBM => "TBM (AMD) instructions are required but not enabled; use -mtbm",
X86DiagID::FeatureMissingAES => "AES-NI instructions are required but not enabled; use -maes",
X86DiagID::FeatureMissingPCLMUL => "PCLMULQDQ instruction is required but not enabled; use -mpclmul",
X86DiagID::FeatureMissingSHA => "SHA instructions are required but not enabled; use -msha",
X86DiagID::FeatureMissingSHA512 => "SHA512 instructions are required but not enabled; use -msha512",
X86DiagID::FeatureMissingSM3 => "SM3 instructions are required but not enabled; use -msm3",
X86DiagID::FeatureMissingSM4 => "SM4 instructions are required but not enabled; use -msm4",
X86DiagID::FeatureMissingGFNI => "GFNI instructions are required but not enabled; use -mgfni",
X86DiagID::FeatureMissingVAES => "VAES instructions are required but not enabled; use -mvaes",
X86DiagID::FeatureMissingVPCLMULQDQ => "VPCLMULQDQ instruction is required but not enabled; use -mvpclmulqdq",
X86DiagID::FeatureMissingRDRAND => "RDRAND instruction is required but not enabled; use -mrdrand",
X86DiagID::FeatureMissingRDSEED => "RDSEED instruction is required but not enabled; use -mrdseed",
X86DiagID::FeatureMissingADX => "ADX instructions are required but not enabled; use -madx",
X86DiagID::FeatureMissingRTM => "RTM (Restricted Transactional Memory) instructions are required but not enabled; use -mrtm",
X86DiagID::FeatureMissingHLE => "HLE (Hardware Lock Elision) instructions are required but not enabled; use -mhle",
X86DiagID::FeatureMissingSGX => "SGX instructions are required but not enabled; use -msgx",
X86DiagID::FeatureMissingCET => "CET (Control-flow Enforcement Technology) instructions are required but not enabled; use -mcet",
X86DiagID::FeatureMissingXSAVE => "XSAVE instructions are required but not enabled; use -mxsave",
X86DiagID::FeatureMissingXSAVEOPT => "XSAVEOPT instruction is required but not enabled; use -mxsaveopt",
X86DiagID::FeatureMissingXSAVEC => "XSAVEC instruction is required but not enabled; use -mxsavec",
X86DiagID::FeatureMissingXSAVES => "XSAVES instruction is required but not enabled; use -mxsaves",
X86DiagID::FeatureMissingFSGSBASE => "FSGSBASE instructions are required but not enabled; use -mfsgsbase",
X86DiagID::FeatureMissingMOVBE => "MOVBE instruction is required but not enabled; use -mmovbe",
X86DiagID::FeatureMissingMOVDIRI => "MOVDIRI instruction is required but not enabled; use -mmovdiri",
X86DiagID::FeatureMissingMOVDIR64B => "MOVDIR64B instruction is required but not enabled; use -mmovdir64b",
X86DiagID::FeatureMissingENQCMD => "ENQCMD instruction is required but not enabled; use -menqcmd",
X86DiagID::FeatureMissingSERIALIZE => "SERIALIZE instruction is required but not enabled; use -mserialize",
X86DiagID::FeatureMissingTSXLDTRK => "TSXLDTRK instructions are required but not enabled; use -mtsxldtrk",
X86DiagID::FeatureMissingWAITPKG => "WAITPKG instructions are required but not enabled; use -mwaitpkg",
X86DiagID::FeatureMissingCLDEMOTE => "CLDEMOTE instruction is required but not enabled; use -mcldemote",
X86DiagID::FeatureMissingCLFLUSHOPT => "CLFLUSHOPT instruction is required but not enabled; use -mclflushopt",
X86DiagID::FeatureMissingCLWB => "CLWB instruction is required but not enabled; use -mclwb",
X86DiagID::FeatureMissingCLZERO => "CLZERO instruction is required but not enabled; use -mclzero",
X86DiagID::FeatureMissingMWAITX => "MWAITX instruction is required but not enabled; use -mmwaitx",
X86DiagID::FeatureMissingMONITORX => "MONITORX instruction is required but not enabled; use -mmonitorx",
X86DiagID::FeatureMissingPKU => "PKU instructions are required but not enabled; use -mpku",
X86DiagID::FeatureMissingSMAP => "SMAP instructions are required but not enabled; use -msmap",
X86DiagID::FeatureMissingSMEP => "SMEP instructions are required but not enabled; use -msmep",
X86DiagID::FeatureMissingMPX => "MPX instructions are required but not enabled; use -mmpx",
X86DiagID::FeatureMissingPTWRITE => "PTWRITE instruction is required but not enabled; use -mptwrite",
X86DiagID::FeatureMissingINVPCID => "INVPCID instruction is required but not enabled; use -minvpcid",
X86DiagID::FeatureMissingPREFETCHWT1 => "PREFETCHWT1 instruction is required but not enabled; use -mprefetchwt1",
X86DiagID::FeatureMissingPREFETCHW => "PREFETCHW instruction is required but not enabled; use -mprefetchw",
X86DiagID::FeatureMissingPREFETCHI => "PREFETCHI instruction is required but not enabled; use -mprefetchi",
X86DiagID::FeatureMissingAMX_BF16 => "AMX-BF16 instructions are required but not enabled; use -mamx-bf16",
X86DiagID::FeatureMissingAMX_INT8 => "AMX-INT8 instructions are required but not enabled; use -mamx-int8",
X86DiagID::FeatureMissingAMX_TILE => "AMX-TILE instructions are required but not enabled; use -mamx-tile",
X86DiagID::FeatureMissingAMX_FP16 => "AMX-FP16 instructions are required but not enabled; use -mamx-fp16",
X86DiagID::FeatureMissingAMX_COMPLEX => "AMX-COMPLEX instructions are required but not enabled; use -mamx-complex",
X86DiagID::FeatureMissingX87 => "x87 floating-point instructions are required but not enabled; use -m80387",
X86DiagID::FeatureMissingCMOV => "CMOV instructions are required but not enabled; this requires i686 or later",
X86DiagID::FeatureMissingSAHF => "SAHF instruction is required but not enabled; use -msahf",
X86DiagID::FeatureMissingRDPID => "RDPID instruction is required but not enabled; use -mrdpid",
X86DiagID::FeatureMissingRDPRU => "RDPRU instruction is required but not enabled; use -mrdpru",
X86DiagID::FeatureMissingHRESET => "HRESET instruction is required but not enabled; use -mhreset",
X86DiagID::FeatureMissingUINTR => "UINTR instructions are required but not enabled; use -muintr",
X86DiagID::FeatureMissingKL => "KL instructions are required but not enabled; use -mkl",
X86DiagID::FeatureMissingWIDEKL => "WIDEKL instructions are required but not enabled; use -mwidekl",
X86DiagID::FeatureMissingCMPCCXADD => "CMPCCXADD instructions are required but not enabled; use -mcmpccxadd",
X86DiagID::FeatureMissingRAOINT => "RAOINT instructions are required but not enabled; use -mraoint",
X86DiagID::FeatureMissingAVX_NE_CONVERT => "AVX-NE-CONVERT instructions are required but not enabled; use -mavxneconvert",
X86DiagID::FeatureMissingAVX_VNNI => "AVX-VNNI instructions are required but not enabled; use -mavxvnni",
X86DiagID::FeatureMissingAVX_VNNI_INT8 => "AVX-VNNI-INT8 instructions are required but not enabled; use -mavxvnniint8",
X86DiagID::FeatureNeedsX86_64V2 => "instruction requires x86-64-v2 baseline (SSE4.2 + POPCNT); target '{}' does not meet this level",
X86DiagID::FeatureNeedsX86_64V3 => "instruction requires x86-64-v3 baseline (AVX2 + BMI + FMA + LZCNT); target '{}' does not meet this level",
X86DiagID::FeatureNeedsX86_64V4 => "instruction requires x86-64-v4 baseline (AVX-512); target '{}' does not meet this level",
X86DiagID::FeatureDeprecated => "feature '{}' is deprecated and may be removed in a future release",
X86DiagID::FeatureRemoved => "feature '{}' has been removed; code depending on this feature will fail",
X86DiagID::FeatureExperimental => "feature '{}' is experimental and may change without notice",
X86DiagID::FeatureConflicting => "conflicting target features: '{}' and '{}' cannot both be enabled",
X86DiagID::FeatureMissingForCPU => "feature '{}' is required by the target CPU '{}' but is not available",
X86DiagID::FeatureNotAvailableOnCPU => "feature '{}' is not available on CPU '{}'",
X86DiagID::FeatureRequires64Bit => "feature '{}' requires 64-bit mode; use -m64 to compile for X86-64",
X86DiagID::FeatureRequires32Bit => "feature '{}' is only available in 32-bit mode; use -m32",
X86DiagID::FeatureMismatchedTuning => "CPU tuning model '{}' does not match target CPU '{}'; using generic tuning",
X86DiagID::FeatureGenericTuning => "no specific tuning for CPU '{}'; using generic x86-64 tuning",
X86DiagID::FeatureSuboptimalTuning => "suboptimal code generation: target CPU '{}' supports additional features not utilized",
X86DiagID::ABIStructTooLarge => "struct of size {} bytes is too large to pass in registers; it will be passed in memory",
X86DiagID::ABIStructPassedInMem => "struct '{}' with size {} bytes exceeds ABI register-passing limit; passed indirectly via memory",
X86DiagID::ABIStructSplitAcrossRegs => "struct '{}' is split across {} registers and {} bytes in memory",
X86DiagID::ABIReturnTooLarge => "return type of size {} bytes exceeds the ABI limit; hidden sret pointer will be used",
X86DiagID::ABIHiddenPointerReturn => "function '{}' returns a struct larger than {} bytes; using hidden pointer parameter",
X86DiagID::ABIParamTooLarge => "parameter of type '{}' with size {} bytes exceeds the ABI register-passing limit",
X86DiagID::ABITooManyParams => "too many parameters for calling convention '{}': {} arguments but only {} register slots available",
X86DiagID::ABIMismatchedCallingConv => "calling convention mismatch: '{}' in declaration, '{}' in definition",
X86DiagID::ABIUnknownCallingConv => "unknown calling convention '{}' for X86 target",
X86DiagID::ABICallingConvNotSupported => "calling convention '{}' is not supported on this X86 target",
X86DiagID::ABIFastcallTooManyArgs => "fastcall supports at most 2 register-passed arguments; got {}",
X86DiagID::ABIVectorcallAlignment => "vectorcall requires the stack to be aligned to {} bytes but current stack is only {} bytes aligned",
X86DiagID::ABIVectorcallTypeUnsupported => "vectorcall does not support non-vector types larger than {} bytes passed by value",
X86DiagID::ABIRegcallNotEnoughRegs => "regcall requires {} registers but only {} are available in calling convention",
X86DiagID::ABIThiscallNonMember => "thiscall calling convention is only valid for non-static member functions",
X86DiagID::ABIStdCallVarArgs => "stdcall calling convention does not support variadic arguments",
X86DiagID::ABICdeclMismatch => "cdecl calling convention mismatch: caller expects {} bytes cleanup but callee requires {}",
X86DiagID::ABIStackAlignmentViolation => "stack alignment violation: function '{}' requires {} byte aligned stack but may receive {} byte aligned stack",
X86DiagID::ABIRedZoneViolation => "red zone violation: function '{}' accesses memory below RSP in the 128-byte red zone",
X86DiagID::ABIArgOverlap => "argument overlap detected: parameter '{}' at offset {} overlaps with parameter '{}' at offset {}",
X86DiagID::ABIRegisterClassMismatch => "register class mismatch: parameter '{}' expected in class {} but assigned to class {}",
X86DiagID::ABIHomogeneousAggregate => "function '{}' returns a homogeneous vector aggregate of {} elements; using {} registers",
X86DiagID::ABIFloatArgsInIntegerReg => "floating-point argument '{}' of type '{}' passed in integer register",
X86DiagID::ABIIntegerArgsInFloatReg => "integer argument '{}' of type '{}' passed in floating-point register",
X86DiagID::ABIX87Return => "function '{}' returns a value using x87 FPU stack; consider using SSE for better performance",
X86DiagID::ABIComplexReturn => "complex '{}' returned via hidden pointer; ABI cannot pass complex values in registers",
X86DiagID::ABISysVClassificationFailed => "System V AMD64 ABI classification failed for type '{}'",
X86DiagID::ABIMicrosoftClassificationFailed => "Microsoft x64 ABI classification failed for type '{}'",
X86DiagID::ABIRegCallClassificationFailed => "GHC calling convention classification failed for type '{}'",
X86DiagID::ABIUnclassifiedType => "type '{}' cannot be classified for the X86 ABI; defaulting to memory",
X86DiagID::ABIMemClassTooMany => "type '{}' exceeds 8 eightbyte classification limit for AMD64 ABI",
X86DiagID::ABIEmptyStructPass => "empty struct '{}' passed by value: ABI may pass or ignore this depending on the calling convention",
X86DiagID::ABIZeroWidthBitfield => "struct '{}' contains a zero-width bitfield affecting layout in the ABI",
X86DiagID::ABIUnalignedFieldPass => "struct field at offset {} is unaligned; ABI may introduce padding",
X86DiagID::ABIPackedStructPass => "packed struct '{}' with size {} passed through ABI; alignment requirements are relaxed",
X86DiagID::ABIUnionPass => "union '{}' classification for ABI depends on the active member",
X86DiagID::ABIBitfieldStraddle => "bitfield straddles an 8-byte boundary in struct '{}'; may affect ABI register passing",
X86DiagID::SizeFunctionTooLarge => "function '{}' is {} bytes, exceeding the {} byte threshold for inline/branch optimization",
X86DiagID::SizeBasicBlockTooLarge => "basic block '{}' is {} instructions, exceeding the {} instruction limit",
X86DiagID::SizeAlignmentExcessive => "alignment of {} bytes for function '{}' may waste {} bytes of code space",
X86DiagID::SizeNopPaddingExcessive => "excessive NOP padding detected: {} bytes of NOPs inserted for alignment",
X86DiagID::SizeJumpTableTooLarge => "jump table for switch in function '{}' has {} entries and is too large for efficient dispatch",
X86DiagID::SizeELFTextOverflow => ".text section exceeds {} bytes; ELF32 section header limit reached",
X86DiagID::SizeCOFFTextOverflow => ".text section exceeds the COFF object file limit of {} bytes",
X86DiagID::SizeSectionOverflow => "section '{}' overflow: size {} exceeds limit {}",
X86DiagID::SizeDisplacementOverflowRelax => "instruction with {} byte displacement cannot be relaxed; requires branch island",
X86DiagID::SizeCallDisplacementError => "CALL instruction displacement of {} bytes exceeds the {} byte limit",
X86DiagID::SizeJumpDisplacementError => "JMP instruction displacement of {} bytes exceeds the {} byte limit",
X86DiagID::SizeLoopAlignmentHint => "loop at {} in function '{}' would benefit from {} byte alignment (currently {} aligned)",
X86DiagID::SizeFunctionAlignmentHint => "function '{}' entry at {} would benefit from {} byte alignment (currently {} aligned)",
X86DiagID::SizeBranchRelaxRequired => "branch relaxation needed: instruction at offset {} targets offset {} (distance: {} bytes)",
X86DiagID::SizeRelaxationLoop => "entering branch relaxation loop for function '{}': {} iterations remaining",
X86DiagID::SizeColdSectionSplit => "function '{}' cold sections split: moved {} blocks to .text.unlikely",
X86DiagID::SizeUnlikelyBranch => "unlikely branch at offset {} placed out-of-line to improve icache density",
X86DiagID::SizeHotColdPadding => "{} bytes of padding between hot and cold sections in function '{}'",
X86DiagID::SizeOptNoneHint => "function '{}' compiled with -O0: size optimizations skipped",
X86DiagID::SizeOptSizeHint => "function '{}' compiled with -Os: size-optimized layout applied",
X86DiagID::SizeMinSizeHint => "function '{}' compiled with -Oz: aggressive size-optimized layout applied",
X86DiagID::SizeBlockPlacementHint => "basic block '{}' placed at offset {} for optimal fallthrough from {}",
X86DiagID::SizeTailDuplicationHint => "tail duplication applied: block '{}' duplicated {} times to improve code layout",
X86DiagID::AlignUnalignedAccess => "unaligned memory access at offset {} in function '{}': access is {} bytes but alignment is {}",
X86DiagID::AlignUnalignedStackAccess => "unaligned stack access at SP+{} in function '{}': access is {} bytes but stack alignment is {}",
X86DiagID::AlignUnalignedLoad => "unaligned load of {} bytes from address with alignment {} in function '{}'",
X86DiagID::AlignUnalignedStore => "unaligned store of {} bytes to address with alignment {} in function '{}'",
X86DiagID::AlignMisalignedAtomics => "misaligned atomic operation of {} bytes at offset {}: this may be very slow on some microarchitectures",
X86DiagID::AlignLockPrefixAlign => "LOCK-prefixed instruction at an unaligned address; performance may degrade significantly",
X86DiagID::AlignSIMDUnalignedAccess => "unaligned SSE access in function '{}': using movups instead of movaps (slower on some CPUs)",
X86DiagID::AlignAVXUnalignedAccess => "unaligned AVX access in function '{}': using vmovups instead of vmovaps",
X86DiagID::AlignAVX512UnalignedAccess => "unaligned AVX-512 access in function '{}': using VMOVUPS instead of VMOVAPS",
X86DiagID::AlignDataAlign => "data alignment of {} bytes requested for '{}' but target supports maximum of {}",
X86DiagID::AlignCodeAlign => "code alignment of {} bytes requested for block '{}' but maximum allowed is {}",
X86DiagID::AlignStackAlign => "stack alignment of {} bytes requested for function '{}' but target requires {} bytes",
X86DiagID::AlignStructAlign => "struct '{}' requires {} byte alignment but the ABI specifies {}",
X86DiagID::AlignCacheLineBoundary => "data crosses a cache-line boundary (64 bytes) at offset {}: may cause split-cache-line access",
X86DiagID::AlignPageBoundary => "data crosses a page boundary (4096 bytes) at offset {}: may cause a TLB miss",
X86DiagID::AlignFunctionEntryAlign => "function '{}' entry aligned to {} bytes at offset {}",
X86DiagID::AlignLoopAlign => "loop header aligned to {} bytes at offset {} in function '{}'",
X86DiagID::AlignUnalignedBranchTarget => "branch target at offset {} is unaligned; consider {} byte alignment for fetch efficiency",
X86DiagID::AlignMisalignedReturnAddress => "return address at RSP is misaligned; possible stack corruption in function '{}'",
X86DiagID::AlignStackRealignNeeded => "stack realignment needed: function '{}' requires {} byte alignment but ABI guarantees {} bytes",
X86DiagID::AlignStackProbeNeeded => "stack probe needed: function '{}' allocates {} bytes which may skip guard pages on Windows",
X86DiagID::AlignVariableAlignment => "variable '{}' has alignment {}; generated code aligns the stack variable",
X86DiagID::AlignNopSledNeeded => "NOP sled inserted for alignment: {} bytes at offset {}",
X86DiagID::AlignOverAlignedAlloca => "alloca with alignment {} exceeds default stack alignment; dynamic realignment emitted",
X86DiagID::AlignUnderAlignedAlloca => "alloca with alignment {} is below the ABI minimum; alignment increased to {}",
X86DiagID::InlineAsmParseError => "error parsing inline assembly: {}",
X86DiagID::InlineAsmInvalidInstruction => "invalid instruction mnemonic '{}' in inline assembly",
X86DiagID::InlineAsmInvalidOperand => "invalid operand '{}' in inline assembly instruction '{}'",
X86DiagID::InlineAsmInvalidConstraint => "invalid constraint '{}' in inline assembly operand {}",
X86DiagID::InlineAsmClobberConflict => "register '{}' listed as both output operand and clobber",
X86DiagID::InlineAsmRegisterClobbered => "register '{}' is clobbered by inline asm but also used in surrounding code",
X86DiagID::InlineAsmTooManyOperands => "inline assembly has {} operands but the maximum supported is {} for this instruction",
X86DiagID::InlineAsmSizeMismatch => "operand size mismatch in inline asm: operand {} expects {} bytes but got {} bytes",
X86DiagID::InlineAsmUnsupportedConstraint => "constraint '{}' is not supported on this X86 target",
X86DiagID::InlineAsmImmediateConstraint => "constraint '{}' requires an immediate value but got a register operand",
X86DiagID::InlineAsmMemoryConstraint => "memory constraint 'm' used for operand {}: consider using a register constraint for performance",
X86DiagID::InlineAsmFloatConstraint => "floating-point constraint used for operand {} on a target without SSE: falling back to x87",
X86DiagID::InlineAsmMultipleAlternative => "multiple alternative constraint used for operand {}: compiler will select the best match",
X86DiagID::InlineAsmInvalidTiedOperand => "tied operand constraint '{}' references invalid operand index {}",
X86DiagID::InlineAsmDuplicateConstraint => "duplicate constraint '{}' for operand {}: each output operand must be unique",
X86DiagID::InlineAsmInputOutputMismatch => "input operand {} with constraint '{}' does not match output operand {} constraint '{}'",
X86DiagID::InlineAsmGlobalRegister => "global register variable '{}' conflicts with inline asm register usage",
X86DiagID::InlineAsmFramePointerClobber => "inline asm clobbers the frame pointer register (RBP/EBP); stack unwinding may fail",
X86DiagID::InlineAsmStackPointerClobber => "inline asm clobbers the stack pointer register (RSP/ESP); this is extremely dangerous",
X86DiagID::InlineAsmReservedRegister => "inline asm uses reserved register '{}' which is reserved by the operating system",
X86DiagID::InlineAsmIPRegisterClobber => "inline asm attempts to clobber the instruction pointer register (RIP/EIP)",
X86DiagID::InlineAsmFlagsRegisterClobber => "inline asm clobbers the flags register (RFLAGS/EFLAGS) without listing it in the clobber list",
X86DiagID::InlineAsmAVX512MaskOperand => "AVX-512 mask operand {} must be a k0-k7 register; got '{}'",
X86DiagID::InlineAsmAVX512BroadcastOperand => "AVX-512 broadcast operand {} requires memory source with {{{}}} decorator",
X86DiagID::InlineAsmAVX512RoundingOperand => "AVX-512 rounding control operand {} must be {{rn}}, {{rd}}, {{ru}}, or {{rz}}",
X86DiagID::InlineAsmAVX512SAEOperand => "AVX-512 SAE operand {} suppresses all exceptions; ensure this is intentional",
X86DiagID::InlineAsmAVX512ZeroMasking => "AVX-512 zero-masking applied to operand {}: masked-off elements will be zeroed",
X86DiagID::InlineAsmAMXTileOperand => "AMX tile operand {} must reference tile registers tmm0-tmm7",
X86DiagID::InlineAsmAMXConfigNeeded => "AMX tile operations require a preceding LDTILECFG instruction to configure tiles",
X86DiagID::InlineAsmGotoLabel => "inline asm goto label '{}' referenced in asm string",
X86DiagID::InlineAsmGotoTooManyLabels => "asm goto has {} labels but only {} are allowed",
X86DiagID::InlineAsmGotoIndirectBranch => "asm goto may perform an indirect branch to '{}'",
X86DiagID::InlineAsmIntelSyntaxWarning => "inline asm using Intel syntax; ensure .intel_syntax directive is present",
X86DiagID::InlineAsmATTDirectiveWarning => "AT&T syntax directive '{}' detected in inline asm",
X86DiagID::InlineAsmIntelDirectiveWarning => "Intel syntax directive '{}' detected in inline asm",
X86DiagID::InlineAsmSplitOperandType => "operand '{}' has a split type: {} bits in upper portion, {} bits in lower portion",
X86DiagID::InlineAsmUndefinedSymbol => "inline asm references undefined symbol '{}'",
X86DiagID::InlineAsmRelocationOverflow => "relocation for symbol '{}' in inline asm overflows the available {} bits",
X86DiagID::InlineAsmAbsoluteAddress => "absolute address used in inline asm for symbol '{}'; use RIP-relative addressing for position-independent code",
X86DiagID::InlineAsmTLSRelocation => "thread-local storage access in inline asm for symbol '{}'; ensure correct TLS model",
X86DiagID::InlineAsmGOTPCREL => "GOTPCREL relocation used in inline asm for '{}': ensure symbol is defined in a shared library",
X86DiagID::InlineAsmPLTRelocation => "PLT relocation used in inline asm for '{}': lazily resolved at runtime",
X86DiagID::InlineAsmSegmentOverride => "segment override prefix (CS/DS/ES/FS/GS/SS) used in inline asm: ensure correct segment",
X86DiagID::InlineAsmAddressSizeOverride => "address size override prefix (67h) used in inline asm: mixing 32-bit and 64-bit addressing",
X86DiagID::InlineAsmOperandSizeOverride => "operand size override prefix (66h) used in inline asm: mixing 16-bit and 32-bit operands",
X86DiagID::InlineAsmREXPrefixUnused => "REX prefix emitted but not needed for instruction '{}'",
X86DiagID::InlineAsmLockPrefixWrong => "LOCK prefix used on instruction '{}' which does not support atomic operations",
X86DiagID::InlineAsmRepPrefixWrong => "REP prefix used on instruction '{}' which does not support string operations",
X86DiagID::InlineAsmVEXPrefixInvalid => "VEX prefix encoding is invalid for instruction '{}': {}",
X86DiagID::InlineAsmEVEXPrefixInvalid => "EVEX prefix encoding is invalid for instruction '{}': {}",
X86DiagID::VectorWidthMismatch => "vector width mismatch: operand '{}' expects {} bits but got {} bits",
X86DiagID::VectorTypeMismatch => "vector type mismatch: '{}' vs '{}' in operation '{}'",
X86DiagID::VectorElementCountMismatch => "vector element count mismatch: expected {} elements but got {}",
X86DiagID::VectorShuffleMaskInvalid => "shuffle mask element {} is invalid: expected value in range 0..{}",
X86DiagID::VectorShuffleMaskOutOfRange => "shuffle mask element {} at index {} is out of range for {} element vector",
X86DiagID::VectorInsertIndexOutOfRange => "vector insert index {} is out of range for {} element vector",
X86DiagID::VectorExtractIndexOutOfRange => "vector extract index {} is out of range for {} element vector",
X86DiagID::VectorGatherScatterAlign => "gather/scatter operation requires {} byte alignment but address is only {} byte aligned",
X86DiagID::VectorMaskOperandMissing => "mask operand missing for AVX-512 masked operation; defaulting to no mask (k0)",
X86DiagID::VectorMaskTypeMismatch => "mask register type mismatch: expected {} bit mask but got {} bit mask",
X86DiagID::VectorZeroMaskNotSupported => "zero-masking not supported for this operation; falling back to merge-masking",
X86DiagID::VectorMergeMaskNotSupported => "merge-masking not supported for this operation with destination type '{}'",
X86DiagID::VectorBroadcastUnsupported => "vector broadcast of element '{}' is not supported for the current target",
X86DiagID::VectorBroadcastMemSource => "broadcast from memory source at offset {}: loading single element and broadcasting",
X86DiagID::VectorBroadcastWidth => "broadcast width {} exceeds the maximum vector width {} for this target",
X86DiagID::VectorPermuteUnsupported => "vector permutation pattern '{}' is not directly supported; may be lowered to multiple shuffles",
X86DiagID::VectorInterleaveUnsupported => "vector interleave operation not supported for element type '{}' on this target",
X86DiagID::VectorDeinterleaveUnsupported => "vector deinterleave operation not supported for element type '{}' on this target",
X86DiagID::VectorLoadUnaligned => "unaligned vector load of {} bytes from offset {} in function '{}'",
X86DiagID::VectorStoreUnaligned => "unaligned vector store of {} bytes to offset {} in function '{}'",
X86DiagID::VectorLoadNonTemporal => "non-temporal vector load streaming hint used at offset {}",
X86DiagID::VectorStoreNonTemporal => "non-temporal vector store streaming hint used at offset {}",
X86DiagID::VectorGatherUnsupported => "vector gather operation not supported for element type '{}' on this target",
X86DiagID::VectorScatterUnsupported => "vector scatter operation not supported for element type '{}' on this target",
X86DiagID::VectorGather4Unsupported => "4-element gather not supported; falling back to scalar loads",
X86DiagID::VectorScatter4Unsupported => "4-element scatter not supported; falling back to scalar stores",
X86DiagID::VectorCompressUnsupported => "vector compress operation not supported on this target; may be expanded",
X86DiagID::VectorExpandUnsupported => "vector expand operation not supported on this target; may be expanded",
X86DiagID::VectorReduceUnsupported => "vector reduction of type '{}' is not supported on this target; expanding to log2(N) operations",
X86DiagID::VectorHorizontalAddSub => "horizontal add/sub operation expanded to vector shuffle and vertical add/sub for type '{}'",
X86DiagID::VectorDotProductUnsupported => "vector dot product of '{}' x '{}' not natively supported; lowered to multiply and horizontal add",
X86DiagID::VectorFMAUnsupported => "fused multiply-add on vectors of type '{}' not supported; using separate multiply and add",
X86DiagID::VectorFP16Unsupported => "FP16 vector operations not supported on this target; consider using AVX512-FP16 or a scalar fallback",
X86DiagID::VectorBF16Unsupported => "BF16 vector operations not supported on this target; consider using AVX512-BF16 or conversion",
X86DiagID::VectorINT8Unsupported => "INT8 vector operations not supported on this target; consider using VNNI or scalar fallback",
X86DiagID::VectorINT4Unsupported => "INT4 vector operations not supported on this target; using scalar operations",
X86DiagID::VectorFPUnsupportedForWidth => "floating-point vector operation not supported for {} bit width; using narrower vector type",
X86DiagID::VectorIntegerUnsupportedForWidth => "integer vector operation not supported for {} bit width; using narrower vector type",
X86DiagID::VectorConversionRounding => "vector float-to-int conversion with rounding control {} emitted as {}",
X86DiagID::VectorConvertOverflow => "vector conversion from '{}' to '{}' may overflow for some element values",
X86DiagID::VectorConvertSaturation => "vector saturated conversion from '{}' to '{}' uses {} instruction",
X86DiagID::VectorAbsUnsupported => "vector absolute value not natively supported for type '{}'; using sign-bit clear",
X86DiagID::VectorMinMaxUnsupported => "vector min/max not natively supported for type '{}'; using compare + blend",
X86DiagID::VectorRoundUnsupported => "vector round not natively supported for type '{}'; using SSE4.1 roundps fallback",
X86DiagID::VectorSqrtUnsupported => "vector sqrt not natively supported for type '{}'; using scalar sqrt and insert",
X86DiagID::VectorRcpUnsupported => "vector reciprocal not natively supported for type '{}'; using divide fallback",
X86DiagID::VectorRsqrtUnsupported => "vector reciprocal sqrt not natively supported for type '{}'; using rsqrtps with Newton-Raphson",
X86DiagID::VectorPopcountUnsupported => "vector popcount not natively supported for type '{}'; using scalar popcount loop",
X86DiagID::VectorLZCNTUnsupported => "vector leading-zero count not natively supported for type '{}'; using scalar LZCNT",
X86DiagID::VectorRotateUnsupported => "vector rotate not natively supported for type '{}'; using shift and OR",
X86DiagID::VectorShiftImmOutOfRange => "shift immediate {} is out of range for vector element type '{}' (valid: {})",
X86DiagID::VectorShiftAmountMismatch => "shift amount vector width {} does not match data vector width {}",
X86DiagID::VectorBlendMaskInvalid => "blend mask 0x{:x} has invalid bits for {} element vector",
X86DiagID::VectorComparePredicateInvalid => "vector comparison predicate '{}' is not valid for floating-point elements",
X86DiagID::VectorSelectConditionInvalid => "vector select condition of type '{}' is not a valid mask type",
X86DiagID::VectorAMXLoadStore => "AMX tile load from/store to memory at offset {}: tile is {} rows x {} columns",
X86DiagID::VectorAMXTileShape => "AMX tile shape {}x{} does not match the configured tile shape {}x{}",
X86DiagID::VectorAMXConfig => "AMX tile configuration: {} tiles configured, total size {} bytes",
X86DiagID::VectorAMXZero => "AMX tile {} zeroed: {} rows x {} columns",
X86DiagID::VectorAMXTilePair => "AMX tile pair operation on tiles {} and {}: result in tile {}",
X86DiagID::VectorSSEUpgradeHint => "consider using SSE2+ instructions for better performance (current target does not enable SSE2)",
X86DiagID::VectorAVXUpgradeHint => "consider enabling AVX for 256-bit vector operations (currently using 128-bit SSE)",
X86DiagID::VectorAVX512UpgradeHint => "consider enabling AVX-512 for 512-bit vector operations (currently using {} bit vectors)",
X86DiagID::VectorAVX10UpgradeHint => "consider enabling AVX10 for convergent vector ISA across P-core and E-core",
X86DiagID::VectorUsePackedHint => "using packed (SIMD) operation: performing {} elements in parallel",
X86DiagID::VectorUseScalarHint => "using scalar operation: vectorized form would process {} elements in parallel",
X86DiagID::VectorUseGatherHint => "using gather instruction to load {} indices from memory",
X86DiagID::VectorUseScatterHint => "using scatter instruction to store {} values to memory at indexed positions",
X86DiagID::OptX86ISelSuccess => "instruction selection succeeded: '{}' selected for IR instruction '{}'",
X86DiagID::OptX86ISelFailure => "instruction selection failed for '{}' in function '{}': no matching pattern",
X86DiagID::OptX86PeepholeApplied => "peephole optimization applied: '{}' -> '{}' in function '{}'",
X86DiagID::OptX86PeepholeSkipped => "peephole optimization skipped for '{}': pattern does not apply in this context",
X86DiagID::OptX86MacroFusion => "macro-fusion applied: '{}' + '{}' fused into single uop in function '{}'",
X86DiagID::OptX86MicroFusion => "micro-fusion applied: '{}' memory operand folded into '{}' in function '{}'",
X86DiagID::OptX86NopInsertion => "NOP inserted: {} bytes of NOP padding at offset {} for alignment",
X86DiagID::OptX86PrefixOptimization => "prefix optimization: removed redundant REX prefix from instruction at offset {}",
X86DiagID::OptX86LEAUsesAG => "LEA replaced with ADD: 'lea rax,[rax+{}]' -> 'add rax,{}' (address generation avoided)",
X86DiagID::OptX86LEAUsesLEA => "LEA used for non-address computation: 'lea {},[{} + {}*{}]' for arithmetic",
X86DiagID::OptX86CMOVConversion => "conditional move inserted: branch converted to cmov{} in function '{}'",
X86DiagID::OptX86SETCCConversion => "setcc conversion: branch pattern recognized and converted to set{}",
X86DiagID::OptX86BranchAvoidance => "branch avoided: replaced conditional branch with {}",
X86DiagID::OptX86FlagCopyEliminated => "flag copy eliminated: redundant save/restore of EFLAGS removed",
X86DiagID::OptX86ConditionalMove => "conditional move used instead of branch for value {} in function '{}'",
X86DiagID::OptX86LoadFoldIntoInstr => "folded load: memory operand '{}' folded into instruction '{}'",
X86DiagID::OptX86StoreFoldIntoInstr => "folded store: store to '{}' folded into preceding instruction '{}'",
X86DiagID::OptX86ImmediateFold => "immediate fold: constant {} folded into instruction operand",
X86DiagID::OptX86AddressFold => "address fold: base+offset computed as single LEA addressing mode",
X86DiagID::OptX86ConstantPoolFold => "constant pool fold: value '{}' from constant pool folded as immediate operand",
X86DiagID::OptX86TwoAddressPass => "two-address pass: instruction '{}' converted from 3-address to 2-address form",
X86DiagID::OptX86FixupBWInst => "fixup BW: byte/word instruction '{}' widened to 32-bit to avoid partial register stalls",
X86DiagID::OptX86FixupLEA => "fixup LEA: LEA instruction at {} optimized to {}",
X86DiagID::OptX86AvoidStoreForwarding => "avoid store forwarding stall: bypassed store-to-load forwarding in function '{}'",
X86DiagID::OptX86AvoidPartialRegStall => "avoid partial register stall: inserted XOR to break dependency on '{}'",
X86DiagID::OptX86AvoidPartialFlagStall => "avoid partial flags stall: used ADD/SUB instead of INC/DEC on '{}'",
X86DiagID::OptX86DomainCrossing => "domain crossing: instruction '{}' changed execution domain from {} to {}",
X86DiagID::OptX86VZeroupperInserted => "VZEROUPPER inserted: clearing upper YMM/ZMM state after function '{}'",
X86DiagID::OptX86VZeroupperNotNeeded => "VZEROUPPER not needed: function '{}' does not use 256-bit or wider vectors",
X86DiagID::OptX86TileConfigInserted => "tile config: LDTILECFG inserted before AMX tile operations in function '{}'",
X86DiagID::OptX86X87Stackify => "x87 stackify: {} x87 instructions reordered for optimal FPU stack usage",
X86DiagID::OptX86CallFrameOptimization => "call frame optimization: {} bytes of call frame setup eliminated in '{}'",
X86DiagID::OptX86StackColoring => "stack coloring: reused {} bytes of stack space across disjoint lifetimes",
X86DiagID::OptX86ShrinkWrapping => "shrink wrapping applied: prologue/epilogue moved for function '{}'",
X86DiagID::OptX86TailDuplicate => "tail duplication: block '{}' duplicated {} times for better fallthrough",
X86DiagID::OptX86TailMerge => "tail merge: {} blocks merged into common epilogue for function '{}'",
X86DiagID::OptX86MachineLICM => "machine LICM: hoisted {} instructions out of loop at block '{}'",
X86DiagID::OptX86MachineCSE => "machine CSE: eliminated {} duplicate machine instructions in '{}'",
X86DiagID::OptX86MachineSink => "machine sink: sank {} instructions to reduce register pressure in '{}'",
X86DiagID::OptX86LoopAlignment => "loop alignment: loop at block '{}' aligned to {} bytes",
X86DiagID::OptX86BranchFolding => "branch folding: {} branches folded into fallthrough in function '{}'",
X86DiagID::OptX86IfConversion => "if-conversion: diamond pattern converted to predicated execution in '{}'",
X86DiagID::OptX86MachineBlockPlacement => "block placement: block '{}' placed at offset {} (probability: {})",
X86DiagID::OptX86EarlyIfConversion => "early if-conversion: speculative execution inserted for branch in '{}'",
X86DiagID::OptX86SpeculativeLoadHardening => "speculative load hardening: LFENCE inserted after bounds check in '{}'",
X86DiagID::OptX86IndirectBranchTracking => "indirect branch tracking: ENDBR64 inserted at function entry for '{}'",
X86DiagID::OptX86Scheduler => "scheduler: {} instructions scheduled across {} cycles for function '{}'",
X86DiagID::OptX86PostRAScheduler => "post-RA scheduler: improved {} critical path instructions in '{}'",
X86DiagID::OptX86PreRAScheduler => "pre-RA scheduler: minimized register pressure for {} vregs",
X86DiagID::OptX86MachinePipeliner => "machine pipeliner: software pipelined loop with initiation interval {}",
X86DiagID::OptX86RegisterCoalescing => "register coalescing: merged vreg{} and vreg{} into physical register {}",
X86DiagID::OptX86VirtualRegisterRewrite => "virtual register rewrite: {} vregs rewritten to physical registers",
X86DiagID::OptX86LiveRangeShrink => "live range shrink: reduced live range of vreg{} by {} instructions",
X86DiagID::OptX86DeadMachineInstructionElim => "dead MI elimination: removed {} dead machine instructions",
X86DiagID::OptX86PrologEpilogInsertion => "prolog/epilog insertion: function '{}' frame size = {} bytes, stack depth = {}",
X86DiagID::OptX86FrameLowering => "frame lowering: emitted {} push/pop instructions for function '{}'",
X86DiagID::OptX86RedZone => "red zone: function '{}' uses {} bytes of red zone below RSP",
X86DiagID::OptX86ShadowStack => "shadow stack: inserted shadow stack push/pop for CET in function '{}'",
X86DiagID::OptX86PatchableFunction => "patchable function: emitted {} NOP bytes before function '{}' entry",
X86DiagID::OptX86FunctionSections => "function sections: placed function '{}' in separate section .text.{}",
X86DiagID::OptX86DataSections => "data sections: placed data '{}' in separate section .data.{}",
X86DiagID::OptX86NoOmitFramePointer => "frame pointer preserved: RBP used as frame pointer in function '{}'",
X86DiagID::OptX86OmitFramePointer => "frame pointer omitted: RBP freed for general use in function '{}'",
X86DiagID::OptX86HotColdSplit => "hot/cold split: function '{}' split into {} hot bytes and {} cold bytes",
X86DiagID::LinkerRelocationOverflow => "relocation overflow: {} bits relocation for symbol '{}' does not fit in {} bits",
X86DiagID::LinkerGOTOverflow => "GOT overflow: too many GOT entries for shared object; increase GOT size",
X86DiagID::LinkerPLTOverflow => "PLT overflow: too many PLT entries; consider reducing the number of external calls",
X86DiagID::LinkerTLSOverflow => "TLS overflow: thread-local storage model '{}' exceeds available space",
X86DiagID::LinkerUnresolvedSymbol => "unresolved symbol: '{}' referenced in object file but not defined in any linked library",
X86DiagID::LinkerSectionMismatch => "section mismatch: symbol '{}' in section '{}' referenced from section '{}'",
X86DiagID::LinkerTrampolineNeeded => "trampoline needed: indirect call to '{}' requires a linker-generated trampoline",
X86DiagID::LinkerRelaxationNeeded => "linker relaxation: section '{}' has {} bytes of unnecessary NOP padding",
X86DiagID::LinkerThreadLocalModel => "thread-local storage model: using {} model for TLS variable '{}'",
X86DiagID::LinkerTLSLocalExec => "TLS local-exec model: variable '{}' accessed via FS/GS segment",
X86DiagID::LinkerTLSInitialExec => "TLS initial-exec model: variable '{}' accessed via GOT + FS/GS",
X86DiagID::LinkerTLSLocalDynamic => "TLS local-dynamic model: variable '{}' uses __tls_get_addr with local-dynamic",
X86DiagID::LinkerTLSGlobalDynamic => "TLS global-dynamic model: variable '{}' uses __tls_get_addr with global-dynamic",
X86DiagID::MiscStackProbe => "stack probe inserted: function '{}' probes stack at intervals of {} bytes",
X86DiagID::MiscAllocaProbe => "alloca probe: dynamic alloca of {} bytes probed at stack page boundaries",
X86DiagID::MiscVLAProbe => "VLA probe: variable-length array of size {} triggers stack probing",
X86DiagID::MiscSegmentedStack => "segmented stack: function '{}' uses segmented stack with {} byte segment size",
X86DiagID::MiscSplitStack => "split stack: function '{}' may allocate additional stack segments at runtime",
X86DiagID::MiscXRayInstrumentation => "XRay instrumentation: function '{}' instrumented with sled at entry and exit",
X86DiagID::MiscCFIInstruction => "CFI instruction: {} directive emitted at offset {} for function '{}'",
X86DiagID::MiscUnwindOpcode => "unwind opcode: {} emitted for function '{}' at offset {}",
X86DiagID::MiscSEHUnwind => "SEH unwind: __C_specific_handler registered for function '{}'",
X86DiagID::MiscCETEndBranch => "CET endbranch: ENDBR64 instruction emitted at indirect branch target {}",
X86DiagID::MiscShadowCallStack => "shadow call stack: function '{}' uses shadow stack for return address protection",
X86DiagID::MiscSafeStack => "safe stack: unsafe objects placed on unsafe stack; {} bytes of safe stack",
X86DiagID::MiscControlFlowGuard => "control flow guard: indirect call check inserted for target '{}'",
X86DiagID::MiscKCFI => "kernel CFI: indirect call target type hash verified for function '{}'",
X86DiagID::MiscFineIBT => "fine IBT: ENDBR + hash check sequence emitted for function '{}'",
X86DiagID::MiscMemoryTagging => "memory tagging: tagged pointer arithmetic detected in function '{}'",
X86DiagID::MiscHardwareEnforcedSP => "hardware-enforced stack protection: shadow stack used for function '{}'",
X86DiagID::MiscZeroCallUsedRegs => "zero call-used registers: {} registers zeroed after call in function '{}'",
X86DiagID::MiscFEntryInsertion => "fentry insertion: __fentry__ call emitted at function '{}' prologue",
X86DiagID::MiscDirectEmission => "direct object emission: skipping assembly text generation for function '{}'",
X86DiagID::MiscDelaySlotFill => "delay slot fill: instruction '{}' moved into delay slot after branch",
X86DiagID::MiscConstantIsland => "constant island: {} bytes of constant data placed at offset {} in function '{}'",
_ => "unknown diagnostic",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct X86DiagnosticGroup {
pub name: String,
pub flag: String,
pub enabled_by_default: bool,
pub description: String,
pub members: Vec<X86DiagID>,
}
pub struct X86DiagnosticGroupRegistry {
pub groups: HashMap<String, X86DiagnosticGroup>,
pub id_to_groups: HashMap<X86DiagID, Vec<String>>,
}
impl X86DiagnosticGroupRegistry {
pub fn new() -> Self {
let mut registry = Self {
groups: HashMap::new(),
id_to_groups: HashMap::new(),
};
registry.register_all();
registry
}
fn register_all(&mut self) {
self.add_group(X86DiagnosticGroup {
name: "x86-backend-isel".into(),
flag: "-Wx86-backend-isel".into(),
enabled_by_default: true,
description: "Warn about X86 instruction selection failures".into(),
members: vec![
X86DiagID::BackendISelFail,
X86DiagID::BackendCannotSelect,
X86DiagID::BackendUnsupportedType,
X86DiagID::BackendIllegalType,
X86DiagID::BackendCannotLower,
X86DiagID::BackendCannotLegalize,
X86DiagID::BackendNoPattern,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-backend-regalloc".into(),
flag: "-Wx86-backend-regalloc".into(),
enabled_by_default: true,
description: "Warn about X86 register allocation issues (spills, failures)".into(),
members: vec![
X86DiagID::BackendRegallocSpill,
X86DiagID::BackendRegallocFail,
X86DiagID::BackendOutOfRegisters,
X86DiagID::BackendPhysRegUnavailable,
X86DiagID::BackendVirtRegUnmapped,
X86DiagID::BackendLiveInConflict,
X86DiagID::BackendStackSlotTooLarge,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-backend-frame".into(),
flag: "-Wx86-backend-frame".into(),
enabled_by_default: true,
description: "Warn about X86 frame lowering issues".into(),
members: vec![
X86DiagID::BackendFrameTooLarge,
X86DiagID::BackendStackRealignLimit,
X86DiagID::BackendCannotEliminateFrameIndex,
X86DiagID::BackendFrameOffsetOverflow,
X86DiagID::BackendRedZoneViolation,
X86DiagID::BackendPrologueEmissionFailed,
X86DiagID::BackendEpilogueEmissionFailed,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-backend-encoding".into(),
flag: "-Wx86-backend-encoding".into(),
enabled_by_default: true,
description: "Warn about X86 instruction encoding failures".into(),
members: vec![
X86DiagID::BackendEncodingFail,
X86DiagID::BackendImmediateTooLarge,
X86DiagID::BackendDisplacementOverflow,
X86DiagID::BackendAddressModeInvalid,
X86DiagID::BackendRexPrefixConflict,
X86DiagID::BackendVexEncodingFail,
X86DiagID::BackendEvexEncodingFail,
X86DiagID::BackendOpcodeNotSupported,
X86DiagID::BackendRelaxationFail,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-backend-emission".into(),
flag: "-Wx86-backend-emission".into(),
enabled_by_default: true,
description: "Warn about code emission failures".into(),
members: vec![
X86DiagID::BackendEmissionFail,
X86DiagID::BackendObjectEmissionFail,
X86DiagID::BackendAsmPrinterFail,
X86DiagID::BackendDwarfEmissionFail,
X86DiagID::BackendUnwindInfoFail,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-backend".into(),
flag: "-Wx86-backend".into(),
enabled_by_default: false,
description: "Enable all X86 backend diagnostics".into(),
members: vec![],
});
self.add_group(X86DiagnosticGroup {
name: "x86-missing-simd".into(),
flag: "-Wx86-missing-simd".into(),
enabled_by_default: true,
description: "Warn when vector/SIMD features are required but not enabled".into(),
members: vec![
X86DiagID::FeatureMissingSSE,
X86DiagID::FeatureMissingSSE2,
X86DiagID::FeatureMissingSSE3,
X86DiagID::FeatureMissingSSSE3,
X86DiagID::FeatureMissingSSE41,
X86DiagID::FeatureMissingSSE42,
X86DiagID::FeatureMissingAVX,
X86DiagID::FeatureMissingAVX2,
X86DiagID::FeatureMissingAVX512F,
X86DiagID::FeatureMissingAVX512BW,
X86DiagID::FeatureMissingAVX512DQ,
X86DiagID::FeatureMissingAVX512VL,
X86DiagID::FeatureMissingFMA,
X86DiagID::FeatureMissingMMX,
X86DiagID::FeatureMissing3DNOW,
X86DiagID::FeatureMissing3DNOWA,
X86DiagID::FeatureMissingF16C,
X86DiagID::FeatureMissingFMA4,
X86DiagID::FeatureMissingXOP,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-missing-avx512".into(),
flag: "-Wx86-missing-avx512".into(),
enabled_by_default: true,
description: "Warn when AVX-512 sub-features are required but not enabled".into(),
members: vec![
X86DiagID::FeatureMissingAVX512F,
X86DiagID::FeatureMissingAVX512BW,
X86DiagID::FeatureMissingAVX512DQ,
X86DiagID::FeatureMissingAVX512VL,
X86DiagID::FeatureMissingAVX512CD,
X86DiagID::FeatureMissingAVX512ER,
X86DiagID::FeatureMissingAVX512PF,
X86DiagID::FeatureMissingAVX512BF16,
X86DiagID::FeatureMissingAVX512FP16,
X86DiagID::FeatureMissingAVX512VBMI,
X86DiagID::FeatureMissingAVX512VBMI2,
X86DiagID::FeatureMissingAVX512VNNI,
X86DiagID::FeatureMissingAVX512BITALG,
X86DiagID::FeatureMissingAVX512VPOPCNTDQ,
X86DiagID::FeatureMissingAVX512IFMA,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-missing-security".into(),
flag: "-Wx86-missing-security".into(),
enabled_by_default: false,
description: "Warn when security-related features are missing".into(),
members: vec![
X86DiagID::FeatureMissingSGX,
X86DiagID::FeatureMissingCET,
X86DiagID::FeatureMissingSMAP,
X86DiagID::FeatureMissingSMEP,
X86DiagID::FeatureMissingMPX,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-target-features".into(),
flag: "-Wx86-target-features".into(),
enabled_by_default: false,
description: "Enable all X86 target-feature diagnostics".into(),
members: vec![],
});
self.add_group(X86DiagnosticGroup {
name: "x86-abi-struct-passing".into(),
flag: "-Wx86-abi-struct-passing".into(),
enabled_by_default: true,
description: "Warn about struct passing ABI violations".into(),
members: vec![
X86DiagID::ABIStructTooLarge,
X86DiagID::ABIStructPassedInMem,
X86DiagID::ABIStructSplitAcrossRegs,
X86DiagID::ABIEmptyStructPass,
X86DiagID::ABIZeroWidthBitfield,
X86DiagID::ABIUnalignedFieldPass,
X86DiagID::ABIPackedStructPass,
X86DiagID::ABIUnionPass,
X86DiagID::ABIBitfieldStraddle,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-abi-calling-conv".into(),
flag: "-Wx86-abi-calling-conv".into(),
enabled_by_default: true,
description: "Warn about calling convention issues".into(),
members: vec![
X86DiagID::ABIMismatchedCallingConv,
X86DiagID::ABIUnknownCallingConv,
X86DiagID::ABICallingConvNotSupported,
X86DiagID::ABIFastcallTooManyArgs,
X86DiagID::ABIVectorcallAlignment,
X86DiagID::ABIVectorcallTypeUnsupported,
X86DiagID::ABIRegcallNotEnoughRegs,
X86DiagID::ABIThiscallNonMember,
X86DiagID::ABIStdCallVarArgs,
X86DiagID::ABICdeclMismatch,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-abi".into(),
flag: "-Wx86-abi".into(),
enabled_by_default: false,
description: "Enable all X86 ABI diagnostics".into(),
members: vec![],
});
self.add_group(X86DiagnosticGroup {
name: "x86-size".into(),
flag: "-Wx86-size".into(),
enabled_by_default: false,
description: "Warn about code-size and layout issues".into(),
members: vec![
X86DiagID::SizeFunctionTooLarge,
X86DiagID::SizeBasicBlockTooLarge,
X86DiagID::SizeAlignmentExcessive,
X86DiagID::SizeNopPaddingExcessive,
X86DiagID::SizeJumpTableTooLarge,
X86DiagID::SizeELFTextOverflow,
X86DiagID::SizeCOFFTextOverflow,
X86DiagID::SizeSectionOverflow,
X86DiagID::SizeBranchRelaxRequired,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-alignment".into(),
flag: "-Wx86-alignment".into(),
enabled_by_default: false,
description: "Warn about alignment issues".into(),
members: vec![
X86DiagID::AlignUnalignedAccess,
X86DiagID::AlignUnalignedStackAccess,
X86DiagID::AlignUnalignedLoad,
X86DiagID::AlignUnalignedStore,
X86DiagID::AlignMisalignedAtomics,
X86DiagID::AlignLockPrefixAlign,
X86DiagID::AlignSIMDUnalignedAccess,
X86DiagID::AlignAVXUnalignedAccess,
X86DiagID::AlignAVX512UnalignedAccess,
X86DiagID::AlignDataAlign,
X86DiagID::AlignCodeAlign,
X86DiagID::AlignStackAlign,
X86DiagID::AlignStructAlign,
X86DiagID::AlignCacheLineBoundary,
X86DiagID::AlignPageBoundary,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-inline-asm".into(),
flag: "-Wx86-inline-asm".into(),
enabled_by_default: false,
description: "Warn about X86 inline assembly issues".into(),
members: vec![
X86DiagID::InlineAsmParseError,
X86DiagID::InlineAsmInvalidInstruction,
X86DiagID::InlineAsmInvalidOperand,
X86DiagID::InlineAsmInvalidConstraint,
X86DiagID::InlineAsmClobberConflict,
X86DiagID::InlineAsmRegisterClobbered,
X86DiagID::InlineAsmTooManyOperands,
X86DiagID::InlineAsmSizeMismatch,
X86DiagID::InlineAsmUnsupportedConstraint,
X86DiagID::InlineAsmFramePointerClobber,
X86DiagID::InlineAsmStackPointerClobber,
X86DiagID::InlineAsmReservedRegister,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-vector".into(),
flag: "-Wx86-vector".into(),
enabled_by_default: false,
description: "Warn about X86 vector/SIMD issues".into(),
members: vec![
X86DiagID::VectorWidthMismatch,
X86DiagID::VectorTypeMismatch,
X86DiagID::VectorElementCountMismatch,
X86DiagID::VectorShuffleMaskInvalid,
X86DiagID::VectorShuffleMaskOutOfRange,
X86DiagID::VectorInsertIndexOutOfRange,
X86DiagID::VectorExtractIndexOutOfRange,
X86DiagID::VectorGatherScatterAlign,
X86DiagID::VectorGatherUnsupported,
X86DiagID::VectorScatterUnsupported,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-linker".into(),
flag: "-Wx86-linker".into(),
enabled_by_default: false,
description: "Warn about X86 linker/relocation issues".into(),
members: vec![
X86DiagID::LinkerRelocationOverflow,
X86DiagID::LinkerGOTOverflow,
X86DiagID::LinkerPLTOverflow,
X86DiagID::LinkerTLSOverflow,
X86DiagID::LinkerUnresolvedSymbol,
X86DiagID::LinkerSectionMismatch,
X86DiagID::LinkerTrampolineNeeded,
],
});
self.add_group(X86DiagnosticGroup {
name: "x86-all".into(),
flag: "-Wx86-all".into(),
enabled_by_default: false,
description: "Enable all X86-specific diagnostics".into(),
members: vec![],
});
}
fn add_group(&mut self, group: X86DiagnosticGroup) {
for &id in &group.members {
self.id_to_groups
.entry(id)
.or_default()
.push(group.name.clone());
}
self.groups.insert(group.name.clone(), group);
}
pub fn groups_for(&self, id: X86DiagID) -> Vec<&X86DiagnosticGroup> {
self.id_to_groups
.get(&id)
.map(|names| names.iter().filter_map(|n| self.groups.get(n)).collect())
.unwrap_or_default()
}
pub fn has_group(&self, name: &str) -> bool {
self.groups.contains_key(name)
}
pub fn group_names(&self) -> Vec<&str> {
self.groups.keys().map(|s| s.as_str()).collect()
}
}
impl Default for X86DiagnosticGroupRegistry {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct X86BackendDiagnostic {
pub id: X86DiagID,
pub severity: DiagSeverity,
pub message: String,
pub location: Option<ClangSourceLocation>,
pub ranges: Vec<SourceRange>,
pub notes: Vec<String>,
pub fixits: Vec<String>,
pub args: Vec<String>,
}
impl X86BackendDiagnostic {
pub fn new(id: X86DiagID) -> Self {
Self {
severity: X86DiagnosticCatalog::default_severity(id),
message: String::new(),
id,
location: None,
ranges: Vec::new(),
notes: Vec::new(),
fixits: Vec::new(),
args: Vec::new(),
}
}
pub fn at(mut self, loc: ClangSourceLocation) -> Self {
self.location = Some(loc);
self
}
pub fn add_range(mut self, range: SourceRange) -> Self {
self.ranges.push(range);
self
}
pub fn add_note(mut self, note: impl Into<String>) -> Self {
self.notes.push(note.into());
self
}
pub fn with_args(mut self, args: Vec<String>) -> Self {
self.args = args;
self
}
pub fn build(mut self) -> Self {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
for arg in &self.args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
self.message = msg;
self
}
pub fn format(&self) -> String {
let sev = match self.severity {
DiagSeverity::Error => "error",
DiagSeverity::Warning => "warning",
DiagSeverity::Note => "note",
DiagSeverity::Remark => "remark",
DiagSeverity::Fatal => "fatal error",
DiagSeverity::Ignored => "ignored",
};
let loc_str = match &self.location {
Some(loc) => format!("{}:{}:{}", loc.file.display(), loc.line, loc.column),
None => String::new(),
};
if loc_str.is_empty() {
format!("{}: {}", sev, self.message)
} else {
format!("{}: {}: {}", loc_str, sev, self.message)
}
}
}
impl fmt::Display for X86BackendDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86TargetFeatureDiag {
pub feature: String,
pub suggested_flag: String,
pub cpu: Option<String>,
pub is_error: bool,
pub id: X86DiagID,
}
impl X86TargetFeatureDiag {
pub fn missing_feature(feature: &str) -> Self {
let id = Self::id_for_feature(feature);
Self {
feature: feature.to_string(),
suggested_flag: format!("-m{}", feature.replace('.', "").to_lowercase()),
cpu: None,
is_error: false,
id,
}
}
pub fn missing_for_cpu(feature: &str, cpu: &str) -> Self {
let mut diag = Self::missing_feature(feature);
diag.cpu = Some(cpu.to_string());
diag.id = X86DiagID::FeatureMissingForCPU;
diag
}
pub fn requires_64bit(feature: &str) -> Self {
Self {
feature: feature.to_string(),
suggested_flag: "-m64".to_string(),
cpu: None,
is_error: true,
id: X86DiagID::FeatureRequires64Bit,
}
}
pub fn conflicting(f1: &str, f2: &str) -> Self {
Self {
feature: format!("{} and {}", f1, f2),
suggested_flag: String::new(),
cpu: None,
is_error: true,
id: X86DiagID::FeatureConflicting,
}
}
pub fn deprecated(feature: &str) -> Self {
Self {
feature: feature.to_string(),
suggested_flag: String::new(),
cpu: None,
is_error: false,
id: X86DiagID::FeatureDeprecated,
}
}
fn id_for_feature(feature: &str) -> X86DiagID {
match feature.to_lowercase().as_str() {
"sse" | "sse1" => X86DiagID::FeatureMissingSSE,
"sse2" => X86DiagID::FeatureMissingSSE2,
"sse3" => X86DiagID::FeatureMissingSSE3,
"ssse3" => X86DiagID::FeatureMissingSSSE3,
"sse4.1" | "sse41" => X86DiagID::FeatureMissingSSE41,
"sse4.2" | "sse42" => X86DiagID::FeatureMissingSSE42,
"avx" => X86DiagID::FeatureMissingAVX,
"avx2" => X86DiagID::FeatureMissingAVX2,
"avx512f" => X86DiagID::FeatureMissingAVX512F,
"avx512bw" => X86DiagID::FeatureMissingAVX512BW,
"avx512dq" => X86DiagID::FeatureMissingAVX512DQ,
"avx512vl" => X86DiagID::FeatureMissingAVX512VL,
"avx512cd" => X86DiagID::FeatureMissingAVX512CD,
"avx512er" => X86DiagID::FeatureMissingAVX512ER,
"avx512pf" => X86DiagID::FeatureMissingAVX512PF,
"avx512bf16" => X86DiagID::FeatureMissingAVX512BF16,
"avx512fp16" => X86DiagID::FeatureMissingAVX512FP16,
"avx512vbmi" => X86DiagID::FeatureMissingAVX512VBMI,
"avx512vnni" => X86DiagID::FeatureMissingAVX512VNNI,
"avx512bitalg" => X86DiagID::FeatureMissingAVX512BITALG,
"avx512vpopcntdq" => X86DiagID::FeatureMissingAVX512VPOPCNTDQ,
"avx5124fmaps" => X86DiagID::FeatureMissingAVX5124FMAPS,
"avx5124vnniw" => X86DiagID::FeatureMissingAVX5124VNNIW,
"avx512ifma" => X86DiagID::FeatureMissingAVX512IFMA,
"fma" => X86DiagID::FeatureMissingFMA,
"fma4" => X86DiagID::FeatureMissingFMA4,
"f16c" => X86DiagID::FeatureMissingF16C,
"xop" => X86DiagID::FeatureMissingXOP,
"mmx" => X86DiagID::FeatureMissingMMX,
"3dnow" => X86DiagID::FeatureMissing3DNOW,
"3dnowa" => X86DiagID::FeatureMissing3DNOWA,
"bmi" | "bmi1" => X86DiagID::FeatureMissingBMI,
"bmi2" => X86DiagID::FeatureMissingBMI2,
"lzcnt" => X86DiagID::FeatureMissingLZCNT,
"popcnt" => X86DiagID::FeatureMissingPOPCNT,
"tbm" => X86DiagID::FeatureMissingTBM,
"aes" | "aes-ni" => X86DiagID::FeatureMissingAES,
"pclmul" | "pclmulqdq" => X86DiagID::FeatureMissingPCLMUL,
"sha" => X86DiagID::FeatureMissingSHA,
"sha512" => X86DiagID::FeatureMissingSHA512,
"sm3" => X86DiagID::FeatureMissingSM3,
"sm4" => X86DiagID::FeatureMissingSM4,
"gfni" => X86DiagID::FeatureMissingGFNI,
"vaes" => X86DiagID::FeatureMissingVAES,
"vpclmulqdq" => X86DiagID::FeatureMissingVPCLMULQDQ,
"rdrand" => X86DiagID::FeatureMissingRDRAND,
"rdseed" => X86DiagID::FeatureMissingRDSEED,
"adx" => X86DiagID::FeatureMissingADX,
"rtm" => X86DiagID::FeatureMissingRTM,
"hle" => X86DiagID::FeatureMissingHLE,
"sgx" => X86DiagID::FeatureMissingSGX,
"cet" => X86DiagID::FeatureMissingCET,
"xsave" => X86DiagID::FeatureMissingXSAVE,
"xsaveopt" => X86DiagID::FeatureMissingXSAVEOPT,
"xsavec" => X86DiagID::FeatureMissingXSAVEC,
"xsaves" => X86DiagID::FeatureMissingXSAVES,
"fsgsbase" => X86DiagID::FeatureMissingFSGSBASE,
"movbe" => X86DiagID::FeatureMissingMOVBE,
"movdiri" => X86DiagID::FeatureMissingMOVDIRI,
"movdir64b" => X86DiagID::FeatureMissingMOVDIR64B,
"enqcmd" => X86DiagID::FeatureMissingENQCMD,
"serialize" => X86DiagID::FeatureMissingSERIALIZE,
"tsxldtrk" => X86DiagID::FeatureMissingTSXLDTRK,
"waitpkg" => X86DiagID::FeatureMissingWAITPKG,
"cldemote" => X86DiagID::FeatureMissingCLDEMOTE,
"clflushopt" => X86DiagID::FeatureMissingCLFLUSHOPT,
"clwb" => X86DiagID::FeatureMissingCLWB,
"clzero" => X86DiagID::FeatureMissingCLZERO,
"mwaitx" => X86DiagID::FeatureMissingMWAITX,
"monitorx" => X86DiagID::FeatureMissingMONITORX,
"pku" => X86DiagID::FeatureMissingPKU,
"smap" => X86DiagID::FeatureMissingSMAP,
"smep" => X86DiagID::FeatureMissingSMEP,
"mpx" => X86DiagID::FeatureMissingMPX,
"ptwrite" => X86DiagID::FeatureMissingPTWRITE,
"invpcid" => X86DiagID::FeatureMissingINVPCID,
"prefetchwt1" => X86DiagID::FeatureMissingPREFETCHWT1,
"prefetchw" => X86DiagID::FeatureMissingPREFETCHW,
"prefetchi" => X86DiagID::FeatureMissingPREFETCHI,
"amx-bf16" => X86DiagID::FeatureMissingAMX_BF16,
"amx-int8" => X86DiagID::FeatureMissingAMX_INT8,
"amx-tile" => X86DiagID::FeatureMissingAMX_TILE,
"amx-fp16" => X86DiagID::FeatureMissingAMX_FP16,
"amx-complex" => X86DiagID::FeatureMissingAMX_COMPLEX,
"x87" | "80387" => X86DiagID::FeatureMissingX87,
"cmov" => X86DiagID::FeatureMissingCMOV,
"sahf" => X86DiagID::FeatureMissingSAHF,
"rdpid" => X86DiagID::FeatureMissingRDPID,
"rdpru" => X86DiagID::FeatureMissingRDPRU,
"hreset" => X86DiagID::FeatureMissingHRESET,
"uintr" => X86DiagID::FeatureMissingUINTR,
"kl" => X86DiagID::FeatureMissingKL,
"widekl" => X86DiagID::FeatureMissingWIDEKL,
"cmpccxadd" => X86DiagID::FeatureMissingCMPCCXADD,
"raoint" => X86DiagID::FeatureMissingRAOINT,
"avxneconvert" => X86DiagID::FeatureMissingAVX_NE_CONVERT,
"avxvnni" => X86DiagID::FeatureMissingAVX_VNNI,
"avxvnniint8" => X86DiagID::FeatureMissingAVX_VNNI_INT8,
_ => X86DiagID::FeatureMissingSSE2, }
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let args: Vec<String> = {
let mut v = vec![self.feature.clone()];
if let Some(ref cpu) = self.cpu {
v.push(cpu.clone());
}
v
};
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
if !self.suggested_flag.is_empty() {
msg.push_str(&format!(" (suggested: {})", self.suggested_flag));
}
msg
}
}
impl fmt::Display for X86TargetFeatureDiag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86ABIDiagnostic {
pub id: X86DiagID,
pub function_name: Option<String>,
pub type_name: Option<String>,
pub size_bytes: Option<u64>,
pub calling_convention: Option<String>,
pub detail: Option<String>,
}
impl X86ABIDiagnostic {
pub fn new(id: X86DiagID) -> Self {
Self {
id,
function_name: None,
type_name: None,
size_bytes: None,
calling_convention: None,
detail: None,
}
}
pub fn with_function(mut self, name: &str) -> Self {
self.function_name = Some(name.to_string());
self
}
pub fn with_type(mut self, name: &str) -> Self {
self.type_name = Some(name.to_string());
self
}
pub fn with_size(mut self, bytes: u64) -> Self {
self.size_bytes = Some(bytes);
self
}
pub fn with_calling_conv(mut self, cc: &str) -> Self {
self.calling_convention = Some(cc.to_string());
self
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let mut args: Vec<String> = Vec::new();
if let Some(ref f) = self.function_name {
args.push(f.clone());
}
if let Some(ref t) = self.type_name {
args.push(t.clone());
}
if let Some(s) = self.size_bytes {
args.push(s.to_string());
}
if let Some(ref cc) = self.calling_convention {
args.push(cc.clone());
}
if let Some(ref d) = self.detail {
args.push(d.clone());
}
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
msg
}
}
impl fmt::Display for X86ABIDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86SizeDiagnostic {
pub id: X86DiagID,
pub function_name: Option<String>,
pub block_name: Option<String>,
pub current_size: Option<u64>,
pub limit: Option<u64>,
pub offset: Option<u64>,
pub detail: Option<String>,
}
impl X86SizeDiagnostic {
pub fn new(id: X86DiagID) -> Self {
Self {
id,
function_name: None,
block_name: None,
current_size: None,
limit: None,
offset: None,
detail: None,
}
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let mut args: Vec<String> = Vec::new();
if let Some(ref f) = self.function_name {
args.push(f.clone());
}
if let Some(ref b) = self.block_name {
args.push(b.clone());
}
if let Some(s) = self.current_size {
args.push(s.to_string());
}
if let Some(l) = self.limit {
args.push(l.to_string());
}
if let Some(o) = self.offset {
args.push(o.to_string());
}
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
msg
}
}
impl fmt::Display for X86SizeDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86AlignDiagnostic {
pub id: X86DiagID,
pub function_name: Option<String>,
pub variable_name: Option<String>,
pub required_alignment: Option<u32>,
pub current_alignment: Option<u32>,
pub offset: Option<u64>,
pub access_size: Option<u32>,
}
impl X86AlignDiagnostic {
pub fn new(id: X86DiagID) -> Self {
Self {
id,
function_name: None,
variable_name: None,
required_alignment: None,
current_alignment: None,
offset: None,
access_size: None,
}
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let mut args: Vec<String> = Vec::new();
if let Some(ref f) = self.function_name {
args.push(f.clone());
}
if let Some(ref v) = self.variable_name {
args.push(v.clone());
}
if let Some(r) = self.required_alignment {
args.push(r.to_string());
}
if let Some(c) = self.current_alignment {
args.push(c.to_string());
}
if let Some(o) = self.offset {
args.push(o.to_string());
}
if let Some(s) = self.access_size {
args.push(s.to_string());
}
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
msg
}
}
impl fmt::Display for X86AlignDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86InlineAsmDiag {
pub id: X86DiagID,
pub asm_string: Option<String>,
pub instruction: Option<String>,
pub operand: Option<String>,
pub constraint: Option<String>,
pub register_name: Option<String>,
pub detail: Option<String>,
}
impl X86InlineAsmDiag {
pub fn new(id: X86DiagID) -> Self {
Self {
id,
asm_string: None,
instruction: None,
operand: None,
constraint: None,
register_name: None,
detail: None,
}
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let mut args: Vec<String> = Vec::new();
if let Some(ref s) = self.asm_string {
args.push(s.clone());
}
if let Some(ref i) = self.instruction {
args.push(i.clone());
}
if let Some(ref o) = self.operand {
args.push(o.clone());
}
if let Some(ref c) = self.constraint {
args.push(c.clone());
}
if let Some(ref r) = self.register_name {
args.push(r.clone());
}
if let Some(ref d) = self.detail {
args.push(d.clone());
}
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
msg
}
}
impl fmt::Display for X86InlineAsmDiag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
#[derive(Debug, Clone)]
pub struct X86VectorDiag {
pub id: X86DiagID,
pub operation: Option<String>,
pub element_type: Option<String>,
pub expected_width: Option<u32>,
pub actual_width: Option<u32>,
pub index: Option<u32>,
pub limit: Option<u32>,
pub detail: Option<String>,
}
impl X86VectorDiag {
pub fn new(id: X86DiagID) -> Self {
Self {
id,
operation: None,
element_type: None,
expected_width: None,
actual_width: None,
index: None,
limit: None,
detail: None,
}
}
pub fn format(&self) -> String {
let template = X86DiagnosticCatalog::message_for(self.id);
let mut msg = template.to_string();
let mut args: Vec<String> = Vec::new();
if let Some(ref op) = self.operation {
args.push(op.clone());
}
if let Some(ref et) = self.element_type {
args.push(et.clone());
}
if let Some(ew) = self.expected_width {
args.push(ew.to_string());
}
if let Some(aw) = self.actual_width {
args.push(aw.to_string());
}
if let Some(idx) = self.index {
args.push(idx.to_string());
}
if let Some(lim) = self.limit {
args.push(lim.to_string());
}
for arg in &args {
if let Some(pos) = msg.find("{}") {
msg.replace_range(pos..pos + 2, arg);
}
}
msg
}
}
impl fmt::Display for X86VectorDiag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.format())
}
}
pub struct X86OptimizationRemarks {
pub remarks: Vec<X86BackendDiagnostic>,
pub enabled: bool,
pub filter: Option<String>,
}
impl X86OptimizationRemarks {
pub fn new() -> Self {
Self {
remarks: Vec::new(),
enabled: false,
filter: None,
}
}
pub fn enable(&mut self) {
self.enabled = true;
}
pub fn set_filter(&mut self, pass: &str) {
self.filter = Some(pass.to_string());
}
pub fn emit(&mut self, id: X86DiagID, args: Vec<String>) {
if !self.enabled {
return;
}
let diag = X86BackendDiagnostic::new(id)
.with_args(args.clone())
.build();
if let Some(ref filter) = self.filter {
let pass_name = diag.message.split_whitespace().next().unwrap_or("");
if !pass_name.contains(filter.as_str()) {
return;
}
}
self.remarks.push(diag);
}
pub fn emit_isel_success(&mut self, ir_instr: &str, x86_instr: &str, func: &str) {
self.emit(
X86DiagID::OptX86ISelSuccess,
vec![
ir_instr.to_string(),
x86_instr.to_string(),
func.to_string(),
],
);
}
pub fn emit_peephole(&mut self, before: &str, after: &str, func: &str) {
self.emit(
X86DiagID::OptX86PeepholeApplied,
vec![before.to_string(), after.to_string(), func.to_string()],
);
}
pub fn emit_macro_fusion(&mut self, instr1: &str, instr2: &str, func: &str) {
self.emit(
X86DiagID::OptX86MacroFusion,
vec![instr1.to_string(), instr2.to_string(), func.to_string()],
);
}
pub fn emit_regalloc_spill(&mut self, vreg: u32, func: &str) {
self.emit(
X86DiagID::BackendRegallocSpill,
vec![vreg.to_string(), func.to_string()],
);
}
pub fn emit_block_placement(&mut self, block: &str, offset: u64, probability: f64) {
self.emit(
X86DiagID::OptX86MachineBlockPlacement,
vec![
block.to_string(),
offset.to_string(),
format!("{:.2}", probability),
],
);
}
pub fn count(&self) -> usize {
self.remarks.len()
}
pub fn count_by_severity(&self, severity: DiagSeverity) -> usize {
self.remarks
.iter()
.filter(|r| r.severity == severity)
.count()
}
pub fn format_all(&self) -> Vec<String> {
self.remarks.iter().map(|r| r.format()).collect()
}
pub fn to_yaml(&self) -> String {
let mut out = String::from("--- !X86OptimizationRemarks\n");
out.push_str(&format!("Remarks:\n"));
for (i, r) in self.remarks.iter().enumerate() {
out.push_str(&format!(
" - Pass: {}\n",
X86DiagnosticCatalog::category(r.id)
));
out.push_str(&format!(
" Name: {}\n",
X86DiagnosticCatalog::flag_name(r.id)
));
out.push_str(&format!(" Function: {}\n", ""));
out.push_str(&format!(" Args:\n"));
for arg in &r.args {
out.push_str(&format!(" - '{}'\n", arg));
}
}
out
}
pub fn to_json(&self) -> String {
let mut items = Vec::new();
for r in &self.remarks {
items.push(format!(
r#"{{"Pass":"{}","Name":"{}","DebugLoc":{{}},"Function":"","Args":{{}}}}"#,
X86DiagnosticCatalog::category(r.id),
X86DiagnosticCatalog::flag_name(r.id)
));
}
format!("[{}]", items.join(","))
}
pub fn clear(&mut self) {
self.remarks.clear();
}
}
impl Default for X86OptimizationRemarks {
fn default() -> Self {
Self::new()
}
}
pub struct X86DiagnosticRenderer<W: Write> {
pub writer: W,
pub use_colors: bool,
pub show_column: bool,
pub show_source_line: bool,
pub show_carets: bool,
pub show_fixits: bool,
pub show_option_names: bool,
pub error_count: usize,
pub warning_count: usize,
pub remark_count: usize,
}
const ANSI_RED: &str = "\x1b[31m";
const ANSI_GREEN: &str = "\x1b[32m";
const ANSI_YELLOW: &str = "\x1b[33m";
const ANSI_BLUE: &str = "\x1b[34m";
const ANSI_MAGENTA: &str = "\x1b[35m";
const ANSI_CYAN: &str = "\x1b[36m";
const ANSI_WHITE: &str = "\x1b[37m";
const ANSI_BOLD: &str = "\x1b[1m";
const ANSI_RESET: &str = "\x1b[0m";
impl<W: Write> X86DiagnosticRenderer<W> {
pub fn new(writer: W) -> Self {
Self {
writer,
use_colors: false,
show_column: true,
show_source_line: true,
show_carets: true,
show_fixits: true,
show_option_names: true,
error_count: 0,
warning_count: 0,
remark_count: 0,
}
}
pub fn render(&mut self, diag: &X86BackendDiagnostic) -> io::Result<()> {
match diag.severity {
DiagSeverity::Error | DiagSeverity::Fatal => self.error_count += 1,
DiagSeverity::Warning => self.warning_count += 1,
DiagSeverity::Remark => self.remark_count += 1,
_ => {}
}
if let Some(ref loc) = diag.location {
write!(
self.writer,
"{}",
self.colorize_filename(&loc.file.display().to_string())
)?;
write!(self.writer, ":")?;
write!(self.writer, "{}", loc.line)?;
if self.show_column {
write!(self.writer, ":{}", loc.column)?;
}
write!(self.writer, ": ")?;
}
let severity_str = match diag.severity {
DiagSeverity::Error => "error",
DiagSeverity::Warning => "warning",
DiagSeverity::Note => "note",
DiagSeverity::Remark => "remark",
DiagSeverity::Fatal => "fatal error",
DiagSeverity::Ignored => "ignored",
};
let severity_colored = match diag.severity {
DiagSeverity::Error | DiagSeverity::Fatal => {
format!("{}", self.colorize_error(severity_str))
}
DiagSeverity::Warning => {
format!("{}", self.colorize_warning(severity_str))
}
DiagSeverity::Note => format!("{}", self.colorize_note(severity_str)),
_ => severity_str.to_string(),
};
write!(self.writer, "{}: ", severity_colored)?;
writeln!(self.writer, "{}", diag.message)?;
if self.show_option_names {
writeln!(
self.writer,
" {}",
self.colorize_note(&X86DiagnosticCatalog::flag_name(diag.id))
)?;
}
for note in &diag.notes {
writeln!(self.writer, "note: {}", note)?;
}
if self.show_fixits && !diag.fixits.is_empty() {
for fix in &diag.fixits {
writeln!(self.writer, "{}", self.colorize_fixit(fix))?;
}
}
Ok(())
}
pub fn render_snippet(
&mut self,
source_lines: &[&str],
primary_line: usize,
ranges: &[(usize, usize)],
) -> io::Result<()> {
if !self.show_source_line {
return Ok(());
}
let ctx_start = if primary_line > 1 {
primary_line - 1
} else {
0
};
let ctx_end = (primary_line + 1).min(source_lines.len() - 1);
for i in ctx_start..=ctx_end {
let is_primary = i == primary_line;
let line_num_str = format!("{:4} |", i + 1);
write!(self.writer, "{}", self.colorize_line_number(&line_num_str))?;
if let Some(line) = source_lines.get(i) {
writeln!(self.writer, " {}", line)?;
if is_primary && self.show_carets {
write!(self.writer, " | ")?;
let caret_line = self.build_caret_line(line, ranges);
writeln!(self.writer, "{}", self.colorize_caret(&caret_line))?;
}
} else {
writeln!(self.writer)?;
}
}
Ok(())
}
fn build_caret_line(&self, line: &str, ranges: &[(usize, usize)]) -> String {
let mut chars: Vec<char> = vec![' '; line.len()];
for &(start, end) in ranges {
let s = start.min(line.len());
let e = end.min(line.len()).max(s);
for i in s..e {
if i < chars.len() {
if i == s {
chars[i] = '^';
} else {
chars[i] = '~';
}
}
}
}
chars.iter().collect::<String>().trim_end().to_string()
}
fn colorize_error<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}{}", ANSI_BOLD, ANSI_RED, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_warning<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}{}", ANSI_BOLD, ANSI_MAGENTA, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_note<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}", ANSI_CYAN, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_caret<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}", ANSI_GREEN, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_fixit<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}", ANSI_GREEN, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_filename<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}", ANSI_BOLD, text, ANSI_RESET)
} else {
text.to_string()
}
}
fn colorize_line_number<'a>(&self, text: &'a str) -> String {
if self.use_colors {
format!("{}{}{}", ANSI_BLUE, text, ANSI_RESET)
} else {
text.to_string()
}
}
}
pub struct X86DiagnosticEmitter {
pub diagnostics: Vec<X86BackendDiagnostic>,
pub remarks_enabled: bool,
pub max_errors: Option<usize>,
pub severity_map: X86DiagnosticSeverityMap,
pub suppressor: X86DiagnosticSuppressor,
pub groups: X86DiagnosticGroupRegistry,
}
impl X86DiagnosticEmitter {
pub fn new() -> Self {
Self {
diagnostics: Vec::new(),
remarks_enabled: false,
max_errors: None,
severity_map: X86DiagnosticSeverityMap::new(),
suppressor: X86DiagnosticSuppressor::new(),
groups: X86DiagnosticGroupRegistry::new(),
}
}
pub fn enable_remarks(&mut self) {
self.remarks_enabled = true;
}
pub fn set_max_errors(&mut self, max: usize) {
self.max_errors = Some(max);
}
pub fn error_limit_reached(&self) -> bool {
if let Some(max) = self.max_errors {
self.error_count() >= max
} else {
false
}
}
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|d| d.severity == DiagSeverity::Error || d.severity == DiagSeverity::Fatal)
}
pub fn diagnostic_count(&self) -> usize {
self.diagnostics.len()
}
pub fn error_count(&self) -> usize {
self.diagnostics
.iter()
.filter(|d| d.severity == DiagSeverity::Error || d.severity == DiagSeverity::Fatal)
.count()
}
pub fn warning_count(&self) -> usize {
self.diagnostics
.iter()
.filter(|d| d.severity == DiagSeverity::Warning)
.count()
}
fn emit_diag(&mut self, id: X86DiagID, args: Vec<String>) {
if self.suppressor.is_suppressed(id) {
return;
}
if self.error_limit_reached() {
return;
}
let effective_severity = self.severity_map.effective_severity(id);
let diag = X86BackendDiagnostic::new(id).with_args(args).build();
let mut diag = diag;
diag.severity = effective_severity;
self.diagnostics.push(diag);
}
pub fn emit_isel_failure(&mut self, ir_instr: &str, func: &str) {
self.emit_diag(
X86DiagID::BackendISelFail,
vec![ir_instr.to_string(), func.to_string()],
);
}
pub fn emit_cannot_select(&mut self, ir_instr: &str, node: &str, func: &str) {
self.emit_diag(
X86DiagID::BackendCannotSelect,
vec![ir_instr.to_string(), node.to_string(), func.to_string()],
);
}
pub fn emit_regalloc_spill(&mut self, vreg: u32, func: &str) {
self.emit_diag(
X86DiagID::BackendRegallocSpill,
vec![vreg.to_string(), func.to_string()],
);
}
pub fn emit_feature_missing(&mut self, feature: &str) {
let id = X86TargetFeatureDiag::id_for_feature(feature);
let diag = X86TargetFeatureDiag::missing_feature(feature);
self.emit_diag(id, vec![feature.to_string()]);
}
pub fn emit_feature_deprecated(&mut self, feature: &str) {
self.emit_diag(X86DiagID::FeatureDeprecated, vec![feature.to_string()]);
}
pub fn emit_feature_conflicting(&mut self, f1: &str, f2: &str) {
self.emit_diag(
X86DiagID::FeatureConflicting,
vec![f1.to_string(), f2.to_string()],
);
}
pub fn emit_abi_struct_too_large(&mut self, type_name: &str, size: u64) {
self.emit_diag(
X86DiagID::ABIStructTooLarge,
vec![type_name.to_string(), size.to_string()],
);
}
pub fn emit_abi_mismatched_calling_conv(&mut self, decl: &str, def: &str) {
self.emit_diag(
X86DiagID::ABIMismatchedCallingConv,
vec![decl.to_string(), def.to_string()],
);
}
pub fn emit_abi_unknown_calling_conv(&mut self, cc: &str) {
self.emit_diag(X86DiagID::ABIUnknownCallingConv, vec![cc.to_string()]);
}
pub fn emit_alignment_warning(
&mut self,
func: &str,
access_size: u32,
alignment: u32,
offset: u64,
) {
self.emit_diag(
X86DiagID::AlignUnalignedAccess,
vec![
func.to_string(),
access_size.to_string(),
alignment.to_string(),
offset.to_string(),
],
);
}
pub fn emit_simd_unaligned_access(&mut self, func: &str) {
self.emit_diag(X86DiagID::AlignSIMDUnalignedAccess, vec![func.to_string()]);
}
pub fn emit_inline_asm_invalid_instruction(&mut self, mnemonic: &str) {
self.emit_diag(
X86DiagID::InlineAsmInvalidInstruction,
vec![mnemonic.to_string()],
);
}
pub fn emit_inline_asm_invalid_constraint(&mut self, constraint: &str, operand: &str) {
self.emit_diag(
X86DiagID::InlineAsmInvalidConstraint,
vec![constraint.to_string(), operand.to_string()],
);
}
pub fn emit_inline_asm_clobber_conflict(&mut self, reg: &str) {
self.emit_diag(X86DiagID::InlineAsmClobberConflict, vec![reg.to_string()]);
}
pub fn emit_inline_asm_sp_clobber(&mut self) {
self.emit_diag(X86DiagID::InlineAsmStackPointerClobber, vec![]);
}
pub fn emit_vector_width_mismatch(&mut self, op: &str, expected: u32, actual: u32) {
self.emit_diag(
X86DiagID::VectorWidthMismatch,
vec![op.to_string(), expected.to_string(), actual.to_string()],
);
}
pub fn emit_vector_shuffle_invalid(&mut self, elem_type: &str, index: u32, limit: u32) {
self.emit_diag(
X86DiagID::VectorShuffleMaskInvalid,
vec![elem_type.to_string(), index.to_string(), limit.to_string()],
);
}
pub fn emit_vector_gather_unsupported(&mut self, elem_type: &str) {
self.emit_diag(
X86DiagID::VectorGatherUnsupported,
vec![elem_type.to_string()],
);
}
pub fn emit_function_too_large(&mut self, func: &str, size: u64, limit: u64) {
self.emit_diag(
X86DiagID::SizeFunctionTooLarge,
vec![func.to_string(), size.to_string(), limit.to_string()],
);
}
pub fn emit_isel_success(&mut self, ir_instr: &str, x86_instr: &str, func: &str) {
if !self.remarks_enabled {
return;
}
self.emit_diag(
X86DiagID::OptX86ISelSuccess,
vec![
ir_instr.to_string(),
x86_instr.to_string(),
func.to_string(),
],
);
}
pub fn emit_peephole_applied(&mut self, before: &str, after: &str, func: &str) {
if !self.remarks_enabled {
return;
}
self.emit_diag(
X86DiagID::OptX86PeepholeApplied,
vec![before.to_string(), after.to_string(), func.to_string()],
);
}
pub fn emit_macro_fusion(&mut self, i1: &str, i2: &str, func: &str) {
if !self.remarks_enabled {
return;
}
self.emit_diag(
X86DiagID::OptX86MacroFusion,
vec![i1.to_string(), i2.to_string(), func.to_string()],
);
}
pub fn format_all(&self) -> Vec<String> {
self.diagnostics.iter().map(|d| d.format()).collect()
}
pub fn clear(&mut self) {
self.diagnostics.clear();
}
}
impl Default for X86DiagnosticEmitter {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct X86DiagnosticMatch {
pub id: X86DiagID,
pub severity: DiagSeverity,
pub substring: String,
pub matched: bool,
}
pub struct X86DiagnosticMatcher {
pub expectations: Vec<X86DiagnosticMatch>,
pub unmatched_diagnostics: Vec<X86BackendDiagnostic>,
}
impl X86DiagnosticMatcher {
pub fn new() -> Self {
Self {
expectations: Vec::new(),
unmatched_diagnostics: Vec::new(),
}
}
pub fn expect(&mut self, id: X86DiagID, severity: DiagSeverity, substring: &str) {
self.expectations.push(X86DiagnosticMatch {
id,
severity,
substring: substring.to_string(),
matched: false,
});
}
pub fn expect_error(&mut self, id: X86DiagID, substring: &str) {
self.expect(id, DiagSeverity::Error, substring);
}
pub fn expect_warning(&mut self, id: X86DiagID, substring: &str) {
self.expect(id, DiagSeverity::Warning, substring);
}
pub fn expect_remark(&mut self, id: X86DiagID, substring: &str) {
self.expect(id, DiagSeverity::Remark, substring);
}
pub fn expected_count(&self) -> usize {
self.expectations.len()
}
pub fn matches(&mut self, diag: &X86BackendDiagnostic) -> Option<usize> {
for (i, exp) in self.expectations.iter_mut().enumerate() {
if exp.matched {
continue;
}
if exp.id == diag.id
&& exp.severity == diag.severity
&& diag.message.contains(&exp.substring)
{
exp.matched = true;
return Some(i);
}
}
self.unmatched_diagnostics.push(diag.clone());
None
}
pub fn run_all(&mut self, diagnostics: &mut Vec<X86BackendDiagnostic>) -> Result<(), String> {
for diag in diagnostics.iter() {
self.matches(diag);
}
let unmatched: Vec<_> = self.expectations.iter().filter(|e| !e.matched).collect();
if !unmatched.is_empty() {
let msgs: Vec<String> = unmatched
.iter()
.map(|e| {
format!(
"Expected {:?} {:?} containing '{}'",
e.severity, e.id, e.substring
)
})
.collect();
return Err(format!(
"{} unmatched diagnostic expectations:\n {}",
unmatched.len(),
msgs.join("\n ")
));
}
Ok(())
}
pub fn reset(&mut self) {
self.expectations.clear();
self.unmatched_diagnostics.clear();
}
}
impl Default for X86DiagnosticMatcher {
fn default() -> Self {
Self::new()
}
}
pub struct X86DiagnosticSeverityMap {
pub id_overrides: HashMap<X86DiagID, DiagSeverity>,
pub group_overrides: HashMap<String, DiagSeverity>,
pub suppressed: HashSet<X86DiagID>,
pub groups: X86DiagnosticGroupRegistry,
}
impl X86DiagnosticSeverityMap {
pub fn new() -> Self {
Self {
id_overrides: HashMap::new(),
group_overrides: HashMap::new(),
suppressed: HashSet::new(),
groups: X86DiagnosticGroupRegistry::new(),
}
}
pub fn set_severity(&mut self, id: X86DiagID, severity: DiagSeverity) {
self.id_overrides.insert(id, severity);
}
pub fn set_group_severity(&mut self, group: &str, severity: DiagSeverity) {
self.group_overrides.insert(group.to_string(), severity);
}
pub fn suppress(&mut self, id: X86DiagID) {
self.suppressed.insert(id);
}
pub fn effective_severity(&self, id: X86DiagID) -> DiagSeverity {
if self.suppressed.contains(&id) {
return DiagSeverity::Ignored;
}
if let Some(sev) = self.id_overrides.get(&id) {
return *sev;
}
if let Some(group_names) = self.groups.id_to_groups.get(&id) {
for name in group_names {
if let Some(sev) = self.group_overrides.get(name) {
return *sev;
}
}
}
X86DiagnosticCatalog::default_severity(id)
}
pub fn is_suppressed(&self, id: X86DiagID) -> bool {
self.suppressed.contains(&id)
}
pub fn reset(&mut self, id: X86DiagID) {
self.id_overrides.remove(&id);
self.suppressed.remove(&id);
}
pub fn reset_all(&mut self) {
self.id_overrides.clear();
self.group_overrides.clear();
self.suppressed.clear();
}
}
impl Default for X86DiagnosticSeverityMap {
fn default() -> Self {
Self::new()
}
}
pub struct X86DiagnosticSuppressor {
pub suppressed_ids: HashSet<X86DiagID>,
pub suppressed_groups: HashSet<String>,
pub groups: X86DiagnosticGroupRegistry,
}
impl X86DiagnosticSuppressor {
pub fn new() -> Self {
Self {
suppressed_ids: HashSet::new(),
suppressed_groups: HashSet::new(),
groups: X86DiagnosticGroupRegistry::new(),
}
}
pub fn suppress_id(&mut self, id: X86DiagID) {
self.suppressed_ids.insert(id);
}
pub fn suppress_group(&mut self, group: &str) {
self.suppressed_groups.insert(group.to_string());
}
pub fn unsuppress_id(&mut self, id: X86DiagID) {
self.suppressed_ids.remove(&id);
}
pub fn unsuppress_group(&mut self, group: &str) {
self.suppressed_groups.remove(group);
}
pub fn is_suppressed(&self, id: X86DiagID) -> bool {
if self.suppressed_ids.contains(&id) {
return true;
}
if let Some(group_names) = self.groups.id_to_groups.get(&id) {
for name in group_names {
if self.suppressed_groups.contains(name) {
return true;
}
}
}
false
}
pub fn reset(&mut self) {
self.suppressed_ids.clear();
self.suppressed_groups.clear();
}
}
impl Default for X86DiagnosticSuppressor {
fn default() -> Self {
Self::new()
}
}
pub struct X86DiagnosticSuggestionEngine {
pub feature_fixits: HashMap<String, String>,
pub known_calling_convs: Vec<String>,
pub alignment_suggestions: HashMap<u32, String>,
}
impl X86DiagnosticSuggestionEngine {
pub fn new() -> Self {
let mut feature_fixits = HashMap::new();
let features = [
("sse", "-msse"),
("sse2", "-msse2"),
("sse3", "-msse3"),
("ssse3", "-mssse3"),
("sse4.1", "-msse4.1"),
("sse4.2", "-msse4.2"),
("avx", "-mavx"),
("avx2", "-mavx2"),
("avx512f", "-mavx512f"),
("avx512bw", "-mavx512bw"),
("avx512dq", "-mavx512dq"),
("avx512vl", "-mavx512vl"),
("avx512cd", "-mavx512cd"),
("avx512bf16", "-mavx512bf16"),
("avx512fp16", "-mavx512fp16"),
("avx512vbmi", "-mavx512vbmi"),
("avx512vnni", "-mavx512vnni"),
("fma", "-mfma"),
("fma4", "-mfma4"),
("f16c", "-mf16c"),
("xop", "-mxop"),
("mmx", "-mmmx"),
("3dnow", "-m3dnow"),
("bmi", "-mbmi"),
("bmi2", "-mbmi2"),
("lzcnt", "-mlzcnt"),
("popcnt", "-mpopcnt"),
("aes", "-maes"),
("pclmul", "-mpclmul"),
("sha", "-msha"),
("rdrand", "-mrdrand"),
("rdseed", "-mrdseed"),
("adx", "-madx"),
("rtm", "-mrtm"),
("sgx", "-msgx"),
("cet", "-mcet"),
("xsave", "-mxsave"),
("fsgsbase", "-mfsgsbase"),
("movbe", "-mmovbe"),
("clflushopt", "-mclflushopt"),
("clwb", "-mclwb"),
("pku", "-mpku"),
("waitpkg", "-mwaitpkg"),
("serialize", "-mserialize"),
("enqcmd", "-menqcmd"),
("amx-bf16", "-mamx-bf16"),
("amx-int8", "-mamx-int8"),
("amx-tile", "-mamx-tile"),
("amx-fp16", "-mamx-fp16"),
("uintr", "-muintr"),
("hreset", "-mhreset"),
("cmpccxadd", "-mcmpccxadd"),
("raoint", "-mraoint"),
("avxvnni", "-mavxvnni"),
("avxneconvert", "-mavxneconvert"),
("prefetchi", "-mprefetchi"),
];
for (feat, flag) in &features {
feature_fixits.insert(feat.to_string(), flag.to_string());
}
let alignment_suggestions = {
let mut m = HashMap::new();
m.insert(16, "__attribute__((aligned(16)))".to_string());
m.insert(32, "__attribute__((aligned(32)))".to_string());
m.insert(64, "__attribute__((aligned(64)))".to_string());
m.insert(128, "__attribute__((aligned(128)))".to_string());
m
};
Self {
feature_fixits,
known_calling_convs: vec![
"cdecl".into(),
"stdcall".into(),
"fastcall".into(),
"thiscall".into(),
"vectorcall".into(),
"regcall".into(),
"sysv_abi".into(),
"ms_abi".into(),
],
alignment_suggestions,
}
}
pub fn suggest_fixit(&self, id: X86DiagID, context: &str) -> Option<String> {
match id {
_id if (id as u32) >= 1000 && (id as u32) < 1200 => {
let feature = context.to_lowercase();
self.feature_fixits
.get(&feature)
.map(|flag| format!("add compiler flag: {}", flag))
}
X86DiagID::ABIStructTooLarge | X86DiagID::ABIStructPassedInMem => Some(format!(
"consider passing '{}' by pointer/reference instead of by value",
context
)),
X86DiagID::AlignUnalignedAccess
| X86DiagID::AlignUnalignedLoad
| X86DiagID::AlignUnalignedStore => Some(format!(
"ensure '{}' is properly aligned; consider __attribute__((aligned))",
context
)),
X86DiagID::InlineAsmInvalidConstraint | X86DiagID::InlineAsmUnsupportedConstraint => {
Some(format!(
"check the X86 constraint list for valid constraint characters"
))
}
X86DiagID::InlineAsmStackPointerClobber => Some(
"do not clobber RSP/ESP; use a different register or restructure the asm"
.to_string(),
),
X86DiagID::InlineAsmFramePointerClobber => {
Some("save and restore RBP/EBP or use -fomit-frame-pointer".to_string())
}
X86DiagID::VectorWidthMismatch => Some(format!(
"ensure vector operands have matching widths; use _mm{}_* intrinsics consistently",
context
)),
X86DiagID::VectorGatherUnsupported
| X86DiagID::VectorScatterUnsupported
| X86DiagID::VectorFMAUnsupported => {
Some("enable AVX2 or AVX-512 to use this vector operation".to_string())
}
X86DiagID::BackendRedZoneViolation | X86DiagID::ABIRedZoneViolation => {
Some("avoid accessing memory below the stack pointer in leaf functions".to_string())
}
X86DiagID::BackendBranchTargetTooFar => Some(
"split the function into smaller pieces or use a different branch strategy"
.to_string(),
),
X86DiagID::ABIMismatchedCallingConv => Some(
"ensure the calling convention is consistent between declaration and definition"
.to_string(),
),
_ => None,
}
}
pub fn suggest_calling_convention(&self, current: &str) -> Vec<String> {
self.known_calling_convs
.iter()
.filter(|cc| *cc != current)
.cloned()
.collect()
}
pub fn suggest_alignment_fix(&self, required: u32) -> Option<&str> {
self.alignment_suggestions
.get(&required)
.map(|s| s.as_str())
}
pub fn has_feature_fixit(&self, feature: &str) -> bool {
self.feature_fixits.contains_key(&feature.to_lowercase())
}
pub fn flag_for_feature(&self, feature: &str) -> Option<&str> {
self.feature_fixits
.get(&feature.to_lowercase())
.map(|s| s.as_str())
}
}
impl Default for X86DiagnosticSuggestionEngine {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Default)]
pub struct X86DiagnosticCounters {
pub total: usize,
pub errors: usize,
pub warnings: usize,
pub remarks: usize,
pub notes: usize,
pub fatal: usize,
pub ignored: usize,
pub by_category: HashMap<String, usize>,
pub by_function: HashMap<String, usize>,
}
impl X86DiagnosticCounters {
pub fn new() -> Self {
Self::default()
}
pub fn record(&mut self, diag: &X86BackendDiagnostic) {
self.total += 1;
match diag.severity {
DiagSeverity::Error => self.errors += 1,
DiagSeverity::Warning => self.warnings += 1,
DiagSeverity::Remark => self.remarks += 1,
DiagSeverity::Note => self.notes += 1,
DiagSeverity::Fatal => self.fatal += 1,
DiagSeverity::Ignored => self.ignored += 1,
}
let cat = X86DiagnosticCatalog::category(diag.id).to_string();
*self.by_category.entry(cat).or_default() += 1;
}
pub fn record_all(&mut self, diags: &[X86BackendDiagnostic]) {
for d in diags {
self.record(d);
}
}
pub fn summary(&self) -> String {
format!(
"{} diagnostic(s): {} error(s), {} warning(s), {} remark(s)",
self.total, self.errors, self.warnings, self.remarks
)
}
pub fn reset(&mut self) {
*self = Self::new();
}
}
pub struct X86DiagnosticBatchProcessor {
pub emitter: X86DiagnosticEmitter,
pub counters: X86DiagnosticCounters,
pub suggestion_engine: X86DiagnosticSuggestionEngine,
pub renderer_writer: Vec<u8>,
}
impl X86DiagnosticBatchProcessor {
pub fn new() -> Self {
Self {
emitter: X86DiagnosticEmitter::new(),
counters: X86DiagnosticCounters::new(),
suggestion_engine: X86DiagnosticSuggestionEngine::new(),
renderer_writer: Vec::new(),
}
}
pub fn process(&mut self, diag: X86BackendDiagnostic) {
self.counters.record(&diag);
if let Some(fixit) = self.suggestion_engine.suggest_fixit(diag.id, &diag.message) {
let _ = fixit;
}
}
pub fn process_all(&mut self, diags: Vec<X86BackendDiagnostic>) {
for d in diags {
self.process(d);
}
}
pub fn summary(&self) -> String {
self.counters.summary()
}
pub fn reset(&mut self) {
self.emitter.clear();
self.counters.reset();
self.renderer_writer.clear();
}
}
impl Default for X86DiagnosticBatchProcessor {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_diag_id_discriminants_are_unique() {
let mut ids = Vec::new();
ids.push(X86DiagID::BackendISelFail as u32);
ids.push(X86DiagID::BackendCannotSelect as u32);
ids.push(X86DiagID::BackendUnsupportedType as u32);
ids.push(X86DiagID::BackendIllegalType as u32);
ids.push(X86DiagID::BackendCannotLower as u32);
ids.push(X86DiagID::BackendCannotLegalize as u32);
ids.push(X86DiagID::BackendNoPattern as u32);
ids.push(X86DiagID::BackendRegallocSpill as u32);
ids.push(X86DiagID::BackendRegallocFail as u32);
ids.push(X86DiagID::BackendOutOfRegisters as u32);
ids.push(X86DiagID::BackendPhysRegUnavailable as u32);
ids.push(X86DiagID::BackendVirtRegUnmapped as u32);
ids.push(X86DiagID::BackendLiveInConflict as u32);
ids.push(X86DiagID::BackendStackSlotTooLarge as u32);
ids.push(X86DiagID::BackendFrameTooLarge as u32);
ids.push(X86DiagID::BackendStackRealignLimit as u32);
ids.push(X86DiagID::BackendCannotEliminateFrameIndex as u32);
ids.push(X86DiagID::BackendFrameOffsetOverflow as u32);
ids.push(X86DiagID::BackendRedZoneViolation as u32);
ids.push(X86DiagID::BackendPrologueEmissionFailed as u32);
ids.push(X86DiagID::BackendEpilogueEmissionFailed as u32);
ids.push(X86DiagID::BackendEncodingFail as u32);
ids.push(X86DiagID::BackendImmediateTooLarge as u32);
ids.push(X86DiagID::BackendDisplacementOverflow as u32);
ids.push(X86DiagID::BackendAddressModeInvalid as u32);
ids.push(X86DiagID::BackendRexPrefixConflict as u32);
ids.push(X86DiagID::BackendVexEncodingFail as u32);
ids.push(X86DiagID::BackendEvexEncodingFail as u32);
ids.push(X86DiagID::BackendOpcodeNotSupported as u32);
ids.push(X86DiagID::BackendRelaxationFail as u32);
ids.push(X86DiagID::BackendEmissionFail as u32);
ids.push(X86DiagID::BackendObjectEmissionFail as u32);
ids.push(X86DiagID::BackendAsmPrinterFail as u32);
ids.push(X86DiagID::BackendDwarfEmissionFail as u32);
ids.push(X86DiagID::BackendUnwindInfoFail as u32);
ids.push(X86DiagID::BackendELFStubFail as u32);
ids.push(X86DiagID::BackendCOFFStubFail as u32);
ids.push(X86DiagID::BackendMachOStubFail as u32);
ids.push(X86DiagID::BackendBranchTargetTooFar as u32);
ids.push(X86DiagID::BackendJumpTableFail as u32);
ids.push(X86DiagID::BackendIndirectBranchFail as u32);
ids.push(X86DiagID::BackendTailMergeFail as u32);
ids.push(X86DiagID::BackendConditionalTailCallFail as u32);
ids.push(X86DiagID::BackendUnsupportedIndirectCall as u32);
ids.push(X86DiagID::BackendScheduleConflict as u32);
ids.push(X86DiagID::BackendBundleFail as u32);
ids.push(X86DiagID::BackendResourceConflict as u32);
ids.push(X86DiagID::BackendDependencyCycle as u32);
ids.push(X86DiagID::BackendBlockPlacementFail as u32);
ids.push(X86DiagID::BackendLayoutConflict as u32);
ids.push(X86DiagID::BackendAlignmentConflict as u32);
ids.push(X86DiagID::BackendFastISelFail as u32);
ids.push(X86DiagID::BackendFastISelUnsupportedType as u32);
ids.push(X86DiagID::BackendFastISelUnsupportedOp as u32);
ids.push(X86DiagID::BackendFastISelNoVreg as u32);
ids.push(X86DiagID::BackendGISelFail as u32);
ids.push(X86DiagID::BackendGISelUnsupported as u32);
ids.push(X86DiagID::BackendGISelNoLegalizer as u32);
ids.push(X86DiagID::BackendGISelNoRegBank as u32);
let mut sorted = ids.clone();
sorted.sort_unstable();
sorted.dedup();
assert_eq!(
sorted.len(),
ids.len(),
"Duplicate discriminant values found among backend diagnostics"
);
let max_backend = ids.iter().max().copied().unwrap();
assert!(
max_backend < 1000,
"Backend IDs should be < 1000, got {}",
max_backend
);
let min_feature = X86DiagID::FeatureMissingSSE as u32;
assert!(
min_feature >= 1000,
"Feature IDs should be >= 1000, got {}",
min_feature
);
}
#[test]
fn test_catalog_default_severity() {
assert!(X86DiagnosticCatalog::is_error(X86DiagID::BackendISelFail));
assert!(X86DiagnosticCatalog::is_error(
X86DiagID::BackendCannotSelect
));
assert!(X86DiagnosticCatalog::is_error(
X86DiagID::BackendRegallocFail
));
assert!(X86DiagnosticCatalog::is_error(
X86DiagID::BackendEncodingFail
));
assert!(X86DiagnosticCatalog::is_error(
X86DiagID::LinkerRelocationOverflow
));
assert!(X86DiagnosticCatalog::is_warning(
X86DiagID::FeatureMissingSSE
));
assert!(X86DiagnosticCatalog::is_warning(
X86DiagID::FeatureMissingAVX
));
assert!(X86DiagnosticCatalog::is_warning(
X86DiagID::ABIStructTooLarge
));
assert!(X86DiagnosticCatalog::is_warning(
X86DiagID::VectorWidthMismatch
));
assert!(X86DiagnosticCatalog::is_warning(
X86DiagID::AlignUnalignedAccess
));
assert!(X86DiagnosticCatalog::is_optimization_remark(
X86DiagID::OptX86ISelSuccess
));
assert!(X86DiagnosticCatalog::is_optimization_remark(
X86DiagID::OptX86PeepholeApplied
));
assert!(!X86DiagnosticCatalog::is_optimization_remark(
X86DiagID::BackendISelFail
));
}
#[test]
fn test_catalog_category() {
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::BackendISelFail),
"x86-backend"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::FeatureMissingSSE),
"x86-target-features"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::ABIStructTooLarge),
"x86-abi"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::SizeFunctionTooLarge),
"x86-code-size"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::AlignUnalignedAccess),
"x86-alignment"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::InlineAsmParseError),
"x86-inline-asm"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::VectorWidthMismatch),
"x86-vector"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::OptX86ISelSuccess),
"x86-optimization"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::LinkerRelocationOverflow),
"x86-linker"
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::MiscStackProbe),
"x86-misc"
);
}
#[test]
fn test_catalog_flag_names() {
assert_eq!(
X86DiagnosticCatalog::flag_name(X86DiagID::BackendISelFail),
"-Wx86-backend-isel-fail"
);
assert_eq!(
X86DiagnosticCatalog::flag_name(X86DiagID::FeatureMissingAVX),
"-Wx86-missing-avx"
);
assert_eq!(
X86DiagnosticCatalog::flag_name(X86DiagID::FeatureMissingSSE2),
"-Wx86-missing-sse2"
);
assert_eq!(
X86DiagnosticCatalog::flag_name(X86DiagID::ABIStructTooLarge),
"-Wx86-abi-struct-too-large"
);
assert_eq!(
X86DiagnosticCatalog::flag_name(X86DiagID::OptX86PeepholeApplied),
"-Rpass=x86-peephole"
);
}
#[test]
fn test_catalog_messages_not_empty() {
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::BackendISelFail).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingSSE).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::ABIStructTooLarge).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::SizeFunctionTooLarge).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::AlignUnalignedAccess).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::InlineAsmParseError).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::VectorWidthMismatch).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::OptX86ISelSuccess).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::LinkerRelocationOverflow).is_empty());
assert!(!X86DiagnosticCatalog::message_for(X86DiagID::MiscStackProbe).is_empty());
}
#[test]
fn test_catalog_message_contains_placeholders() {
let msg = X86DiagnosticCatalog::message_for(X86DiagID::BackendISelFail);
assert!(
msg.contains("{}"),
"BackendISelFail message should contain placeholders: {}",
msg
);
let msg = X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingSSE);
assert!(
!msg.contains("{}"),
"FeatureMissingSSE message should not contain placeholders: {}",
msg
);
let msg = X86DiagnosticCatalog::message_for(X86DiagID::ABIStructTooLarge);
assert!(
msg.contains("{}"),
"ABIStructTooLarge message should contain placeholders: {}",
msg
);
}
#[test]
fn test_catalog_all_feature_ids_have_messages() {
for raw_id in 1000..=1103u32 {
let msg = match raw_id {
1000 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingSSE),
1001 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingSSE2),
1006 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingAVX),
1007 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingAVX2),
1008 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingAVX512F),
1030 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingFMA),
1034 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingMMX),
1040 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingPOPCNT),
1060 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingXSAVEC),
1085 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingAMX_BF16),
1090 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingX87),
1100 => X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingRAOINT),
_ => continue,
};
assert!(!msg.is_empty(), "Message for raw_id {} is empty", raw_id);
}
}
#[test]
fn test_group_registry_creation() {
let registry = X86DiagnosticGroupRegistry::new();
assert!(registry.has_group("x86-backend-isel"));
assert!(registry.has_group("x86-backend-regalloc"));
assert!(registry.has_group("x86-missing-simd"));
assert!(registry.has_group("x86-missing-avx512"));
assert!(registry.has_group("x86-abi-struct-passing"));
assert!(registry.has_group("x86-abi-calling-conv"));
assert!(registry.has_group("x86-inline-asm"));
assert!(registry.has_group("x86-vector"));
assert!(registry.has_group("x86-linker"));
assert!(registry.has_group("x86-all"));
}
#[test]
fn test_group_membership() {
let registry = X86DiagnosticGroupRegistry::new();
let groups = registry.groups_for(X86DiagID::BackendISelFail);
assert!(!groups.is_empty());
assert!(groups.iter().any(|g| g.name == "x86-backend-isel"));
let groups = registry.groups_for(X86DiagID::FeatureMissingAVX);
assert!(!groups.is_empty());
assert!(groups.iter().any(|g| g.name == "x86-missing-simd"));
}
#[test]
fn test_group_enabled_by_default() {
let registry = X86DiagnosticGroupRegistry::new();
let group = registry.groups.get("x86-backend-isel").unwrap();
assert!(group.enabled_by_default);
let group = registry.groups.get("x86-missing-simd").unwrap();
assert!(group.enabled_by_default);
let group = registry.groups.get("x86-missing-security").unwrap();
assert!(!group.enabled_by_default);
let group = registry.groups.get("x86-abi-struct-passing").unwrap();
assert!(group.enabled_by_default);
}
#[test]
fn test_group_names() {
let registry = X86DiagnosticGroupRegistry::new();
let names = registry.group_names();
assert!(names.contains(&"x86-backend-isel"));
assert!(names.contains(&"x86-missing-simd"));
assert!(names.contains(&"x86-all"));
}
#[test]
fn test_backend_diagnostic_new() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail);
assert_eq!(diag.id, X86DiagID::BackendISelFail);
assert_eq!(diag.severity, DiagSeverity::Error);
assert!(diag.message.is_empty());
}
#[test]
fn test_backend_diagnostic_build() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendCannotSelect)
.with_args(vec!["add".into(), "i32".into(), "my_func".into()])
.build();
assert!(diag.message.contains("cannot select"));
assert!(diag.message.contains("add"));
assert!(diag.message.contains("my_func"));
}
#[test]
fn test_backend_diagnostic_format() {
let loc = ClangSourceLocation {
file: PathBuf::from("test.c"),
line: 42,
column: 10,
offset: 0,
is_valid: true,
is_macro_expansion: false,
spelling_loc: None,
expansion_loc: None,
};
let diag = X86BackendDiagnostic::new(X86DiagID::BackendRegallocSpill)
.at(loc)
.with_args(vec!["3".into(), "baz".into()])
.build();
let formatted = diag.format();
assert!(formatted.contains("test.c"));
assert!(formatted.contains("42"));
assert!(formatted.contains("error"));
assert!(formatted.contains("spill"));
}
#[test]
fn test_backend_diagnostic_add_note() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendEncodingFail)
.with_args(vec!["MOVAPS".into(), "displacement overflow".into()])
.add_note("consider using a different addressing mode")
.build();
assert_eq!(diag.notes.len(), 1);
assert!(diag.notes[0].contains("addressing mode"));
}
#[test]
fn test_backend_diagnostic_display() {
let diag = X86BackendDiagnostic::new(X86DiagID::FeatureMissingAVX)
.with_args(vec![])
.build();
let displayed = format!("{}", diag);
assert!(displayed.contains("warning"));
assert!(displayed.contains("AVX"));
}
#[test]
fn test_backend_diagnostic_to_structured_via_builder() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendCannotSelect)
.with_args(vec!["shl".into(), "i64".into(), "f".into()])
.build();
assert_eq!(diag.severity, DiagSeverity::Error);
assert_eq!(diag.id, X86DiagID::BackendCannotSelect);
assert!(!diag.message.is_empty());
assert!(diag.message.contains("cannot select"));
}
#[test]
fn test_feature_diag_missing() {
let diag = X86TargetFeatureDiag::missing_feature("avx2");
assert_eq!(diag.id, X86DiagID::FeatureMissingAVX2);
assert!(!diag.is_error);
assert_eq!(diag.suggested_flag, "-mavx2");
let formatted = diag.format();
assert!(formatted.contains("AVX2"));
assert!(formatted.contains("-mavx2"));
}
#[test]
fn test_feature_diag_missing_for_cpu() {
let diag = X86TargetFeatureDiag::missing_for_cpu("avx512f", "pentium4");
assert_eq!(diag.id, X86DiagID::FeatureMissingForCPU);
assert!(diag.format().contains("pentium4"));
}
#[test]
fn test_feature_diag_requires_64bit() {
let diag = X86TargetFeatureDiag::requires_64bit("avx512vl");
assert!(diag.is_error);
assert_eq!(diag.id, X86DiagID::FeatureRequires64Bit);
assert!(diag.format().contains("-m64"));
}
#[test]
fn test_feature_diag_conflicting() {
let diag = X86TargetFeatureDiag::conflicting("sse", "avx512f");
assert!(diag.is_error);
assert_eq!(diag.id, X86DiagID::FeatureConflicting);
assert!(diag.format().contains("sse"));
assert!(diag.format().contains("avx512f"));
}
#[test]
fn test_feature_diag_deprecated() {
let diag = X86TargetFeatureDiag::deprecated("3dnow");
assert_eq!(diag.id, X86DiagID::FeatureDeprecated);
}
#[test]
fn test_feature_diag_id_for_feature_mapping() {
assert_eq!(
X86TargetFeatureDiag::id_for_feature("sse4.1"),
X86DiagID::FeatureMissingSSE41
);
assert_eq!(
X86TargetFeatureDiag::id_for_feature("avx512vnni"),
X86DiagID::FeatureMissingAVX512VNNI
);
assert_eq!(
X86TargetFeatureDiag::id_for_feature("aes-ni"),
X86DiagID::FeatureMissingAES
);
assert_eq!(
X86TargetFeatureDiag::id_for_feature("unknown-feature"),
X86DiagID::FeatureMissingSSE2
);
}
#[test]
fn test_feature_diag_display() {
let diag = X86TargetFeatureDiag::missing_feature("avx");
let displayed = format!("{}", diag);
assert!(displayed.contains("AVX"));
}
#[test]
fn test_abi_diagnostic_basic() {
let diag = X86ABIDiagnostic::new(X86DiagID::ABIStructTooLarge)
.with_type("BigStruct")
.with_size(256);
let formatted = diag.format();
assert!(formatted.contains("BigStruct"));
assert!(formatted.contains("256"));
}
#[test]
fn test_abi_diagnostic_calling_conv() {
let diag = X86ABIDiagnostic::new(X86DiagID::ABIMismatchedCallingConv)
.with_function("foo")
.with_calling_conv("fastcall")
.with_type("stdcall");
let formatted = diag.format();
assert!(formatted.contains("foo"));
}
#[test]
fn test_abi_diagnostic_display() {
let diag = X86ABIDiagnostic::new(X86DiagID::ABIParamTooLarge)
.with_type("LargeStruct")
.with_size(128);
let displayed = format!("{}", diag);
assert!(displayed.contains("LargeStruct"));
assert!(displayed.contains("128"));
}
#[test]
fn test_size_diagnostic_basic() {
let diag = X86SizeDiagnostic::new(X86DiagID::SizeFunctionTooLarge);
let diag = X86SizeDiagnostic {
function_name: Some("big_func".into()),
current_size: Some(50000),
limit: Some(30000),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("big_func"));
assert!(formatted.contains("50000"));
assert!(formatted.contains("30000"));
}
#[test]
fn test_size_diagnostic_block() {
let diag = X86SizeDiagnostic::new(X86DiagID::SizeBasicBlockTooLarge);
let diag = X86SizeDiagnostic {
block_name: Some("LBB0_42".into()),
current_size: Some(1500),
limit: Some(1000),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("LBB0_42"));
assert!(formatted.contains("1500"));
}
#[test]
fn test_align_diagnostic_basic() {
let diag = X86AlignDiagnostic::new(X86DiagID::AlignUnalignedAccess);
let diag = X86AlignDiagnostic {
function_name: Some("vec_add".into()),
offset: Some(0x1001),
access_size: Some(32),
current_alignment: Some(4),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("vec_add"));
assert!(formatted.contains("32"));
}
#[test]
fn test_align_diagnostic_simd() {
let diag = X86AlignDiagnostic::new(X86DiagID::AlignSIMDUnalignedAccess);
let diag = X86AlignDiagnostic {
function_name: Some("kernel".into()),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("kernel"));
assert!(formatted.contains("movups"));
}
#[test]
fn test_inline_asm_diag_invalid_instruction() {
let diag = X86InlineAsmDiag::new(X86DiagID::InlineAsmInvalidInstruction);
let diag = X86InlineAsmDiag {
instruction: Some("MOVXYZ".into()),
detail: Some("unknown mnemonic".into()),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("MOVXYZ"));
}
#[test]
fn test_inline_asm_diag_clobber() {
let diag = X86InlineAsmDiag::new(X86DiagID::InlineAsmFramePointerClobber);
let formatted = diag.format();
assert!(formatted.contains("RBP"));
}
#[test]
fn test_inline_asm_diag_constraint() {
let diag = X86InlineAsmDiag::new(X86DiagID::InlineAsmInvalidConstraint);
let diag = X86InlineAsmDiag {
constraint: Some("X".into()),
operand: Some("0".into()),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("X"));
}
#[test]
fn test_vector_diag_width_mismatch() {
let diag = X86VectorDiag::new(X86DiagID::VectorWidthMismatch);
let diag = X86VectorDiag {
operation: Some("vaddps".into()),
expected_width: Some(512),
actual_width: Some(256),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("vaddps"));
assert!(formatted.contains("512"));
assert!(formatted.contains("256"));
}
#[test]
fn test_vector_diag_shuffle() {
let diag = X86VectorDiag::new(X86DiagID::VectorShuffleMaskInvalid);
let diag = X86VectorDiag {
element_type: Some("i32".into()),
index: Some(8),
limit: Some(4),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("i32"));
assert!(formatted.contains("8"));
}
#[test]
fn test_vector_diag_gather() {
let diag = X86VectorDiag::new(X86DiagID::VectorGatherUnsupported);
let diag = X86VectorDiag {
element_type: Some("f64".into()),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("f64"));
assert!(formatted.contains("gather"));
}
#[test]
fn test_vector_diag_upgrade_hint() {
let diag = X86VectorDiag::new(X86DiagID::VectorAVX512UpgradeHint);
let diag = X86VectorDiag {
expected_width: Some(256),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("AVX-512"));
}
#[test]
fn test_remarks_disabled_by_default() {
let remarks = X86OptimizationRemarks::new();
assert!(!remarks.enabled);
assert_eq!(remarks.count(), 0);
}
#[test]
fn test_remarks_enabled() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
assert!(remarks.enabled);
}
#[test]
fn test_remarks_emit_isel() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "my_func");
assert_eq!(remarks.count(), 1);
}
#[test]
fn test_remarks_no_emit_when_disabled() {
let mut remarks = X86OptimizationRemarks::new();
remarks.emit_isel_success("add", "ADD64rr", "my_func");
assert_eq!(remarks.count(), 0);
}
#[test]
fn test_remarks_peephole() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_peephole("mov rax,rbx; mov rbx,rax", "mov rax,rbx", "f");
assert_eq!(remarks.count(), 1);
}
#[test]
fn test_remarks_macro_fusion() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_macro_fusion("CMP", "JNE", "loop_body");
assert_eq!(remarks.count(), 1);
}
#[test]
fn test_remarks_regalloc_spill() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_regalloc_spill(5, "spill_func");
assert_eq!(remarks.count(), 1);
}
#[test]
fn test_remarks_block_placement() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_block_placement("LBB0_4", 0x200, 0.85);
assert_eq!(remarks.count(), 1);
}
#[test]
fn test_remarks_count_by_severity() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "f");
remarks.emit_peephole("a", "b", "f");
remarks.emit_macro_fusion("CMP", "JNE", "f");
remarks.emit_regalloc_spill(1, "f");
let remark_count = remarks.count_by_severity(DiagSeverity::Remark);
let error_count = remarks.count_by_severity(DiagSeverity::Error);
assert!(remark_count + error_count == remarks.count());
}
#[test]
fn test_remarks_format_all() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "f");
let formatted = remarks.format_all();
assert_eq!(formatted.len(), 1);
assert!(formatted[0].contains("selected"));
}
#[test]
fn test_remarks_to_yaml() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "f");
let yaml = remarks.to_yaml();
assert!(yaml.contains("X86OptimizationRemarks"));
assert!(yaml.contains("Pass:"));
}
#[test]
fn test_remarks_to_json() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "f");
let json = remarks.to_json();
assert!(json.starts_with('['));
assert!(json.contains("x86-optimization"));
}
#[test]
fn test_remarks_clear() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.emit_isel_success("add", "ADD64rr", "f");
assert_eq!(remarks.count(), 1);
remarks.clear();
assert_eq!(remarks.count(), 0);
}
#[test]
fn test_remarks_filter() {
let mut remarks = X86OptimizationRemarks::new();
remarks.enable();
remarks.set_filter("peephole");
remarks.emit_isel_success("add", "ADD64rr", "f");
assert_eq!(remarks.count(), 0);
}
#[test]
fn test_renderer_new() {
let writer: Vec<u8> = Vec::new();
let renderer = X86DiagnosticRenderer::new(writer);
assert!(!renderer.use_colors);
assert!(renderer.show_column);
assert!(renderer.show_source_line);
assert!(renderer.show_carets);
assert!(renderer.show_fixits);
assert_eq!(renderer.error_count, 0);
assert_eq!(renderer.warning_count, 0);
}
#[test]
fn test_renderer_render_basic() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
let loc = ClangSourceLocation {
file: PathBuf::from("test.c"),
line: 10,
column: 5,
offset: 0,
is_valid: true,
is_macro_expansion: false,
spelling_loc: None,
expansion_loc: None,
};
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.at(loc)
.with_args(vec!["add".into(), "my_func".into()])
.build();
renderer.render(&diag).unwrap();
assert_eq!(renderer.error_count, 1);
assert_eq!(renderer.warning_count, 0);
}
#[test]
fn test_renderer_count_warnings() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
let diag = X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build();
renderer.render(&diag).unwrap();
assert_eq!(renderer.error_count, 0);
assert_eq!(renderer.warning_count, 1);
}
#[test]
fn test_renderer_count_remark() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
let diag = X86BackendDiagnostic::new(X86DiagID::OptX86ISelSuccess)
.with_args(vec!["add".into(), "ADD64rr".into(), "f".into()])
.build();
renderer.render(&diag).unwrap();
assert_eq!(renderer.remark_count, 1);
}
#[test]
fn test_renderer_colorize_output() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
renderer.use_colors = true;
let colored = renderer.colorize_error("error");
assert!(colored.contains(ANSI_RED));
assert!(colored.contains(ANSI_BOLD));
let colored = renderer.colorize_warning("warning");
assert!(colored.contains(ANSI_MAGENTA));
let colored = renderer.colorize_note("note");
assert!(colored.contains(ANSI_CYAN));
let colored = renderer.colorize_caret("^~~~");
assert!(colored.contains(ANSI_GREEN));
let colored = renderer.colorize_filename("file.c");
assert!(colored.contains(ANSI_BOLD));
let colored = renderer.colorize_line_number(" 10 |");
assert!(colored.contains(ANSI_BLUE));
}
#[test]
fn test_renderer_no_colors() {
let writer: Vec<u8> = Vec::new();
let renderer = X86DiagnosticRenderer::new(writer);
let text = renderer.colorize_error("error");
assert!(!text.contains('\x1b'));
assert_eq!(text, "error");
}
#[test]
fn test_build_caret_line() {
let writer: Vec<u8> = Vec::new();
let renderer = X86DiagnosticRenderer::new(writer);
let line = " int x = 42;";
let ranges = &[(4, 7)]; let caret = renderer.build_caret_line(line, ranges);
assert!(caret.contains('^'));
assert!(caret.contains('~'));
}
#[test]
fn test_build_caret_line_multiple_ranges() {
let writer: Vec<u8> = Vec::new();
let renderer = X86DiagnosticRenderer::new(writer);
let line = " return a + b;";
let ranges = &[(4, 10), (13, 14)]; let caret = renderer.build_caret_line(line, ranges);
assert!(!caret.is_empty());
}
#[test]
fn test_renderer_snippet() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
let source_lines = &["void foo() {", " int x = 42;", " return x;", "}"];
let ranges = &[(8, 9)];
renderer.render_snippet(source_lines, 1, ranges).unwrap();
}
#[test]
fn test_full_workflow_backend_error() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendCannotSelect)
.with_args(vec!["shl".into(), "i64".into(), "my_func".into()])
.add_note("the target CPU may not support this operation")
.build();
assert_eq!(diag.severity, DiagSeverity::Error);
assert!(!diag.message.is_empty());
assert_eq!(diag.notes.len(), 1);
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
renderer.render(&diag).unwrap();
assert_eq!(renderer.error_count, 1);
}
#[test]
fn test_full_workflow_feature_warning() {
let diag = X86TargetFeatureDiag::missing_feature("avx512f");
let formatted = diag.format();
assert!(formatted.contains("AVX-512 Foundation"));
assert!(diag.suggested_flag == "-mavx512f");
}
#[test]
fn test_full_workflow_abi_warning() {
let diag = X86ABIDiagnostic::new(X86DiagID::ABIStructTooLarge)
.with_type("Matrix4x4")
.with_size(128)
.with_function("transform");
let formatted = diag.format();
assert!(formatted.contains("Matrix4x4"));
assert!(formatted.contains("128"));
assert!(formatted.contains("transform"));
}
#[test]
fn test_full_workflow_vector_warning() {
let diag = X86VectorDiag::new(X86DiagID::VectorGatherUnsupported);
let diag = X86VectorDiag {
element_type: Some("f64".into()),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("f64"));
assert!(formatted.contains("gather"));
}
#[test]
fn test_full_workflow_inline_asm_error() {
let diag = X86InlineAsmDiag::new(X86DiagID::InlineAsmStackPointerClobber);
let formatted = diag.format();
assert!(formatted.contains("RSP"));
assert!(formatted.contains("dangerous"));
}
#[test]
fn test_full_workflow_alignment_warning() {
let diag = X86AlignDiagnostic::new(X86DiagID::AlignUnalignedAccess);
let diag = X86AlignDiagnostic {
function_name: Some("memcpy_avx2".into()),
offset: Some(0x1004),
access_size: Some(32),
current_alignment: Some(4),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("memcpy_avx2"));
}
#[test]
fn test_full_workflow_size_warning() {
let diag = X86SizeDiagnostic::new(X86DiagID::SizeFunctionTooLarge);
let diag = X86SizeDiagnostic {
function_name: Some("giant_switch".into()),
current_size: Some(200000),
limit: Some(100000),
..diag
};
let formatted = diag.format();
assert!(formatted.contains("giant_switch"));
assert!(formatted.contains("200000"));
}
#[test]
fn test_backend_diagnostic_all_severities() {
let errors = [
X86DiagID::BackendISelFail,
X86DiagID::BackendCannotSelect,
X86DiagID::BackendRegallocFail,
X86DiagID::BackendEncodingFail,
X86DiagID::BackendEmissionFail,
X86DiagID::LinkerRelocationOverflow,
];
for &id in &errors {
assert!(
X86DiagnosticCatalog::is_error(id),
"Expected {:?} to be an error",
id
);
}
let warnings = [
X86DiagID::FeatureMissingSSE,
X86DiagID::FeatureMissingAVX,
X86DiagID::ABIStructTooLarge,
X86DiagID::VectorWidthMismatch,
X86DiagID::InlineAsmIntelSyntaxWarning,
X86DiagID::AlignUnalignedAccess,
];
for &id in &warnings {
assert!(
X86DiagnosticCatalog::is_warning(id),
"Expected {:?} to be a warning",
id
);
}
}
#[test]
fn test_optimization_remarks_count_categories() {
let mut isel_count = 0u32;
let mut peephole_count = 0u32;
let mut fusion_count = 0u32;
let mut frame_count = 0u32;
let mut block_count = 0u32;
let mut sched_count = 0u32;
let mut reg_count = 0u32;
let raw = X86DiagID::OptX86ISelSuccess as u32;
for id_val in raw..raw + 200 {
if !X86DiagnosticCatalog::is_optimization_remark(unsafe {
std::mem::transmute::<u32, X86DiagID>(id_val)
}) {
continue;
}
let flag = X86DiagnosticCatalog::flag_name(unsafe {
std::mem::transmute::<u32, X86DiagID>(id_val)
});
if flag.contains("isel") {
isel_count += 1;
} else if flag.contains("peephole") {
peephole_count += 1;
} else if flag.contains("fusion") {
fusion_count += 1;
} else if flag.contains("frame") || flag.contains("prolog") {
frame_count += 1;
} else if flag.contains("block") || flag.contains("placement") {
block_count += 1;
} else if flag.contains("sched") {
sched_count += 1;
} else if flag.contains("reg") || flag.contains("coalesc") {
reg_count += 1;
}
}
assert!(isel_count > 0, "Expected some ISel remarks");
assert!(peephole_count > 0, "Expected some peephole remarks");
}
#[test]
fn test_no_unreachable_match_arms() {
let test_ids = vec![
X86DiagID::BackendISelFail,
X86DiagID::BackendCannotSelect,
X86DiagID::BackendUnsupportedType,
X86DiagID::BackendIllegalType,
X86DiagID::BackendCannotLower,
X86DiagID::BackendCannotLegalize,
X86DiagID::BackendNoPattern,
X86DiagID::BackendRegallocSpill,
X86DiagID::BackendRegallocFail,
X86DiagID::BackendOutOfRegisters,
X86DiagID::BackendPhysRegUnavailable,
X86DiagID::BackendVirtRegUnmapped,
X86DiagID::BackendLiveInConflict,
X86DiagID::BackendStackSlotTooLarge,
X86DiagID::BackendFrameTooLarge,
X86DiagID::BackendStackRealignLimit,
X86DiagID::BackendCannotEliminateFrameIndex,
X86DiagID::BackendFrameOffsetOverflow,
X86DiagID::BackendRedZoneViolation,
X86DiagID::BackendPrologueEmissionFailed,
X86DiagID::BackendEpilogueEmissionFailed,
X86DiagID::BackendEncodingFail,
X86DiagID::BackendImmediateTooLarge,
X86DiagID::BackendDisplacementOverflow,
X86DiagID::BackendAddressModeInvalid,
X86DiagID::BackendRexPrefixConflict,
X86DiagID::BackendVexEncodingFail,
X86DiagID::BackendEvexEncodingFail,
X86DiagID::BackendOpcodeNotSupported,
X86DiagID::BackendRelaxationFail,
X86DiagID::BackendEmissionFail,
X86DiagID::BackendObjectEmissionFail,
X86DiagID::BackendAsmPrinterFail,
X86DiagID::BackendDwarfEmissionFail,
X86DiagID::BackendUnwindInfoFail,
X86DiagID::BackendELFStubFail,
X86DiagID::BackendCOFFStubFail,
X86DiagID::BackendMachOStubFail,
X86DiagID::BackendBranchTargetTooFar,
X86DiagID::BackendJumpTableFail,
X86DiagID::BackendIndirectBranchFail,
X86DiagID::BackendTailMergeFail,
X86DiagID::BackendConditionalTailCallFail,
X86DiagID::BackendUnsupportedIndirectCall,
X86DiagID::BackendScheduleConflict,
X86DiagID::BackendBundleFail,
X86DiagID::BackendResourceConflict,
X86DiagID::BackendDependencyCycle,
X86DiagID::BackendBlockPlacementFail,
X86DiagID::BackendLayoutConflict,
X86DiagID::BackendAlignmentConflict,
X86DiagID::BackendFastISelFail,
X86DiagID::BackendFastISelUnsupportedType,
X86DiagID::BackendFastISelUnsupportedOp,
X86DiagID::BackendFastISelNoVreg,
X86DiagID::BackendGISelFail,
X86DiagID::BackendGISelUnsupported,
X86DiagID::BackendGISelNoLegalizer,
X86DiagID::BackendGISelNoRegBank,
X86DiagID::FeatureMissingSSE,
X86DiagID::FeatureMissingSSE2,
X86DiagID::FeatureMissingSSE3,
X86DiagID::FeatureMissingSSSE3,
X86DiagID::FeatureMissingSSE41,
X86DiagID::FeatureMissingSSE42,
X86DiagID::FeatureMissingAVX,
X86DiagID::FeatureMissingAVX2,
X86DiagID::FeatureMissingAVX512F,
X86DiagID::FeatureMissingAVX512BW,
X86DiagID::FeatureMissingAVX512DQ,
X86DiagID::FeatureMissingAVX512VL,
X86DiagID::FeatureMissingAVX512CD,
X86DiagID::FeatureMissingAVX512ER,
X86DiagID::FeatureMissingAVX512PF,
X86DiagID::FeatureMissingAVX512BF16,
X86DiagID::FeatureMissingAVX512FP16,
X86DiagID::FeatureMissingAVX512VBMI,
X86DiagID::FeatureMissingAVX512VBMI2,
X86DiagID::FeatureMissingAVX512VNNI,
X86DiagID::FeatureMissingAVX512BITALG,
X86DiagID::FeatureMissingAVX512VPOPCNTDQ,
X86DiagID::FeatureMissingAVX5124FMAPS,
X86DiagID::FeatureMissingAVX5124VNNIW,
X86DiagID::FeatureMissingAVX512VP2INTERSECT,
X86DiagID::FeatureMissingAVX512IFMA,
X86DiagID::FeatureMissingAVX10_1_256,
X86DiagID::FeatureMissingAVX10_1_512,
X86DiagID::FeatureMissingAVX10_2,
X86DiagID::FeatureMissingFMA,
X86DiagID::FeatureMissingFMA4,
X86DiagID::FeatureMissingF16C,
X86DiagID::FeatureMissingXOP,
X86DiagID::FeatureMissingMMX,
X86DiagID::FeatureMissing3DNOW,
X86DiagID::FeatureMissing3DNOWA,
X86DiagID::FeatureMissingBMI,
X86DiagID::FeatureMissingBMI2,
X86DiagID::FeatureMissingLZCNT,
X86DiagID::FeatureMissingPOPCNT,
X86DiagID::FeatureMissingTBM,
X86DiagID::FeatureMissingAES,
X86DiagID::FeatureMissingPCLMUL,
X86DiagID::FeatureMissingSHA,
X86DiagID::FeatureMissingSHA512,
X86DiagID::FeatureMissingSM3,
X86DiagID::FeatureMissingSM4,
X86DiagID::FeatureMissingGFNI,
X86DiagID::FeatureMissingVAES,
X86DiagID::FeatureMissingVPCLMULQDQ,
X86DiagID::FeatureMissingRDRAND,
X86DiagID::FeatureMissingRDSEED,
X86DiagID::FeatureMissingADX,
X86DiagID::FeatureMissingRTM,
X86DiagID::FeatureMissingHLE,
X86DiagID::FeatureMissingSGX,
X86DiagID::FeatureMissingCET,
X86DiagID::FeatureMissingXSAVE,
X86DiagID::FeatureMissingXSAVEOPT,
X86DiagID::FeatureMissingXSAVEC,
X86DiagID::FeatureMissingXSAVES,
X86DiagID::FeatureMissingFSGSBASE,
X86DiagID::FeatureMissingMOVBE,
X86DiagID::FeatureMissingMOVDIRI,
X86DiagID::FeatureMissingMOVDIR64B,
X86DiagID::FeatureMissingENQCMD,
X86DiagID::FeatureMissingSERIALIZE,
X86DiagID::FeatureMissingTSXLDTRK,
X86DiagID::FeatureMissingWAITPKG,
X86DiagID::FeatureMissingCLDEMOTE,
X86DiagID::FeatureMissingCLFLUSHOPT,
X86DiagID::FeatureMissingCLWB,
X86DiagID::FeatureMissingCLZERO,
X86DiagID::FeatureMissingMWAITX,
X86DiagID::FeatureMissingMONITORX,
X86DiagID::FeatureMissingPKU,
X86DiagID::FeatureMissingSMAP,
X86DiagID::FeatureMissingSMEP,
X86DiagID::FeatureMissingMPX,
X86DiagID::FeatureMissingPTWRITE,
X86DiagID::FeatureMissingINVPCID,
X86DiagID::FeatureMissingPREFETCHWT1,
X86DiagID::FeatureMissingPREFETCHW,
X86DiagID::FeatureMissingPREFETCHI,
X86DiagID::FeatureMissingAMX_BF16,
X86DiagID::FeatureMissingAMX_INT8,
X86DiagID::FeatureMissingAMX_TILE,
X86DiagID::FeatureMissingAMX_FP16,
X86DiagID::FeatureMissingAMX_COMPLEX,
X86DiagID::FeatureMissingX87,
X86DiagID::FeatureMissingCMOV,
X86DiagID::FeatureMissingSAHF,
X86DiagID::FeatureMissingRDPID,
X86DiagID::FeatureMissingRDPRU,
X86DiagID::FeatureMissingHRESET,
X86DiagID::FeatureMissingUINTR,
X86DiagID::FeatureMissingKL,
X86DiagID::FeatureMissingWIDEKL,
X86DiagID::FeatureMissingCMPCCXADD,
X86DiagID::FeatureMissingRAOINT,
X86DiagID::FeatureMissingAVX_NE_CONVERT,
X86DiagID::FeatureMissingAVX_VNNI,
X86DiagID::FeatureMissingAVX_VNNI_INT8,
X86DiagID::FeatureNeedsX86_64V2,
X86DiagID::FeatureNeedsX86_64V3,
X86DiagID::FeatureNeedsX86_64V4,
X86DiagID::FeatureDeprecated,
X86DiagID::FeatureRemoved,
X86DiagID::FeatureExperimental,
X86DiagID::FeatureConflicting,
X86DiagID::FeatureMissingForCPU,
X86DiagID::FeatureNotAvailableOnCPU,
X86DiagID::FeatureRequires64Bit,
X86DiagID::FeatureRequires32Bit,
X86DiagID::FeatureMismatchedTuning,
X86DiagID::FeatureGenericTuning,
X86DiagID::FeatureSuboptimalTuning,
X86DiagID::ABIStructTooLarge,
X86DiagID::ABIStructPassedInMem,
X86DiagID::ABIStructSplitAcrossRegs,
X86DiagID::ABIReturnTooLarge,
X86DiagID::ABIHiddenPointerReturn,
X86DiagID::ABIParamTooLarge,
X86DiagID::ABITooManyParams,
X86DiagID::ABIMismatchedCallingConv,
X86DiagID::ABIUnknownCallingConv,
X86DiagID::ABICallingConvNotSupported,
X86DiagID::ABIFastcallTooManyArgs,
X86DiagID::ABIVectorcallAlignment,
X86DiagID::ABIVectorcallTypeUnsupported,
X86DiagID::ABIRegcallNotEnoughRegs,
X86DiagID::ABIThiscallNonMember,
X86DiagID::ABIStdCallVarArgs,
X86DiagID::ABICdeclMismatch,
X86DiagID::ABIStackAlignmentViolation,
X86DiagID::ABIRedZoneViolation,
X86DiagID::ABIArgOverlap,
X86DiagID::ABIRegisterClassMismatch,
X86DiagID::ABIHomogeneousAggregate,
X86DiagID::ABIFloatArgsInIntegerReg,
X86DiagID::ABIIntegerArgsInFloatReg,
X86DiagID::ABIX87Return,
X86DiagID::ABIComplexReturn,
X86DiagID::ABISysVClassificationFailed,
X86DiagID::ABIMicrosoftClassificationFailed,
X86DiagID::ABIRegCallClassificationFailed,
X86DiagID::ABIUnclassifiedType,
X86DiagID::ABIMemClassTooMany,
X86DiagID::ABIEmptyStructPass,
X86DiagID::ABIZeroWidthBitfield,
X86DiagID::ABIUnalignedFieldPass,
X86DiagID::ABIPackedStructPass,
X86DiagID::ABIUnionPass,
X86DiagID::ABIBitfieldStraddle,
X86DiagID::SizeFunctionTooLarge,
X86DiagID::SizeBasicBlockTooLarge,
X86DiagID::SizeAlignmentExcessive,
X86DiagID::SizeNopPaddingExcessive,
X86DiagID::SizeJumpTableTooLarge,
X86DiagID::SizeELFTextOverflow,
X86DiagID::SizeCOFFTextOverflow,
X86DiagID::SizeSectionOverflow,
X86DiagID::SizeDisplacementOverflowRelax,
X86DiagID::SizeCallDisplacementError,
X86DiagID::SizeJumpDisplacementError,
X86DiagID::SizeLoopAlignmentHint,
X86DiagID::SizeFunctionAlignmentHint,
X86DiagID::SizeBranchRelaxRequired,
X86DiagID::SizeRelaxationLoop,
X86DiagID::SizeColdSectionSplit,
X86DiagID::SizeUnlikelyBranch,
X86DiagID::SizeHotColdPadding,
X86DiagID::SizeOptNoneHint,
X86DiagID::SizeOptSizeHint,
X86DiagID::SizeMinSizeHint,
X86DiagID::SizeBlockPlacementHint,
X86DiagID::SizeTailDuplicationHint,
X86DiagID::AlignUnalignedAccess,
X86DiagID::AlignUnalignedStackAccess,
X86DiagID::AlignUnalignedLoad,
X86DiagID::AlignUnalignedStore,
X86DiagID::AlignMisalignedAtomics,
X86DiagID::AlignLockPrefixAlign,
X86DiagID::AlignSIMDUnalignedAccess,
X86DiagID::AlignAVXUnalignedAccess,
X86DiagID::AlignAVX512UnalignedAccess,
X86DiagID::AlignDataAlign,
X86DiagID::AlignCodeAlign,
X86DiagID::AlignStackAlign,
X86DiagID::AlignStructAlign,
X86DiagID::AlignCacheLineBoundary,
X86DiagID::AlignPageBoundary,
X86DiagID::AlignFunctionEntryAlign,
X86DiagID::AlignLoopAlign,
X86DiagID::AlignUnalignedBranchTarget,
X86DiagID::AlignMisalignedReturnAddress,
X86DiagID::AlignStackRealignNeeded,
X86DiagID::AlignStackProbeNeeded,
X86DiagID::AlignVariableAlignment,
X86DiagID::AlignNopSledNeeded,
X86DiagID::AlignOverAlignedAlloca,
X86DiagID::AlignUnderAlignedAlloca,
X86DiagID::InlineAsmParseError,
X86DiagID::InlineAsmInvalidInstruction,
X86DiagID::InlineAsmInvalidOperand,
X86DiagID::InlineAsmInvalidConstraint,
X86DiagID::InlineAsmClobberConflict,
X86DiagID::InlineAsmRegisterClobbered,
X86DiagID::InlineAsmTooManyOperands,
X86DiagID::InlineAsmSizeMismatch,
X86DiagID::InlineAsmUnsupportedConstraint,
X86DiagID::InlineAsmImmediateConstraint,
X86DiagID::InlineAsmMemoryConstraint,
X86DiagID::InlineAsmFloatConstraint,
X86DiagID::InlineAsmMultipleAlternative,
X86DiagID::InlineAsmInvalidTiedOperand,
X86DiagID::InlineAsmDuplicateConstraint,
X86DiagID::InlineAsmInputOutputMismatch,
X86DiagID::InlineAsmGlobalRegister,
X86DiagID::InlineAsmFramePointerClobber,
X86DiagID::InlineAsmStackPointerClobber,
X86DiagID::InlineAsmReservedRegister,
X86DiagID::InlineAsmIPRegisterClobber,
X86DiagID::InlineAsmFlagsRegisterClobber,
X86DiagID::InlineAsmAVX512MaskOperand,
X86DiagID::InlineAsmAVX512BroadcastOperand,
X86DiagID::InlineAsmAVX512RoundingOperand,
X86DiagID::InlineAsmAVX512SAEOperand,
X86DiagID::InlineAsmAVX512ZeroMasking,
X86DiagID::InlineAsmAMXTileOperand,
X86DiagID::InlineAsmAMXConfigNeeded,
X86DiagID::InlineAsmGotoLabel,
X86DiagID::InlineAsmGotoTooManyLabels,
X86DiagID::InlineAsmGotoIndirectBranch,
X86DiagID::InlineAsmIntelSyntaxWarning,
X86DiagID::InlineAsmATTDirectiveWarning,
X86DiagID::InlineAsmIntelDirectiveWarning,
X86DiagID::InlineAsmSplitOperandType,
X86DiagID::InlineAsmUndefinedSymbol,
X86DiagID::InlineAsmRelocationOverflow,
X86DiagID::InlineAsmAbsoluteAddress,
X86DiagID::InlineAsmTLSRelocation,
X86DiagID::InlineAsmGOTPCREL,
X86DiagID::InlineAsmPLTRelocation,
X86DiagID::InlineAsmSegmentOverride,
X86DiagID::InlineAsmAddressSizeOverride,
X86DiagID::InlineAsmOperandSizeOverride,
X86DiagID::InlineAsmREXPrefixUnused,
X86DiagID::InlineAsmLockPrefixWrong,
X86DiagID::InlineAsmRepPrefixWrong,
X86DiagID::InlineAsmVEXPrefixInvalid,
X86DiagID::InlineAsmEVEXPrefixInvalid,
X86DiagID::VectorWidthMismatch,
X86DiagID::VectorTypeMismatch,
X86DiagID::VectorElementCountMismatch,
X86DiagID::VectorShuffleMaskInvalid,
X86DiagID::VectorShuffleMaskOutOfRange,
X86DiagID::VectorInsertIndexOutOfRange,
X86DiagID::VectorExtractIndexOutOfRange,
X86DiagID::VectorGatherScatterAlign,
X86DiagID::VectorMaskOperandMissing,
X86DiagID::VectorMaskTypeMismatch,
X86DiagID::VectorZeroMaskNotSupported,
X86DiagID::VectorMergeMaskNotSupported,
X86DiagID::VectorBroadcastUnsupported,
X86DiagID::VectorBroadcastMemSource,
X86DiagID::VectorBroadcastWidth,
X86DiagID::VectorPermuteUnsupported,
X86DiagID::VectorInterleaveUnsupported,
X86DiagID::VectorDeinterleaveUnsupported,
X86DiagID::VectorLoadUnaligned,
X86DiagID::VectorStoreUnaligned,
X86DiagID::VectorLoadNonTemporal,
X86DiagID::VectorStoreNonTemporal,
X86DiagID::VectorGatherUnsupported,
X86DiagID::VectorScatterUnsupported,
X86DiagID::VectorGather4Unsupported,
X86DiagID::VectorScatter4Unsupported,
X86DiagID::VectorCompressUnsupported,
X86DiagID::VectorExpandUnsupported,
X86DiagID::VectorReduceUnsupported,
X86DiagID::VectorHorizontalAddSub,
X86DiagID::VectorDotProductUnsupported,
X86DiagID::VectorFMAUnsupported,
X86DiagID::VectorFP16Unsupported,
X86DiagID::VectorBF16Unsupported,
X86DiagID::VectorINT8Unsupported,
X86DiagID::VectorINT4Unsupported,
X86DiagID::VectorFPUnsupportedForWidth,
X86DiagID::VectorIntegerUnsupportedForWidth,
X86DiagID::VectorConversionRounding,
X86DiagID::VectorConvertOverflow,
X86DiagID::VectorConvertSaturation,
X86DiagID::VectorAbsUnsupported,
X86DiagID::VectorMinMaxUnsupported,
X86DiagID::VectorRoundUnsupported,
X86DiagID::VectorSqrtUnsupported,
X86DiagID::VectorRcpUnsupported,
X86DiagID::VectorRsqrtUnsupported,
X86DiagID::VectorPopcountUnsupported,
X86DiagID::VectorLZCNTUnsupported,
X86DiagID::VectorRotateUnsupported,
X86DiagID::VectorShiftImmOutOfRange,
X86DiagID::VectorShiftAmountMismatch,
X86DiagID::VectorBlendMaskInvalid,
X86DiagID::VectorComparePredicateInvalid,
X86DiagID::VectorSelectConditionInvalid,
X86DiagID::VectorAMXLoadStore,
X86DiagID::VectorAMXTileShape,
X86DiagID::VectorAMXConfig,
X86DiagID::VectorAMXZero,
X86DiagID::VectorAMXTilePair,
X86DiagID::VectorSSEUpgradeHint,
X86DiagID::VectorAVXUpgradeHint,
X86DiagID::VectorAVX512UpgradeHint,
X86DiagID::VectorAVX10UpgradeHint,
X86DiagID::VectorUsePackedHint,
X86DiagID::VectorUseScalarHint,
X86DiagID::VectorUseGatherHint,
X86DiagID::VectorUseScatterHint,
X86DiagID::OptX86ISelSuccess,
X86DiagID::OptX86ISelFailure,
X86DiagID::OptX86PeepholeApplied,
X86DiagID::OptX86PeepholeSkipped,
X86DiagID::OptX86MacroFusion,
X86DiagID::OptX86MicroFusion,
X86DiagID::OptX86NopInsertion,
X86DiagID::OptX86PrefixOptimization,
X86DiagID::OptX86LEAUsesAG,
X86DiagID::OptX86LEAUsesLEA,
X86DiagID::OptX86CMOVConversion,
X86DiagID::OptX86SETCCConversion,
X86DiagID::OptX86BranchAvoidance,
X86DiagID::OptX86FlagCopyEliminated,
X86DiagID::OptX86ConditionalMove,
X86DiagID::OptX86LoadFoldIntoInstr,
X86DiagID::OptX86StoreFoldIntoInstr,
X86DiagID::OptX86ImmediateFold,
X86DiagID::OptX86AddressFold,
X86DiagID::OptX86ConstantPoolFold,
X86DiagID::OptX86TwoAddressPass,
X86DiagID::OptX86FixupBWInst,
X86DiagID::OptX86FixupLEA,
X86DiagID::OptX86AvoidStoreForwarding,
X86DiagID::OptX86AvoidPartialRegStall,
X86DiagID::OptX86AvoidPartialFlagStall,
X86DiagID::OptX86DomainCrossing,
X86DiagID::OptX86VZeroupperInserted,
X86DiagID::OptX86VZeroupperNotNeeded,
X86DiagID::OptX86TileConfigInserted,
X86DiagID::OptX86X87Stackify,
X86DiagID::OptX86CallFrameOptimization,
X86DiagID::OptX86StackColoring,
X86DiagID::OptX86ShrinkWrapping,
X86DiagID::OptX86TailDuplicate,
X86DiagID::OptX86TailMerge,
X86DiagID::OptX86MachineLICM,
X86DiagID::OptX86MachineCSE,
X86DiagID::OptX86MachineSink,
X86DiagID::OptX86LoopAlignment,
X86DiagID::OptX86BranchFolding,
X86DiagID::OptX86IfConversion,
X86DiagID::OptX86MachineBlockPlacement,
X86DiagID::OptX86EarlyIfConversion,
X86DiagID::OptX86SpeculativeLoadHardening,
X86DiagID::OptX86IndirectBranchTracking,
X86DiagID::OptX86Scheduler,
X86DiagID::OptX86PostRAScheduler,
X86DiagID::OptX86PreRAScheduler,
X86DiagID::OptX86MachinePipeliner,
X86DiagID::OptX86RegisterCoalescing,
X86DiagID::OptX86VirtualRegisterRewrite,
X86DiagID::OptX86LiveRangeShrink,
X86DiagID::OptX86DeadMachineInstructionElim,
X86DiagID::OptX86PrologEpilogInsertion,
X86DiagID::OptX86FrameLowering,
X86DiagID::OptX86RedZone,
X86DiagID::OptX86ShadowStack,
X86DiagID::OptX86PatchableFunction,
X86DiagID::OptX86FunctionSections,
X86DiagID::OptX86DataSections,
X86DiagID::OptX86NoOmitFramePointer,
X86DiagID::OptX86OmitFramePointer,
X86DiagID::OptX86HotColdSplit,
X86DiagID::LinkerRelocationOverflow,
X86DiagID::LinkerGOTOverflow,
X86DiagID::LinkerPLTOverflow,
X86DiagID::LinkerTLSOverflow,
X86DiagID::LinkerUnresolvedSymbol,
X86DiagID::LinkerSectionMismatch,
X86DiagID::LinkerTrampolineNeeded,
X86DiagID::LinkerRelaxationNeeded,
X86DiagID::LinkerThreadLocalModel,
X86DiagID::LinkerTLSLocalExec,
X86DiagID::LinkerTLSInitialExec,
X86DiagID::LinkerTLSLocalDynamic,
X86DiagID::LinkerTLSGlobalDynamic,
X86DiagID::MiscStackProbe,
X86DiagID::MiscAllocaProbe,
X86DiagID::MiscVLAProbe,
X86DiagID::MiscSegmentedStack,
X86DiagID::MiscSplitStack,
X86DiagID::MiscXRayInstrumentation,
X86DiagID::MiscCFIInstruction,
X86DiagID::MiscUnwindOpcode,
X86DiagID::MiscSEHUnwind,
X86DiagID::MiscCETEndBranch,
X86DiagID::MiscShadowCallStack,
X86DiagID::MiscSafeStack,
X86DiagID::MiscControlFlowGuard,
X86DiagID::MiscKCFI,
X86DiagID::MiscFineIBT,
X86DiagID::MiscMemoryTagging,
X86DiagID::MiscHardwareEnforcedSP,
X86DiagID::MiscZeroCallUsedRegs,
X86DiagID::MiscFEntryInsertion,
X86DiagID::MiscDirectEmission,
X86DiagID::MiscDelaySlotFill,
X86DiagID::MiscConstantIsland,
];
for id in test_ids {
let msg = X86DiagnosticCatalog::message_for(id);
assert!(!msg.is_empty(), "Message for {:?} is empty", id);
let flag = X86DiagnosticCatalog::flag_name(id);
assert!(!flag.is_empty(), "Flag for {:?} is empty", id);
let cat = X86DiagnosticCatalog::category(id);
assert!(!cat.is_empty(), "Category for {:?} is empty", id);
let sev = X86DiagnosticCatalog::default_severity(id);
let _ = format!("{:?}", sev);
}
}
#[test]
fn test_default_group_registry() {
let registry = X86DiagnosticGroupRegistry::default();
assert!(!registry.groups.is_empty());
assert!(registry.group_names().len() > 5);
}
#[test]
fn test_default_remarks() {
let remarks = X86OptimizationRemarks::default();
assert!(!remarks.enabled);
assert_eq!(remarks.count(), 0);
}
#[test]
fn test_emitter_new() {
let emitter = X86DiagnosticEmitter::new();
assert!(!emitter.remarks_enabled);
assert_eq!(emitter.diagnostic_count(), 0);
}
#[test]
fn test_emitter_emit_backend_error() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_isel_failure("fadd", "my_func");
assert_eq!(emitter.diagnostic_count(), 1);
assert_eq!(emitter.error_count(), 1);
}
#[test]
fn test_emitter_emit_feature_warning() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_feature_missing("avx2");
assert_eq!(emitter.diagnostic_count(), 1);
assert_eq!(emitter.warning_count(), 1);
}
#[test]
fn test_emitter_emit_abi_warning() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_abi_struct_too_large("BigStruct", 256);
assert_eq!(emitter.diagnostic_count(), 1);
}
#[test]
fn test_emitter_emit_alignment_warning() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_alignment_warning("kernel", 32, 4, 0x1000);
assert_eq!(emitter.diagnostic_count(), 1);
}
#[test]
fn test_emitter_emit_inline_asm_error() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_inline_asm_invalid_instruction("MOVXYZ");
assert_eq!(emitter.diagnostic_count(), 1);
assert_eq!(emitter.error_count(), 1);
}
#[test]
fn test_emitter_emit_vector_diag() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_vector_width_mismatch("vaddps", 512, 256);
assert_eq!(emitter.diagnostic_count(), 1);
}
#[test]
fn test_emitter_emit_size_diag() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_function_too_large("big_func", 50000, 30000);
assert_eq!(emitter.diagnostic_count(), 1);
}
#[test]
fn test_emitter_emit_opt_remark() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.enable_remarks();
emitter.emit_isel_success("add", "ADD64rr", "f");
assert_eq!(emitter.diagnostic_count(), 1);
assert_eq!(emitter.error_count(), 0);
assert_eq!(emitter.warning_count(), 0);
}
#[test]
fn test_emitter_multiple_diagnostics() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_isel_failure("shl", "f1");
emitter.emit_isel_failure("load", "f2");
emitter.emit_feature_missing("avx2");
emitter.emit_abi_struct_too_large("Matrix", 128);
assert_eq!(emitter.diagnostic_count(), 4);
assert_eq!(emitter.error_count(), 2);
assert_eq!(emitter.warning_count(), 2);
}
#[test]
fn test_emitter_format_all() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_isel_failure("add", "f");
emitter.emit_feature_missing("avx");
let formatted = emitter.format_all();
assert_eq!(formatted.len(), 2);
}
#[test]
fn test_emitter_clear() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_isel_failure("add", "f");
assert_eq!(emitter.diagnostic_count(), 1);
emitter.clear();
assert_eq!(emitter.diagnostic_count(), 0);
}
#[test]
fn test_emitter_has_errors() {
let mut emitter = X86DiagnosticEmitter::new();
assert!(!emitter.has_errors());
emitter.emit_isel_failure("add", "f");
assert!(emitter.has_errors());
}
#[test]
fn test_emitter_max_errors() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.set_max_errors(2);
emitter.emit_isel_failure("add", "f1");
emitter.emit_isel_failure("sub", "f2");
emitter.emit_isel_failure("mul", "f3"); assert_eq!(emitter.diagnostic_count(), 2);
assert!(emitter.error_limit_reached());
}
#[test]
fn test_matcher_new() {
let matcher = X86DiagnosticMatcher::new();
assert_eq!(matcher.expected_count(), 0);
}
#[test]
fn test_matcher_expect_error() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "instruction selection failed");
assert_eq!(matcher.expected_count(), 1);
}
#[test]
fn test_matcher_expect_warning() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_warning(X86DiagID::FeatureMissingAVX, "AVX");
assert_eq!(matcher.expected_count(), 1);
}
#[test]
fn test_matcher_expect_remark() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_remark(X86DiagID::OptX86PeepholeApplied, "peephole");
assert_eq!(matcher.expected_count(), 1);
}
#[test]
fn test_matcher_match_error() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "selection");
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "my_func".into()])
.build();
let result = matcher.matches(&diag);
assert!(result.is_some());
}
#[test]
fn test_matcher_no_match_wrong_id() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "selection");
let diag = X86BackendDiagnostic::new(X86DiagID::BackendCannotSelect)
.with_args(vec!["add".into(), "f".into()])
.build();
let result = matcher.matches(&diag);
assert!(result.is_none());
}
#[test]
fn test_matcher_run_all_pass() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "selection");
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f".into()])
.build();
let mut diags = vec![diag];
let result = matcher.run_all(&mut diags);
assert!(result.is_ok());
}
#[test]
fn test_matcher_run_all_fail_unmatched_expectation() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "selection");
let mut diags: Vec<X86BackendDiagnostic> = Vec::new();
let result = matcher.run_all(&mut diags);
assert!(result.is_err());
}
#[test]
fn test_matcher_reset() {
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "fail");
assert_eq!(matcher.expected_count(), 1);
matcher.reset();
assert_eq!(matcher.expected_count(), 0);
}
#[test]
fn test_severity_map_default() {
let map = X86DiagnosticSeverityMap::default();
let sev = map.effective_severity(X86DiagID::BackendISelFail);
assert_eq!(sev, DiagSeverity::Error);
}
#[test]
fn test_severity_map_override_warning_to_error() {
let mut map = X86DiagnosticSeverityMap::new();
map.set_severity(X86DiagID::FeatureMissingSSE, DiagSeverity::Error);
let sev = map.effective_severity(X86DiagID::FeatureMissingSSE);
assert_eq!(sev, DiagSeverity::Error);
}
#[test]
fn test_severity_map_override_error_to_warning() {
let mut map = X86DiagnosticSeverityMap::new();
map.set_severity(X86DiagID::BackendISelFail, DiagSeverity::Warning);
let sev = map.effective_severity(X86DiagID::BackendISelFail);
assert_eq!(sev, DiagSeverity::Warning);
}
#[test]
fn test_severity_map_suppress() {
let mut map = X86DiagnosticSeverityMap::new();
map.suppress(X86DiagID::FeatureMissingAVX);
let sev = map.effective_severity(X86DiagID::FeatureMissingAVX);
assert_eq!(sev, DiagSeverity::Ignored);
}
#[test]
fn test_severity_map_group_override() {
let mut map = X86DiagnosticSeverityMap::new();
map.set_group_severity("x86-missing-simd", DiagSeverity::Error);
let sev = map.effective_severity(X86DiagID::FeatureMissingSSE);
assert_eq!(sev, DiagSeverity::Error);
}
#[test]
fn test_severity_map_reset_single() {
let mut map = X86DiagnosticSeverityMap::new();
map.set_severity(X86DiagID::FeatureMissingSSE, DiagSeverity::Error);
map.reset(X86DiagID::FeatureMissingSSE);
let sev = map.effective_severity(X86DiagID::FeatureMissingSSE);
assert_eq!(sev, DiagSeverity::Warning); }
#[test]
fn test_severity_map_reset_all() {
let mut map = X86DiagnosticSeverityMap::new();
map.set_severity(X86DiagID::BackendISelFail, DiagSeverity::Warning);
map.set_severity(X86DiagID::FeatureMissingSSE, DiagSeverity::Error);
map.reset_all();
assert_eq!(
map.effective_severity(X86DiagID::BackendISelFail),
DiagSeverity::Error
);
assert_eq!(
map.effective_severity(X86DiagID::FeatureMissingSSE),
DiagSeverity::Warning
);
}
#[test]
fn test_severity_map_is_suppressed() {
let mut map = X86DiagnosticSeverityMap::new();
assert!(!map.is_suppressed(X86DiagID::BackendISelFail));
map.suppress(X86DiagID::BackendISelFail);
assert!(map.is_suppressed(X86DiagID::BackendISelFail));
}
#[test]
fn test_suppressor_not_suppressed_by_default() {
let suppressor = X86DiagnosticSuppressor::new();
assert!(!suppressor.is_suppressed(X86DiagID::BackendISelFail));
}
#[test]
fn test_suppressor_suppress_single() {
let mut suppressor = X86DiagnosticSuppressor::new();
suppressor.suppress_id(X86DiagID::FeatureMissingSSE);
assert!(suppressor.is_suppressed(X86DiagID::FeatureMissingSSE));
assert!(!suppressor.is_suppressed(X86DiagID::FeatureMissingAVX));
}
#[test]
fn test_suppressor_suppress_group() {
let mut suppressor = X86DiagnosticSuppressor::new();
suppressor.suppress_group("x86-missing-simd");
assert!(suppressor.is_suppressed(X86DiagID::FeatureMissingSSE));
assert!(suppressor.is_suppressed(X86DiagID::FeatureMissingAVX));
}
#[test]
fn test_suppressor_un_suppress() {
let mut suppressor = X86DiagnosticSuppressor::new();
suppressor.suppress_id(X86DiagID::FeatureMissingSSE);
assert!(suppressor.is_suppressed(X86DiagID::FeatureMissingSSE));
suppressor.unsuppress_id(X86DiagID::FeatureMissingSSE);
assert!(!suppressor.is_suppressed(X86DiagID::FeatureMissingSSE));
}
#[test]
fn test_suggestion_engine_has_feature_fixit() {
let engine = X86DiagnosticSuggestionEngine::new();
assert!(engine.has_feature_fixit("avx2"));
assert!(engine.has_feature_fixit("sse4.2"));
assert!(engine.has_feature_fixit("bmi"));
assert!(!engine.has_feature_fixit("nonexistent-feature"));
}
#[test]
fn test_suggestion_engine_flag_for_feature() {
let engine = X86DiagnosticSuggestionEngine::new();
assert_eq!(engine.flag_for_feature("avx"), Some("-mavx"));
assert_eq!(engine.flag_for_feature("fma"), Some("-mfma"));
assert_eq!(engine.flag_for_feature("nonexistent"), None);
}
#[test]
fn test_suggestion_engine_suggest_fixit_feature() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::FeatureMissingAVX, "avx");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("-mavx"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_abi() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::ABIStructTooLarge, "BigStruct");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("pointer"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_alignment() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::AlignUnalignedAccess, "data");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("aligned"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_inline_asm() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::InlineAsmStackPointerClobber, "");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("RSP"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_vector() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::VectorGatherUnsupported, "");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("AVX2"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_red_zone() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::BackendRedZoneViolation, "");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("stack pointer"));
}
#[test]
fn test_suggestion_engine_suggest_fixit_no_suggestion() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::BackendISelFail, "");
assert!(fixit.is_none());
}
#[test]
fn test_suggestion_engine_calling_convs() {
let engine = X86DiagnosticSuggestionEngine::new();
let alts = engine.suggest_calling_convention("cdecl");
assert!(!alts.contains(&"cdecl".to_string()));
assert!(alts.contains(&"stdcall".to_string()));
assert!(alts.contains(&"fastcall".to_string()));
}
#[test]
fn test_suggestion_engine_alignment_fix() {
let engine = X86DiagnosticSuggestionEngine::new();
assert!(engine.suggest_alignment_fix(16).is_some());
assert!(engine.suggest_alignment_fix(32).is_some());
assert!(engine.suggest_alignment_fix(64).is_some());
assert!(engine.suggest_alignment_fix(8).is_none());
}
#[test]
fn test_suggestion_engine_default() {
let engine = X86DiagnosticSuggestionEngine::default();
assert!(engine.has_feature_fixit("sse2"));
}
#[test]
fn test_counters_new() {
let counters = X86DiagnosticCounters::new();
assert_eq!(counters.total, 0);
assert_eq!(counters.errors, 0);
assert_eq!(counters.warnings, 0);
assert_eq!(counters.remarks, 0);
}
#[test]
fn test_counters_record_error() {
let mut counters = X86DiagnosticCounters::new();
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f".into()])
.build();
counters.record(&diag);
assert_eq!(counters.total, 1);
assert_eq!(counters.errors, 1);
assert_eq!(counters.warnings, 0);
}
#[test]
fn test_counters_record_warning() {
let mut counters = X86DiagnosticCounters::new();
let diag = X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build();
counters.record(&diag);
assert_eq!(counters.total, 1);
assert_eq!(counters.errors, 0);
assert_eq!(counters.warnings, 1);
}
#[test]
fn test_counters_record_remark() {
let mut counters = X86DiagnosticCounters::new();
let diag = X86BackendDiagnostic::new(X86DiagID::OptX86PeepholeApplied)
.with_args(vec!["a".into(), "b".into(), "f".into()])
.build();
counters.record(&diag);
assert_eq!(counters.total, 1);
assert_eq!(counters.remarks, 1);
}
#[test]
fn test_counters_record_all() {
let mut counters = X86DiagnosticCounters::new();
let diags = vec![
X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f1".into()])
.build(),
X86BackendDiagnostic::new(X86DiagID::FeatureMissingAVX)
.with_args(vec![])
.build(),
X86BackendDiagnostic::new(X86DiagID::BackendCannotSelect)
.with_args(vec!["sub".into(), "f2".into()])
.build(),
];
counters.record_all(&diags);
assert_eq!(counters.total, 3);
assert_eq!(counters.errors, 2);
assert_eq!(counters.warnings, 1);
}
#[test]
fn test_counters_summary() {
let mut counters = X86DiagnosticCounters::new();
counters.errors = 3;
counters.warnings = 5;
counters.total = 8;
let summary = counters.summary();
assert!(summary.contains("8"));
assert!(summary.contains("3 error"));
assert!(summary.contains("5 warning"));
}
#[test]
fn test_counters_reset() {
let mut counters = X86DiagnosticCounters::new();
counters.errors = 5;
counters.total = 10;
counters.reset();
assert_eq!(counters.total, 0);
assert_eq!(counters.errors, 0);
}
#[test]
fn test_counters_by_category() {
let mut counters = X86DiagnosticCounters::new();
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f".into()])
.build();
counters.record(&diag);
cats = vec!["x86-backend"];
let cat_count = counters.by_category.get("x86-backend");
assert_eq!(cat_count, Some(&1));
}
#[test]
fn test_batch_processor_new() {
let processor = X86DiagnosticBatchProcessor::new();
assert_eq!(
processor.summary(),
"0 diagnostic(s): 0 error(s), 0 warning(s), 0 remark(s)"
);
}
#[test]
fn test_batch_processor_process_one() {
let mut processor = X86DiagnosticBatchProcessor::new();
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f".into()])
.build();
processor.process(diag);
let summary = processor.summary();
assert!(summary.contains("1 error"));
}
#[test]
fn test_batch_processor_process_all() {
let mut processor = X86DiagnosticBatchProcessor::new();
let diags = vec![
X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f1".into()])
.build(),
X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build(),
];
processor.process_all(diags);
let summary = processor.summary();
assert!(summary.contains("2 diagnostic"));
assert!(summary.contains("1 error"));
assert!(summary.contains("1 warning"));
}
#[test]
fn test_batch_processor_reset() {
let mut processor = X86DiagnosticBatchProcessor::new();
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f".into()])
.build();
processor.process(diag);
processor.reset();
assert_eq!(
processor.summary(),
"0 diagnostic(s): 0 error(s), 0 warning(s), 0 remark(s)"
);
}
#[test]
fn test_batch_processor_default() {
let processor = X86DiagnosticBatchProcessor::default();
assert!(processor.summary().contains("0 diagnostic"));
}
#[test]
fn test_integration_emitter_with_severity_override() {
let mut emitter = X86DiagnosticEmitter::new();
emitter
.severity_map
.set_severity(X86DiagID::FeatureMissingSSE, DiagSeverity::Error);
emitter.emit_feature_missing("sse");
assert_eq!(emitter.diagnostic_count(), 1);
assert_eq!(emitter.error_count(), 1);
assert_eq!(emitter.warning_count(), 0);
}
#[test]
fn test_integration_emitter_with_suppression() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.suppressor.suppress_id(X86DiagID::BackendISelFail);
emitter.emit_isel_failure("add", "f");
assert_eq!(emitter.diagnostic_count(), 0);
}
#[test]
fn test_integration_emitter_with_suggestion() {
let engine = X86DiagnosticSuggestionEngine::new();
let fixit = engine.suggest_fixit(X86DiagID::FeatureMissingAVX512F, "avx512f");
assert!(fixit.is_some());
assert!(fixit.unwrap().contains("-mavx512f"));
}
#[test]
fn test_integration_counters_with_batch() {
let mut counters = X86DiagnosticCounters::new();
let diags = vec![
X86BackendDiagnostic::new(X86DiagID::BackendRegallocFail)
.with_args(vec!["f1".into()])
.build(),
X86BackendDiagnostic::new(X86DiagID::FeatureMissingFMA)
.with_args(vec![])
.build(),
X86BackendDiagnostic::new(X86DiagID::ABIStructTooLarge)
.with_args(vec!["Big".into(), "128".into()])
.build(),
X86BackendDiagnostic::new(X86DiagID::OptX86ShrinkWrapping)
.with_args(vec!["f2".into()])
.build(),
];
counters.record_all(&diags);
assert_eq!(counters.total, 4);
assert_eq!(counters.errors, 1); assert_eq!(counters.warnings, 2); assert_eq!(counters.remarks, 1); }
#[test]
fn test_integration_matcher_with_emitter() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.emit_isel_failure("add", "test_func");
emitter.emit_feature_missing("avx");
let mut matcher = X86DiagnosticMatcher::new();
matcher.expect_error(X86DiagID::BackendISelFail, "instruction selection failed");
matcher.expect_warning(X86DiagID::FeatureMissingAVX, "AVX");
let result = matcher.run_all(&mut emitter.diagnostics);
assert!(result.is_ok());
}
#[test]
fn test_integration_renderer_with_all_severities() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
let diags = vec![
X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["add".into(), "f1".into()])
.build(),
X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build(),
X86BackendDiagnostic::new(X86DiagID::OptX86ISelSuccess)
.with_args(vec!["sub".into(), "SUB64rr".into(), "f2".into()])
.build(),
];
for d in &diags {
renderer.render(d).unwrap();
}
assert_eq!(renderer.error_count, 1);
assert_eq!(renderer.warning_count, 1);
assert_eq!(renderer.remark_count, 1);
}
#[test]
fn test_integration_feature_diag_to_backend() {
let feature_diag = X86TargetFeatureDiag::missing_feature("avx512bw");
let formatted = feature_diag.format();
assert!(formatted.contains("AVX-512 Byte/Word"));
let backend_diag = X86BackendDiagnostic::new(feature_diag.id)
.with_args(vec![feature_diag.feature.clone()])
.build();
assert!(backend_diag.message.contains("AVX-512"));
}
#[test]
fn test_integration_abi_to_align() {
let abi_diag = X86ABIDiagnostic::new(X86DiagID::ABIUnalignedFieldPass)
.with_type("MyStruct")
.with_size(24);
let align_diag = X86AlignDiagnostic::new(X86DiagID::AlignStructAlign);
let align_diag = X86AlignDiagnostic {
variable_name: Some("MyStruct".into()),
required_alignment: Some(16),
current_alignment: Some(4),
..align_diag
};
assert!(abi_diag.format().contains("unaligned"));
assert!(align_diag.format().contains("MyStruct"));
}
#[test]
fn test_integration_vector_to_feature() {
let vec_diag = X86VectorDiag::new(X86DiagID::VectorAVX512UpgradeHint);
let vec_diag = X86VectorDiag {
expected_width: Some(256),
..vec_diag
};
let feat_diag = X86TargetFeatureDiag::missing_feature("avx512f");
assert!(vec_diag.format().contains("AVX-512"));
assert!(feat_diag.format().contains("AVX-512 Foundation"));
}
#[test]
fn test_catalog_fatal_severities() {
let fatal_ids = [
X86DiagID::BackendISelFail,
X86DiagID::FeatureMissingSSE,
X86DiagID::ABIStructTooLarge,
X86DiagID::OptX86ISelSuccess,
];
for &id in &fatal_ids {
assert!(!matches!(
X86DiagnosticCatalog::default_severity(id),
DiagSeverity::Fatal
));
}
}
#[test]
fn test_catalog_unique_messages() {
let msg_backend = X86DiagnosticCatalog::message_for(X86DiagID::BackendISelFail);
let msg_feature = X86DiagnosticCatalog::message_for(X86DiagID::FeatureMissingSSE);
let msg_abi = X86DiagnosticCatalog::message_for(X86DiagID::ABIStructTooLarge);
assert_ne!(msg_backend, msg_feature);
assert_ne!(msg_backend, msg_abi);
assert_ne!(msg_feature, msg_abi);
}
#[test]
fn test_catalog_flag_name_format() {
for id_val in [
X86DiagID::BackendISelFail as u32,
X86DiagID::FeatureMissingSSE as u32,
X86DiagID::ABIStructTooLarge as u32,
X86DiagID::AlignUnalignedAccess as u32,
X86DiagID::InlineAsmParseError as u32,
X86DiagID::VectorWidthMismatch as u32,
X86DiagID::OptX86ISelSuccess as u32,
X86DiagID::LinkerRelocationOverflow as u32,
X86DiagID::MiscStackProbe as u32,
] {
let id: X86DiagID = unsafe { std::mem::transmute(id_val) };
let flag = X86DiagnosticCatalog::flag_name(id);
assert!(
flag.starts_with("-W") || flag.starts_with("-R"),
"Flag {:?} for {:?} doesn't start with -W or -R",
flag,
id
);
}
}
#[test]
fn test_catalog_category_consistency() {
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::OptX86ISelSuccess),
X86DiagnosticCatalog::category(X86DiagID::OptX86ISelFailure)
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::FeatureMissingSSE),
X86DiagnosticCatalog::category(X86DiagID::FeatureMissingAVX2)
);
assert_eq!(
X86DiagnosticCatalog::category(X86DiagID::ABIStructTooLarge),
X86DiagnosticCatalog::category(X86DiagID::ABIReturnTooLarge)
);
}
#[test]
fn test_stress_many_diagnostics() {
let mut emitter = X86DiagnosticEmitter::new();
for i in 0..100 {
emitter.emit_isel_failure(&format!("op{}", i), "stress_func");
}
assert_eq!(emitter.diagnostic_count(), 100);
assert_eq!(emitter.error_count(), 100);
}
#[test]
fn test_stress_many_feature_warnings() {
let mut emitter = X86DiagnosticEmitter::new();
let features = [
"sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512f",
"avx512bw", "avx512dq", "avx512vl", "fma", "bmi", "bmi2", "lzcnt", "popcnt", "aes",
"pclmul", "sha", "rdrand", "rdseed", "adx",
];
for feat in &features {
emitter.emit_feature_missing(feat);
}
assert_eq!(emitter.diagnostic_count(), features.len());
assert_eq!(emitter.warning_count(), features.len());
}
#[test]
fn test_stress_max_errors_stops_emission() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.set_max_errors(5);
for i in 0..20 {
emitter.emit_isel_failure(&format!("op{}", i), "f");
}
assert_eq!(emitter.diagnostic_count(), 5);
assert!(emitter.error_limit_reached());
}
#[test]
fn test_stress_suppression_all_backend() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.suppressor.suppress_group("x86-backend-isel");
emitter.emit_isel_failure("add", "f");
emitter.emit_cannot_select("add", "node0", "f");
assert_eq!(emitter.diagnostic_count(), 0);
}
#[test]
fn test_stress_remarks_not_counted_as_errors() {
let mut emitter = X86DiagnosticEmitter::new();
emitter.enable_remarks();
emitter.emit_isel_success("add", "ADD64rr", "f");
emitter.emit_peephole_applied("a", "b", "f");
emitter.emit_macro_fusion("cmp", "jne", "f");
assert_eq!(emitter.diagnostic_count(), 3);
assert_eq!(emitter.error_count(), 0);
assert_eq!(emitter.warning_count(), 0);
}
#[test]
fn test_stress_unicode_in_diagnostic_message() {
let diag = X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec!["fñńć".into(), "my_func_λ".into()])
.build();
let formatted = diag.format();
assert!(!formatted.is_empty());
}
#[test]
fn test_stress_empty_args() {
let diag = X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build();
assert!(!diag.message.is_empty());
assert!(!diag.message.contains("{}"));
}
#[test]
fn test_stress_group_registry_no_duplicates() {
let registry = X86DiagnosticGroupRegistry::new();
let mut all_member_ids = Vec::new();
for (_, group) in ®istry.groups {
for &id in &group.members {
all_member_ids.push(id);
}
}
let len_before = all_member_ids.len();
all_member_ids.sort();
all_member_ids.dedup();
assert_eq!(
len_before,
all_member_ids.len(),
"Duplicate member IDs found across groups"
);
}
#[test]
fn test_stress_feature_id_roundtrip() {
let features = [
"sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512f",
"avx512bw", "avx512dq", "avx512vl", "fma", "mmx", "3dnow", "bmi", "bmi2", "lzcnt",
"popcnt", "aes", "pclmul", "sha", "rdrand", "rdseed", "adx", "rtm", "sgx", "cet",
"xsave", "fsgsbase", "movbe",
];
for feat in &features {
let id = X86TargetFeatureDiag::id_for_feature(feat);
let msg = X86DiagnosticCatalog::message_for(id);
assert!(
!msg.is_empty(),
"No message for feature '{}' -> {:?}",
feat,
id
);
}
}
#[test]
fn test_stress_renderer_large_output() {
let writer: Vec<u8> = Vec::new();
let mut renderer = X86DiagnosticRenderer::new(writer);
renderer.use_colors = true;
for _ in 0..50 {
let diag = X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build();
renderer.render(&diag).unwrap();
}
assert_eq!(renderer.warning_count, 50);
}
#[test]
fn test_stress_batch_processor_large_batch() {
let mut processor = X86DiagnosticBatchProcessor::new();
let mut diags = Vec::new();
for i in 0..200 {
let diag = if i % 3 == 0 {
X86BackendDiagnostic::new(X86DiagID::BackendISelFail)
.with_args(vec![format!("op{}", i), "func".into()])
.build()
} else if i % 3 == 1 {
X86BackendDiagnostic::new(X86DiagID::FeatureMissingSSE)
.with_args(vec![])
.build()
} else {
X86BackendDiagnostic::new(X86DiagID::OptX86PeepholeApplied)
.with_args(vec!["a".into(), "b".into(), "f".into()])
.build()
};
diags.push(diag);
}
processor.process_all(diags);
assert_eq!(processor.counters.total, 200);
}
#[test]
fn test_stress_suggestion_engine_all_features() {
let engine = X86DiagnosticSuggestionEngine::new();
let features = ["avx", "avx2", "sse2", "sse4.1", "fma", "bmi", "aes"];
let mut found = 0;
for feat in &features {
if engine.has_feature_fixit(feat) {
found += 1;
}
}
assert_eq!(found, features.len());
}
#[test]
fn test_stress_all_categories_have_messages() {
let samples = [
X86DiagID::BackendISelFail,
X86DiagID::BackendRegallocSpill,
X86DiagID::BackendFrameTooLarge,
X86DiagID::BackendEncodingFail,
X86DiagID::BackendEmissionFail,
X86DiagID::BackendBranchTargetTooFar,
X86DiagID::BackendFastISelFail,
X86DiagID::BackendGISelFail,
X86DiagID::FeatureMissingSSE,
X86DiagID::FeatureMissingAVX,
X86DiagID::FeatureMissingAVX512F,
X86DiagID::FeatureMissingFMA,
X86DiagID::FeatureMissingAMX_TILE,
X86DiagID::FeatureDeprecated,
X86DiagID::FeatureConflicting,
X86DiagID::ABIStructTooLarge,
X86DiagID::ABIMismatchedCallingConv,
X86DiagID::ABISysVClassificationFailed,
X86DiagID::SizeFunctionTooLarge,
X86DiagID::SizeELFTextOverflow,
X86DiagID::AlignUnalignedAccess,
X86DiagID::AlignCacheLineBoundary,
X86DiagID::InlineAsmParseError,
X86DiagID::InlineAsmFramePointerClobber,
X86DiagID::InlineAsmAVX512MaskOperand,
X86DiagID::VectorWidthMismatch,
X86DiagID::VectorGatherUnsupported,
X86DiagID::VectorAMXConfig,
X86DiagID::OptX86ISelSuccess,
X86DiagID::OptX86PeepholeApplied,
X86DiagID::OptX86MacroFusion,
X86DiagID::OptX86VZeroupperInserted,
X86DiagID::OptX86RegisterCoalescing,
X86DiagID::OptX86HotColdSplit,
X86DiagID::LinkerRelocationOverflow,
X86DiagID::LinkerTLSOverflow,
X86DiagID::MiscStackProbe,
X86DiagID::MiscCETEndBranch,
X86DiagID::MiscZeroCallUsedRegs,
];
for &id in &samples {
let msg = X86DiagnosticCatalog::message_for(id);
assert!(!msg.is_empty(), "Empty message for {:?}", id);
let flag = X86DiagnosticCatalog::flag_name(id);
assert!(!flag.is_empty(), "Empty flag for {:?}", id);
let cat = X86DiagnosticCatalog::category(id);
assert!(!cat.is_empty(), "Empty category for {:?}", id);
}
}
#[test]
fn test_suggestion_engine_case_insensitive() {
let engine = X86DiagnosticSuggestionEngine::new();
assert!(engine.has_feature_fixit("AVX2"));
assert!(engine.has_feature_fixit("Avx"));
assert!(engine.has_feature_fixit("SSE4.1"));
}
}