[llvm] 66d41f8 - Reapply "[llvm-exegesis] Add AArch64 operand initializers, SetRegTo" (#174729) (#174944)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 9 00:16:53 PST 2026


Author: Cullen Rhodes
Date: 2026-01-09T08:16:49Z
New Revision: 66d41f848393cdb4253fb1a845e3c277efe53ded

URL: https://github.com/llvm/llvm-project/commit/66d41f848393cdb4253fb1a845e3c277efe53ded
DIFF: https://github.com/llvm/llvm-project/commit/66d41f848393cdb4253fb1a845e3c277efe53ded.diff

LOG: Reapply "[llvm-exegesis] Add AArch64 operand initializers, SetRegTo" (#174729) (#174944)

This reverts commit f68774fd1ad570fef850439ac163b61dc96b98f1. The
original PR broke the sanitizer-aarch64-linux-bootstrap-asan builder:
https://lab.llvm.org/buildbot/#/builders/24/builds/16298

The cause of the failure was exegesis producing inconsistent results
across libc++ implementations when seeded with
'--random-generator-seed=<seed>'. The failing Buildbot does a 2-stage
build, in the 1st stage it builds LLVMs libc++ then builds LLVM with it
in the 2nd stage. The exegesis implementation relies on
uniform_int_distribution which doesn't guarantee consistent results
across implementations.

The tests seeded the RNG because FileCheck can't handle the wrap around
constraint of the register pairs, e.g. { v31.1d, v0.1d }. The test is
updated to no longer rely on '--random-generator-seed'. Unfortunately
the tests aren't particularly good anymore, but not sure what else can
be done for now.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
    llvm/test/tools/llvm-exegesis/AArch64/all-opcodes.test
    llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
    llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 06c628d5000f6..9599a572141e4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -389,12 +389,14 @@ def simm10Scaled : Operand<i64> {
   let ParserMatchClass = SImm10s8Operand;
   let DecoderMethod = "DecodeSImm<10>";
   let PrintMethod = "printImmScale<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm9s16 : Operand<i64> {
   let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;
   let DecoderMethod = "DecodeSImm<9>";
   let PrintMethod = "printImmScale<16>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // uimm6 predicate - True if the immediate is in the range [0, 63].
@@ -405,18 +407,22 @@ def UImm6Operand : AsmOperandClass {
 
 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
   let ParserMatchClass = UImm6Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
   let ParserMatchClass = AsmImmRange<0, 65535>;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm6_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
     let ParserMatchClass = UImm6Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
    let ParserMatchClass = UImm6Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def CmpBranchUImm6Operand_32b
@@ -453,24 +459,29 @@ def UImm6Minus1Operand : AsmOperandClass {
 
 def uimm6p1_32b : Operand<i32> {
   let ParserMatchClass = UImm6Plus1Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm6p1_64b : Operand<i64> {
   let ParserMatchClass = UImm6Plus1Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm6m1_32b : Operand<i32> {
   let ParserMatchClass = UImm6Minus1Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm6m1_64b : Operand<i64> {
   let ParserMatchClass = UImm6Minus1Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def SImm9Operand : SImmOperand<9>;
 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
   let ParserMatchClass = SImm9Operand;
   let DecoderMethod = "DecodeSImm<9>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // imm0_255 predicate - True if the immediate is in the range [0,255].
@@ -478,48 +489,57 @@ def Imm0_255Operand : AsmImmRange<0,255>;
 
 def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
   let ParserMatchClass = Imm0_255Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> {
   let ParserMatchClass = Imm0_255Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def SImm8Operand : SImmOperand<8>;
 def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {
   let ParserMatchClass = SImm8Operand;
   let DecoderMethod = "DecodeSImm<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> {
   let ParserMatchClass = SImm8Operand;
   let DecoderMethod = "DecodeSImm<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def SImm6Operand : SImmOperand<6>;
 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
   let ParserMatchClass = SImm6Operand;
   let DecoderMethod = "DecodeSImm<6>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def SImm5Operand : SImmOperand<5>;
 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
   let ParserMatchClass = SImm5Operand;
   let DecoderMethod = "DecodeSImm<5>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
   let ParserMatchClass = SImm5Operand;
   let DecoderMethod = "DecodeSImm<5>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {
   let ParserMatchClass = SImm5Operand;
   let DecoderMethod = "DecodeSImm<5>";
   let PrintMethod = "printSImm<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {
   let ParserMatchClass = SImm5Operand;
   let DecoderMethod = "DecodeSImm<5>";
   let PrintMethod = "printSImm<16>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // simm7sN predicate - True if the immediate is a multiple of N in the range
@@ -532,16 +552,19 @@ def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
 def simm7s4 : Operand<i32> {
   let ParserMatchClass = SImm7s4Operand;
   let PrintMethod = "printImmScale<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm7s8 : Operand<i32> {
   let ParserMatchClass = SImm7s8Operand;
   let PrintMethod = "printImmScale<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm7s16 : Operand<i32> {
   let ParserMatchClass = SImm7s16Operand;
   let PrintMethod = "printImmScale<16>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>;
@@ -591,18 +614,21 @@ def uimm5s2 : Operand<i64>, ImmLeaf<i64,
                 UImmS2XForm> {
   let ParserMatchClass = UImm5s2Operand;
   let PrintMethod = "printImmScale<2>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
                 UImmS4XForm> {
   let ParserMatchClass = UImm5s4Operand;
   let PrintMethod = "printImmScale<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
                 UImmS8XForm> {
   let ParserMatchClass = UImm5s8Operand;
   let PrintMethod = "printImmScale<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // tuimm5sN predicate - similar to uimm5sN, but use TImmLeaf (TargetConstant)
@@ -612,18 +638,21 @@ def tuimm5s2 : Operand<i64>, TImmLeaf<i64,
                 UImmS2XForm> {
   let ParserMatchClass = UImm5s2Operand;
   let PrintMethod = "printImmScale<2>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def tuimm5s4 : Operand<i64>, TImmLeaf<i64,
                 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],
                 UImmS4XForm> {
   let ParserMatchClass = UImm5s4Operand;
   let PrintMethod = "printImmScale<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def tuimm5s8 : Operand<i64>, TImmLeaf<i64,
                 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],
                 UImmS8XForm> {
   let ParserMatchClass = UImm5s8Operand;
   let PrintMethod = "printImmScale<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // uimm6sN predicate - True if the immediate is a multiple of N in the range
@@ -636,26 +665,31 @@ def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;
 
 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
   let ParserMatchClass = UImm6s1Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
   let PrintMethod = "printImmScale<2>";
   let ParserMatchClass = UImm6s2Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
   let PrintMethod = "printImmScale<4>";
   let ParserMatchClass = UImm6s4Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
   let PrintMethod = "printImmScale<8>";
   let ParserMatchClass = UImm6s8Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def uimm6s16 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {
   let PrintMethod = "printImmScale<16>";
   let ParserMatchClass = UImm6s16Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def SImmS2XForm : SDNodeXForm<imm, [{
@@ -680,6 +714,7 @@ def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
   let ParserMatchClass = SImm6s1Operand;
   let DecoderMethod = "DecodeSImm<6>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // simm4sN predicate - True if the immediate is a multiple of N in the range
@@ -695,6 +730,7 @@ def simm4s1 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >=-8  && Imm <= 7; }]> {
   let ParserMatchClass = SImm4s1Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm4s2 : Operand<i64>, ImmLeaf<i64,
@@ -702,6 +738,7 @@ def simm4s2 : Operand<i64>, ImmLeaf<i64,
   let PrintMethod = "printImmScale<2>";
   let ParserMatchClass = SImm4s2Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm4s3 : Operand<i64>, ImmLeaf<i64,
@@ -709,6 +746,7 @@ def simm4s3 : Operand<i64>, ImmLeaf<i64,
   let PrintMethod = "printImmScale<3>";
   let ParserMatchClass = SImm4s3Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def simm4s4 : Operand<i64>, ImmLeaf<i64,
@@ -716,18 +754,21 @@ def simm4s4 : Operand<i64>, ImmLeaf<i64,
   let PrintMethod = "printImmScale<4>";
   let ParserMatchClass = SImm4s4Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def simm4s16 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >=-128  && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {
   let PrintMethod = "printImmScale<16>";
   let ParserMatchClass = SImm4s16Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def simm4s32 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >=-256  && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {
   let PrintMethod = "printImmScale<32>";
   let ParserMatchClass = SImm4s32Operand;
   let DecoderMethod = "DecodeSImm<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def Imm1_8Operand : AsmImmRange<1, 8>;
@@ -757,6 +798,7 @@ def MovWSymbolG3AsmOperand : AsmOperandClass {
 
 def movw_symbol_g3 : Operand<i32> {
   let ParserMatchClass = MovWSymbolG3AsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def MovWSymbolG2AsmOperand : AsmOperandClass {
@@ -766,6 +808,7 @@ def MovWSymbolG2AsmOperand : AsmOperandClass {
 
 def movw_symbol_g2 : Operand<i32> {
   let ParserMatchClass = MovWSymbolG2AsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def MovWSymbolG1AsmOperand : AsmOperandClass {
@@ -775,6 +818,7 @@ def MovWSymbolG1AsmOperand : AsmOperandClass {
 
 def movw_symbol_g1 : Operand<i32> {
   let ParserMatchClass = MovWSymbolG1AsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def MovWSymbolG0AsmOperand : AsmOperandClass {
@@ -784,6 +828,7 @@ def MovWSymbolG0AsmOperand : AsmOperandClass {
 
 def movw_symbol_g0 : Operand<i32> {
   let ParserMatchClass = MovWSymbolG0AsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class fixedpoint_i32<ValueType FloatVT>
@@ -792,6 +837,7 @@ class fixedpoint_i32<ValueType FloatVT>
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm32";
   let ParserMatchClass = Imm1_32Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class fixedpoint_i64<ValueType FloatVT>
@@ -800,6 +846,7 @@ class fixedpoint_i64<ValueType FloatVT>
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm64";
   let ParserMatchClass = Imm1_64Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
@@ -815,6 +862,7 @@ class fixedpoint_recip_i32<ValueType FloatVT>
     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> {
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm32";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class fixedpoint_recip_i64<ValueType FloatVT>
@@ -822,6 +870,7 @@ class fixedpoint_recip_i64<ValueType FloatVT>
     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> {
   let EncoderMethod = "getFixedPointScaleOpValue";
   let DecoderMethod = "DecodeFixedPointScaleImm64";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>;
@@ -838,6 +887,7 @@ def vecshiftR8 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR8OpValue";
   let DecoderMethod = "DecodeVecShiftR8Imm";
   let ParserMatchClass = Imm1_8Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
@@ -845,6 +895,7 @@ def vecshiftR16 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR16OpValue";
   let DecoderMethod = "DecodeVecShiftR16Imm";
   let ParserMatchClass = Imm1_16Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR16Narrow : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
@@ -852,6 +903,7 @@ def vecshiftR16Narrow : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR16OpValue";
   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
   let ParserMatchClass = Imm1_8Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
@@ -859,6 +911,7 @@ def vecshiftR32 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR32OpValue";
   let DecoderMethod = "DecodeVecShiftR32Imm";
   let ParserMatchClass = Imm1_32Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR32Narrow : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
@@ -866,6 +919,7 @@ def vecshiftR32Narrow : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR32OpValue";
   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
   let ParserMatchClass = Imm1_16Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
@@ -873,6 +927,7 @@ def vecshiftR64 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR64OpValue";
   let DecoderMethod = "DecodeVecShiftR64Imm";
   let ParserMatchClass = Imm1_64Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftR64Narrow : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
@@ -880,6 +935,7 @@ def vecshiftR64Narrow : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftR64OpValue";
   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
   let ParserMatchClass = Imm1_32Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def Imm0_0Operand : AsmImmRange<0, 0>;
@@ -899,6 +955,7 @@ def vecshiftL8 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftL8OpValue";
   let DecoderMethod = "DecodeVecShiftL8Imm";
   let ParserMatchClass = Imm0_7Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) < 16);
@@ -906,6 +963,7 @@ def vecshiftL16 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftL16OpValue";
   let DecoderMethod = "DecodeVecShiftL16Imm";
   let ParserMatchClass = Imm0_15Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) < 32);
@@ -913,6 +971,7 @@ def vecshiftL32 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftL32OpValue";
   let DecoderMethod = "DecodeVecShiftL32Imm";
   let ParserMatchClass = Imm0_31Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def vecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
   return (((uint32_t)Imm) < 64);
@@ -920,6 +979,7 @@ def vecshiftL64 : Operand<i32>, TImmLeaf<i32, [{
   let EncoderMethod = "getVecShiftL64OpValue";
   let DecoderMethod = "DecodeVecShiftL64Imm";
   let ParserMatchClass = Imm0_63Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 
@@ -1219,6 +1279,8 @@ class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
   let PrintMethod = "printShiftedRegister";
   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
+  let OperandType = "OPERAND_SHIFTED_REGISTER";
+  let OperandNamespace = "AArch64";
 }
 
 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
@@ -1239,6 +1301,7 @@ class logical_shift<int width> : Operand<i32> {
   let PrintMethod = "printShifter";
   let ParserMatchClass = !cast<AsmOperandClass>(
                          "LogicalShifterOperand" # width);
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def logical_shift32 : logical_shift<32>;
@@ -1249,6 +1312,8 @@ class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
   let PrintMethod = "printShiftedRegister";
   let MIOperandInfo = (ops regclass, shiftop);
+  let OperandType = "OPERAND_SHIFTED_REGISTER";
+  let OperandNamespace = "AArch64";
 }
 
 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
@@ -1269,6 +1334,8 @@ def logical_vec_shift : Operand<i32> {
   let PrintMethod = "printShifter";
   let EncoderMethod = "getVecShifterOpValue";
   let ParserMatchClass = LogicalVecShifterOperand;
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 // A logical vector half-word shifter operand:
@@ -1278,6 +1345,8 @@ def logical_vec_hw_shift : Operand<i32> {
   let PrintMethod = "printShifter";
   let EncoderMethod = "getVecShifterOpValue";
   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 // A vector move shifter operand:
@@ -1312,6 +1381,8 @@ class addsub_shifted_imm<ValueType Ty>
   let EncoderMethod = "getAddSubImmOpValue";
   let ParserMatchClass = AddSubImmOperand;
   let MIOperandInfo = (ops i32imm, i32imm);
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 class addsub_shifted_imm_neg<ValueType Ty>
@@ -1319,6 +1390,8 @@ class addsub_shifted_imm_neg<ValueType Ty>
   let EncoderMethod = "getAddSubImmOpValue";
   let ParserMatchClass = AddSubImmNegOperand;
   let MIOperandInfo = (ops i32imm, i32imm);
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
@@ -1340,6 +1413,8 @@ class neg_addsub_shifted_imm<ValueType Ty>
   let EncoderMethod = "getAddSubImmOpValue";
   let ParserMatchClass = AddSubImmOperand;
   let MIOperandInfo = (ops i32imm, i32imm);
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
@@ -1359,28 +1434,35 @@ def gi_neg_addsub_shifted_imm64 :
 def arith_extend : Operand<i32> {
   let PrintMethod = "printArithExtend";
   let ParserMatchClass = ExtendOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def arith_extend64 : Operand<i32> {
   let PrintMethod = "printArithExtend";
   let ParserMatchClass = ExtendOperand64;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // 'extend' that's a lsl of a 64-bit register.
 def arith_extendlsl64 : Operand<i32> {
   let PrintMethod = "printArithExtend";
   let ParserMatchClass = ExtendOperandLSL64;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
   let PrintMethod = "printExtendedRegister";
   let MIOperandInfo = (ops GPR32, arith_extend);
+  let OperandType = "OPERAND_SHIFTED_REGISTER";
+  let OperandNamespace = "AArch64";
 }
 
 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
   let PrintMethod = "printExtendedRegister";
   let MIOperandInfo = (ops GPR32, arith_extend64);
+  let OperandType = "OPERAND_SHIFTED_REGISTER";
+  let OperandNamespace = "AArch64";
 }
 
 def arith_extended_reg32_i32 : arith_extended_reg32<i32>;
@@ -1462,6 +1544,7 @@ def fpimm64 : Operand<f64>,
 def fpimm8 : Operand<i32> {
   let ParserMatchClass = FPImmOperand;
   let PrintMethod = "printFPImmOperand";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def fpimm0 : FPImmLeaf<fAny, [{
@@ -1527,6 +1610,7 @@ let OperandNamespace = "AArch64", OperandType = "OPERAND_IMPLICIT_IMM_0",
   defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand,
                                      [{ return ((uint32_t)Imm) == 0; }]>;
 }
+let OperandType = "OPERAND_IMMEDIATE" in {
 defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
                                 [{ return ((uint64_t)Imm) == 1; }]>;
 defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,
@@ -1548,6 +1632,7 @@ defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,
                                    [{ return ((uint64_t)Imm) < 4; }]>;
 defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,
                                    [{ return ((uint64_t)Imm) < 2; }]>;
+}
 
 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
@@ -1555,6 +1640,7 @@ def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
 
+let OperandType = "OPERAND_IMMEDIATE" in {
 defm sve_elm_idx_extdup_b
   : VectorIndex<i64, SVEVectorIndexExtDupBOperand,
                 [{ return ((uint64_t)Imm) < 64; }]>;
@@ -1570,6 +1656,7 @@ defm sve_elm_idx_extdup_d
 defm sve_elm_idx_extdup_q
   : VectorIndex<i64, SVEVectorIndexExtDupQOperand,
                 [{ return ((uint64_t)Imm) < 4; }]>;
+}
 
 def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{
   return ((uint32_t)Imm) == 0;
@@ -1585,24 +1672,28 @@ def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{
 }]> {
   let ParserMatchClass = Imm0_1Operand;
   let PrintMethod = "printMatrixIndex";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{
   return ((uint32_t)Imm) <= 3;
 }]> {
   let ParserMatchClass = Imm0_3Operand;
   let PrintMethod = "printMatrixIndex";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{
   return ((uint32_t)Imm) <= 7;
 }]> {
   let ParserMatchClass = Imm0_7Operand;
   let PrintMethod = "printMatrixIndex";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{
   return ((uint32_t)Imm) <= 15;
 }]> {
   let ParserMatchClass = Imm0_15Operand;
   let PrintMethod = "printMatrixIndex";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // SME2 vector select offset operands
@@ -1615,6 +1706,7 @@ def uimm3s8 : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> {
   let PrintMethod = "printMatrixIndex<8>";
   let ParserMatchClass = UImm3s8Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass {
@@ -1658,30 +1750,35 @@ def uimm1s2range : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> {
   let PrintMethod = "printImmRangeScale<2, 1>";
   let ParserMatchClass = UImm1s2RangeOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm1s4range : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> {
   let PrintMethod = "printImmRangeScale<4, 3>";
   let ParserMatchClass = UImm1s4RangeOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm2s2range : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> {
   let PrintMethod = "printImmRangeScale<2, 1>";
   let ParserMatchClass = UImm2s2RangeOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm2s4range : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> {
   let PrintMethod = "printImmRangeScale<4, 3>";
   let ParserMatchClass = UImm2s4RangeOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm3s2range : Operand<i64>, ImmLeaf<i64,
 [{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> {
   let PrintMethod = "printImmRangeScale<2, 1>";
   let ParserMatchClass = UImm3s2RangeOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 
@@ -1700,6 +1797,7 @@ def simdimmtype10 : Operand<i32>,
     }]>> {
   let ParserMatchClass = SIMDImmType10Operand;
   let PrintMethod = "printSIMDType10Operand";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 
@@ -1769,6 +1867,7 @@ def PHintInstOperand : AsmOperandClass {
 def phint_op : Operand<i32> {
     let ParserMatchClass = PHintInstOperand;
    let PrintMethod = "printPHintOp";
+   let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class STSHHI
@@ -1789,6 +1888,7 @@ def BarrierAsmOperand : AsmOperandClass {
 def barrier_op : Operand<i32> {
   let PrintMethod = "printBarrierOption";
   let ParserMatchClass = BarrierAsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def BarriernXSAsmOperand : AsmOperandClass {
   let Name = "BarriernXS";
@@ -1797,6 +1897,7 @@ def BarriernXSAsmOperand : AsmOperandClass {
 def barrier_nxs_op : Operand<i32> {
   let PrintMethod = "printBarriernXSOption";
   let ParserMatchClass = BarriernXSAsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
                  list<dag> pattern = []>
@@ -1831,6 +1932,7 @@ def mrs_sysreg_op : Operand<i32> {
   let ParserMatchClass = MRSSystemRegisterOperand;
   let DecoderMethod = "DecodeMRSSystemRegister";
   let PrintMethod = "printMRSSystemRegister";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def MSRSystemRegisterOperand : AsmOperandClass {
@@ -1842,6 +1944,7 @@ def msr_sysreg_op : Operand<i32> {
   let ParserMatchClass = MSRSystemRegisterOperand;
   let DecoderMethod = "DecodeMSRSystemRegister";
   let PrintMethod = "printMSRSystemRegister";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def PSBHintOperand : AsmOperandClass {
@@ -1858,6 +1961,7 @@ def psbhint_op : Operand<i32> {
       return false;
     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def BTIHintOperand : AsmOperandClass {
@@ -1873,6 +1977,7 @@ def btihint_op : Operand<i32> {
       return false;
     return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def CMHPriorityHintOperand : AsmOperandClass {
@@ -1888,6 +1993,7 @@ def CMHPriorityHint_op : Operand<i32> {
       return false;
     return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(MCOp.getImm()) != nullptr;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def TIndexHintOperand : AsmOperandClass {
@@ -1939,6 +2045,7 @@ def pstatefield4_op : Operand<i32> {
       return false;
     return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // Instructions to modify PSTATE, no input reg
@@ -1979,6 +2086,7 @@ def pstatefield1_op : Operand<i32> {
       return false;
     return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class MSRpstateImm0_1
@@ -2009,6 +2117,7 @@ def SysCRAsmOperand : AsmOperandClass {
 def sys_cr_op : Operand<i32> {
   let PrintMethod = "printSysCROperand";
   let ParserMatchClass = SysCRAsmOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class SystemXtI<bit L, string asm>
@@ -2053,6 +2162,7 @@ def rprfop : Operand<i32>, TImmLeaf<i32, [{
   }]> {
   let PrintMethod = "printRPRFMOperand";
   let ParserMatchClass = RangePrefetchOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // Branch (register) instructions:
@@ -2180,6 +2290,7 @@ multiclass AuthLoad<bit M, string asm, Operand opr> {
 def ccode : Operand<i32> {
   let PrintMethod = "printCondCode";
   let ParserMatchClass = CondCode;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def inv_ccode : Operand<i32> {
   // AL and NV are invalid in the aliases which use inv_ccode
@@ -2190,6 +2301,7 @@ def inv_ccode : Operand<i32> {
            MCOp.getImm() != AArch64CC::AL &&
            MCOp.getImm() != AArch64CC::NV;
   }];
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // Conditional branch target. 19-bit immediate. The low two bits of the target
@@ -2286,6 +2398,7 @@ class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
   return (((uint32_t)Imm) < 32);
 }]> {
   let ParserMatchClass = matcher;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
@@ -2295,6 +2408,7 @@ def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
 }]> {
   let ParserMatchClass = TBZImm32_63Operand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class BaseTestBranch<RegisterClass regtype, Operand immtype,
@@ -2809,14 +2923,17 @@ def movimm32_imm : Operand<i32> {
   let ParserMatchClass = AsmImmRange<0, 65535>;
   let EncoderMethod = "getMoveWideImmOpValue";
   let PrintMethod = "printImm";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def movimm32_shift : Operand<i32> {
   let PrintMethod = "printShifter";
   let ParserMatchClass = MovImm32ShifterOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def movimm64_shift : Operand<i32> {
   let PrintMethod = "printShifter";
   let ParserMatchClass = MovImm64ShifterOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
@@ -3633,9 +3750,11 @@ multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
 //---
 def maski8_or_more : Operand<i32>,
   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def maski16_or_more : Operand<i32>,
   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 
@@ -3693,6 +3812,7 @@ class uimm12_scaled<int Scale> : Operand<i64> {
   let EncoderMethod
    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
   let PrintMethod = "printUImm12Offset<" # Scale # ">";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 def uimm12s1 : uimm12_scaled<1>;
@@ -3769,6 +3889,7 @@ def PrefetchOperand : AsmOperandClass {
 def prfop : Operand<i32> {
   let PrintMethod = "printPrefetchOp";
   let ParserMatchClass = PrefetchOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
@@ -3904,6 +4025,8 @@ class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
   let DecoderMethod = "DecodeMemExtend";
   let EncoderMethod = "getMemExtendOpValue";
   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
+  let OperandType = "OPERAND_SHIFTED_IMMEDIATE";
+  let OperandNamespace = "AArch64";
 }
 
 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
@@ -11759,6 +11882,7 @@ def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 2
 }]>> {
   let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
   let PrintMethod = "printComplexRotationOp<90, 0>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270;  }],
                                                   SDNodeXForm<imm, [{
@@ -11766,6 +11890,7 @@ def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <
 }]>> {
   let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
   let PrintMethod = "printComplexRotationOp<180, 90>";
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in
 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
@@ -13159,6 +13284,7 @@ def LSLImm3ShiftOperand : AsmOperandClass {
 def lsl_imm3_shift_operand : Operand<i64> {
   let PrintMethod = "printShifter";
   let ParserMatchClass = LSLImm3ShiftOperand;
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 // Base CPA scalar add/subtract with lsl #imm3 shift

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
index 7774d07a214bf..f6d9855e78612 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
@@ -71,6 +71,8 @@ namespace AArch64 {
 enum OperandType {
   OPERAND_IMPLICIT_IMM_0 = MCOI::OPERAND_FIRST_TARGET,
   OPERAND_SHIFT_MSL,
+  OPERAND_SHIFTED_REGISTER,
+  OPERAND_SHIFTED_IMMEDIATE,
 };
 } // namespace AArch64
 

diff  --git a/llvm/test/tools/llvm-exegesis/AArch64/all-opcodes.test b/llvm/test/tools/llvm-exegesis/AArch64/all-opcodes.test
index 4644b48bef1ae..c2d4fb8ec6428 100644
--- a/llvm/test/tools/llvm-exegesis/AArch64/all-opcodes.test
+++ b/llvm/test/tools/llvm-exegesis/AArch64/all-opcodes.test
@@ -2,9 +2,19 @@
 # all supported opcodes and gracefully handle unsupported ones.
 
 # RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=cortex-a55 --benchmark-phase=prepare-and-assemble-snippet \
+# RUN:               -random-generator-seed=55 \
 # RUN:               --mode=latency --opcode-index=-1 | FileCheck %s
 # RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=cortex-a55 --benchmark-phase=prepare-and-assemble-snippet \
+# RUN:               -random-generator-seed=55 \
 # RUN:               --mode=uops --opcode-index=-1 | FileCheck %s
 
-# 100 means "quite a lot"
-# CHECK-COUNT-100: assembled_snippet: {{.*}}
+# RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=neoverse-v2 --benchmark-phase=prepare-and-assemble-snippet \
+# RUN:               -random-generator-seed=2 \
+# RUN:               --mode=latency --opcode-index=-1 | FileCheck --check-prefix CHECK-V2 %s
+# RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=neoverse-v2 --benchmark-phase=prepare-and-assemble-snippet \
+# RUN:               -random-generator-seed=2 \
+# RUN:               --mode=uops --opcode-index=-1 | FileCheck --check-prefix CHECK-V2 %s
+
+# One snippet per llvm opcode. Not all opcodes available on any given target.
+# CHECK-COUNT-2572: assembled_snippet: {{.*}}
+# CHECK-V2-COUNT-4601: assembled_snippet: {{.*}}

diff  --git a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
index 3ef664f899551..006394fead637 100644
--- a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
+++ b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s
@@ -73,3 +73,109 @@ FPCR-ASM:         movi    d{{[0-9]+}}, #0000000000000000
 FPCR-ASM-NEXT:    mov     x8, #0x0
 FPCR-ASM-NEXT:    msr     FPCR, x8
 FPCR-ASM-NEXT:    bfcvt   h{{[0-9]+}}, s{{[0-9]+}}
+
+## NZCV Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ADCSWr --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=NZCV-ASM < %t.s
+NZCV-ASM:         <foo>:
+NZCV-ASM:         mrs     x8, NZCV
+NZCV-ASM-NEXT:    mov     x9, #0xf0000000
+NZCV-ASM-NEXT:    bic     x8, x8, x9
+NZCV-ASM-NEXT:    msr     NZCV, x8
+NZCV-ASM-NEXT:    adcs    w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}
+
+## FFR Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=GLDFF1B_D --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=FFR-ASM < %t.s
+FFR-ASM:         <foo>:
+FFR-ASM:         setffr
+FFR-ASM-NEXT:    ldff1b    { z{{[0-9]+}}.d }, p{{[0-9]+}}/z, [x{{[0-9]+}}, z{{[0-9]+}}.d]
+
+# NOTE: Multi-register classes below can wrap around, e.g. { v31.1d, v0.1d }
+# FileCheck cant handle this constraint and '--random-generator-seed=<seed>'
+# can't be used either as the implementation relies on uniform_int_distribution
+# which produces inconsistent results across libc++ implementations.
+
+## WSeqPair Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=CASPW --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=WSEQPAIR-ASM < %t.s
+WSEQPAIR-ASM:         <foo>:
+WSEQPAIR-ASM:         mov     w{{[0-9]+}}, #0x0
+WSEQPAIR-ASM-NEXT:    mov     w{{[0-9]+}}, #0x0
+WSEQPAIR-ASM-NEXT:    mov     w{{[0-9]+}}, #0x0
+WSEQPAIR-ASM-NEXT:    mov     w{{[0-9]+}}, #0x0
+WSEQPAIR-ASM:         casp    w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, [x{{[0-9]+}}]
+
+## XSeqPair Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=CASPX --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=XSEQPAIR-ASM < %t.s
+XSEQPAIR-ASM:         <foo>:
+XSEQPAIR-ASM:         mov     x{{[0-9]+}}, #0x{{[0-9]+}}
+XSEQPAIR-ASM-NEXT:    mov     x{{[0-9]+}}, #0x{{[0-9]+}}
+XSEQPAIR-ASM-NEXT:    mov     x{{[0-9]+}}, #0x{{[0-9]+}}
+XSEQPAIR-ASM-NEXT:    mov     x{{[0-9]+}}, #0x{{[0-9]+}}
+XSEQPAIR-ASM:         casp    x{{[0-9]+}}, x{{[0-9]+}}, x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]
+
+## DD Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Twov1d_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=DD-ASM < %t.s
+DD-ASM:         <foo>:
+DD-ASM:         movi     d{{[0-9]+}}, #0000000000000000
+DD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DD-ASM:         st1      { v{{[0-9]+}}.1d, v{{[0-9]+}}.1d }, [x{{[0-9]+}}], x{{[0-9]+}}
+
+## DDD Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Threev1d_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=DDD-ASM < %t.s
+DDD-ASM:         <foo>:
+DDD-ASM:         movi     d{{[0-9]+}}, #0000000000000000
+DDD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DDD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DDD-ASM:         st1      { v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d }, [x{{[0-9]+}}], x{{[0-9]+}}
+
+## DDDD Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Fourv1d_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=DDDD-ASM < %t.s
+DDDD-ASM:         <foo>:
+DDDD-ASM:         movi     d{{[0-9]+}}, #0000000000000000
+DDDD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DDDD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DDDD-ASM-NEXT:    movi     d{{[0-9]+}}, #0000000000000000
+DDDD-ASM:         st1      { v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d }, [x{{[0-9]+}}], x{{[0-9]+}}
+
+## QQ Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Twov16b_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=QQ-ASM < %t.s
+QQ-ASM:         <foo>:
+QQ-ASM:         movi     v{{[0-9]+}}.2d, #0000000000000000
+QQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQ-ASM:         st1      { v{{[0-9]+}}.16b, v{{[0-9]+}}.16b }, [x{{[0-9]+}}], x{{[0-9]+}}
+
+## QQQ Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Threev16b_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=QQQ-ASM < %t.s
+QQQ-ASM:         <foo>:
+QQQ-ASM:         movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQ-ASM:         st1      { v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b }, [x{{[0-9]+}}], x{{[0-9]+}}
+
+## QQQQ Register Class Initialization Testcase
+RUN: llvm-exegesis -mtriple=aarch64 -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=ST1Fourv16b_POST --benchmark-phase=assemble-measured-code 2>&1
+RUN: llvm-objdump -d %d > %t.s
+RUN: FileCheck %s --check-prefix=QQQQ-ASM < %t.s
+QQQQ-ASM:         <foo>:
+QQQQ-ASM:         movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQQ-ASM-NEXT:    movi     v{{[0-9]+}}.2d, #0000000000000000
+QQQQ-ASM:         st1      { v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b }, [x{{[0-9]+}}], x{{[0-9]+}}

diff  --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index 0e73adab15d86..8e324d0d8fee9 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -70,6 +70,13 @@ static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
       .addImm(31); // All lanes true for 16 bits
 }
 
+static MCInst loadFFRImmediate(MCRegister Reg, unsigned RegBitWidth,
+                               const APInt &Value) {
+  assert(Value.getZExtValue() == 0 && "Expected initialisation value 0");
+  // For first-fault register FFR, we set it to a true
+  return MCInstBuilder(AArch64::SETFFR);
+}
+
 // Generates instructions to load an immediate value into an FPCR register.
 static std::vector<MCInst>
 loadFPCRImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
@@ -80,6 +87,42 @@ loadFPCRImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
   return {LoadImm, MoveToFPCR};
 }
 
+// Generates instructions to load an immediate value into a pair of W registers
+static std::vector<MCInst> loadWSeqPairImmediate(MCRegister Reg,
+                                                 unsigned RegBitWidth,
+                                                 const APInt &Value) {
+  MCRegister EvenReg = (Reg - AArch64::W0_W1) * 2 + AArch64::W0 + 0;
+  MCRegister OddReg = (Reg - AArch64::W0_W1) * 2 + AArch64::W0 + 1;
+  assert(Value.getBitWidth() <= RegBitWidth &&
+         "Value must fit in the Register");
+
+  MCInst LoadEven = MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
+                        .addReg(EvenReg)
+                        .addImm(Value.getZExtValue());
+  MCInst LoadOdd = MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
+                       .addReg(OddReg)
+                       .addImm(Value.getZExtValue());
+  return {LoadEven, LoadOdd};
+}
+
+// Generates instructions to load an immediate value into a pair of X registers
+static std::vector<MCInst> loadXSeqPairImmediate(MCRegister Reg,
+                                                 unsigned RegBitWidth,
+                                                 const APInt &Value) {
+  MCRegister EvenReg = (Reg - AArch64::X0_X1) * 2 + AArch64::X0 + 0;
+  MCRegister OddReg = (Reg - AArch64::X0_X1) * 2 + AArch64::X0 + 1;
+  assert(Value.getBitWidth() <= RegBitWidth &&
+         "Value must fit in the Register");
+
+  MCInst LoadEven = MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
+                        .addReg(EvenReg)
+                        .addImm(Value.getZExtValue());
+  MCInst LoadOdd = MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
+                       .addReg(OddReg)
+                       .addImm(Value.getZExtValue());
+  return {LoadEven, LoadOdd};
+}
+
 // Fetch base-instruction to load an FP immediate value into a register.
 static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
   switch (RegBitWidth) {
@@ -106,6 +149,59 @@ static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth,
   return Instructions;
 }
 
+// Generates instructions to load an immediate value into a DD, DDD, DDDD,
+// QQ, QQQ or QQQQ Reg
+static std::vector<MCInst>
+loadDQ234RegImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value,
+                      MCRegister BaseReg, unsigned RegCount) {
+  MCRegister RegDorQ0 = AArch64::D0;
+  if (RegBitWidth == 128)
+    RegDorQ0 = AArch64::Q0;
+
+  MCRegister RegDQ0 = RegDorQ0 + ((Reg - BaseReg + 0) % 32);
+  MCRegister RegDQ1 = RegDorQ0 + ((Reg - BaseReg + 1) % 32);
+  MCRegister RegDQ2 = RegDorQ0 + ((Reg - BaseReg + 2) % 32);
+  MCRegister RegDQ3 = RegDorQ0 + ((Reg - BaseReg + 3) % 32);
+
+  MCInst LoadDQ0 = loadFPImmediate(RegDQ0, RegBitWidth, Value);
+  MCInst LoadDQ1 = loadFPImmediate(RegDQ1, RegBitWidth, Value);
+  if (RegCount == 2)
+    return {LoadDQ0, LoadDQ1};
+  MCInst LoadDQ2 = loadFPImmediate(RegDQ2, RegBitWidth, Value);
+  if (RegCount == 3)
+    return {LoadDQ0, LoadDQ1, LoadDQ2};
+  MCInst LoadDQ3 = loadFPImmediate(RegDQ3, RegBitWidth, Value);
+  assert((RegCount == 4) && "ExpectedRegCount 2, 3 or 4");
+  return {LoadDQ0, LoadDQ1, LoadDQ2, LoadDQ3};
+}
+
+// Generates instructions to load immediate in the flags register
+static std::vector<MCInst>
+loadNZCVImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
+  MCRegister TempReg1 = AArch64::X8;
+  MCRegister TempReg2 = AArch64::X9;
+
+  MCInst MoveFromNZCV =
+      MCInstBuilder(AArch64::MRS).addReg(TempReg1).addImm(AArch64SysReg::NZCV);
+  MCInst LoadMask =
+      MCInstBuilder(AArch64::MOVi64imm).addReg(TempReg2).addImm(0xf0000000);
+  MCInst BitClear = MCInstBuilder(AArch64::BICXrr)
+                        .addReg(TempReg1)
+                        .addReg(TempReg1)
+                        .addReg(TempReg2);
+  MCInst MoveToNZCV =
+      MCInstBuilder(AArch64::MSR).addImm(AArch64SysReg::NZCV).addReg(TempReg1);
+
+  if (Value.getZExtValue() == 0)
+    return {MoveFromNZCV, LoadMask, BitClear, MoveToNZCV};
+
+  MCInst OrrMask = MCInstBuilder(AArch64::ORRXrr)
+                       .addReg(TempReg1)
+                       .addReg(TempReg1)
+                       .addImm(Value.getZExtValue());
+  return {MoveFromNZCV, LoadMask, BitClear, OrrMask, MoveToNZCV};
+}
+
 #include "AArch64GenExegesis.inc"
 
 namespace {
@@ -146,6 +242,30 @@ class ExegesisAArch64Target : public ExegesisTarget {
       return {loadZPRImmediate(Reg, 128, Value)};
     if (Reg == AArch64::FPCR)
       return {loadFPCRImmediate(Reg, 32, Value)};
+    if (Reg == AArch64::NZCV)
+      return {loadNZCVImmediate(Reg, 32, Value)};
+    if (Reg == AArch64::FFR)
+      return {loadFFRImmediate(Reg, 32, Value)};
+    if (AArch64::WSeqPairsClassRegClass.contains(Reg))
+      return {loadWSeqPairImmediate(Reg, 32, Value)};
+    if (AArch64::XSeqPairsClassRegClass.contains(Reg))
+      return {loadXSeqPairImmediate(Reg, 64, Value)};
+    if (AArch64::DDRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 64, Value, AArch64::D0_D1, 2);
+    if (AArch64::DDDRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 64, Value, AArch64::D0_D1_D2, 3);
+    if (AArch64::DDDDRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 64, Value, AArch64::D0_D1_D2_D3, 4);
+    if (AArch64::QQRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 128, Value, AArch64::Q0_Q1, 2);
+    if (AArch64::QQQRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 128, Value, AArch64::Q0_Q1_Q2, 3);
+    if (AArch64::QQQQRegClass.contains(Reg))
+      return loadDQ234RegImmediate(Reg, 128, Value, AArch64::Q0_Q1_Q2_Q3, 4);
+    // TODO if (AArch64::PNRRegClass.contains(Reg))
+    // TODO if (AArch64::ZPRRegClass.contains(Reg))
+    // TODO if (AArch64::ZPR2RegClass.contains(Reg))
+    // TODO if (AArch64::ZPR2StridedOrContiguousRegClass.contains(Reg))
 
     errs() << "setRegTo is not implemented, results will be unreliable\n";
     return {};
@@ -224,6 +344,13 @@ Error ExegesisAArch64Target::randomizeTargetMCOperand(
   case llvm::AArch64::OPERAND_IMPLICIT_IMM_0:
     AssignedValue = MCOperand::createImm(0);
     return Error::success();
+  case llvm::AArch64::OPERAND_SHIFTED_REGISTER:
+    // TODO it would be better if these operands were randomized
+    AssignedValue = MCOperand::createReg(0);
+    return Error::success();
+  case llvm::AArch64::OPERAND_SHIFTED_IMMEDIATE:
+    AssignedValue = MCOperand::createImm(0);
+    return Error::success();
   case MCOI::OperandType::OPERAND_PCREL:
     AssignedValue = MCOperand::createImm(8);
     return Error::success();


        


More information about the llvm-commits mailing list