Date: Thu, 8 Jun 2023 20:00:56 +0800
Subject:  8251216:Implement MD5 Intrinsics on aarch64

Bug url: https://bugs.openjdk.org/browse/JDK-8251216
---
 .../cpu/aarch64/vm/stubGenerator_aarch64.cpp  | 196 ++++++++++++++++++
 .../cpu/aarch64/vm/stubRoutines_aarch64.hpp   |   2 +-
 .../src/cpu/aarch64/vm/vm_version_aarch64.cpp |   4 +
 hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp     |   5 +
 hotspot/src/cpu/x86/vm/vm_version_x86.cpp     |   5 +
 hotspot/src/share/vm/classfile/vmSymbols.cpp  |   7 +-
 hotspot/src/share/vm/classfile/vmSymbols.hpp  |  11 +-
 hotspot/src/share/vm/opto/c2compiler.cpp      |   1 +
 hotspot/src/share/vm/opto/escape.cpp          |   2 +
 hotspot/src/share/vm/opto/library_call.cpp    | 165 ++++++++-------
 hotspot/src/share/vm/opto/runtime.cpp         |   2 +-
 hotspot/src/share/vm/opto/runtime.hpp         |   2 +-
 hotspot/src/share/vm/runtime/globals.hpp      |   3 +
 hotspot/src/share/vm/runtime/stubRoutines.cpp |   2 +
 hotspot/src/share/vm/runtime/stubRoutines.hpp |   4 +
 .../sha/{TestSHA.java => TestDigest.java}     | 110 ++++++----
 ...ptionsBase.java => DigestOptionsBase.java} | 105 ++++------
 ...tUseMD5IntrinsicsOptionOnSupportedCPU.java |  46 ++++
 ...seMD5IntrinsicsOptionOnUnsupportedCPU.java |  51 +++++
 ...UseSHA1IntrinsicsOptionOnSupportedCPU.java |   6 +-
 ...eSHA1IntrinsicsOptionOnUnsupportedCPU.java |  12 +-
 ...eSHA256IntrinsicsOptionOnSupportedCPU.java |   6 +-
 ...HA256IntrinsicsOptionOnUnsupportedCPU.java |  12 +-
 ...eSHA512IntrinsicsOptionOnSupportedCPU.java |   6 +-
 ...HA512IntrinsicsOptionOnUnsupportedCPU.java |  12 +-
 .../cli/TestUseSHAOptionOnSupportedCPU.java   |   8 +-
 .../cli/TestUseSHAOptionOnUnsupportedCPU.java |  12 +-
 .../testcases/GenericTestCaseForOtherCPU.java |   9 +-
 ...GenericTestCaseForSupportedAArch64CPU.java |  28 ++-
 .../GenericTestCaseForSupportedSparcCPU.java  |  28 ++-
 ...nericTestCaseForUnsupportedAArch64CPU.java |  14 +-
 ...GenericTestCaseForUnsupportedSparcCPU.java |  14 +-
 .../GenericTestCaseForUnsupportedX86CPU.java  |  15 +-
 ...pecificTestCaseForUnsupportedSparcCPU.java |   7 +-
 ...ASpecificTestCaseForSupportedSparcCPU.java |  48 +++--
 ...pecificTestCaseForUnsupportedSparcCPU.java |  31 +--
 ...estBase.java => DigestSanityTestBase.java} |  20 +-
 .../sha/sanity/TestMD5Intrinsics.java         |  66 ++++++
 .../sanity/TestMD5MultiBlockIntrinsics.java   |  74 +++++++
 .../sha/sanity/TestSHA1Intrinsics.java        |   6 +-
 .../sanity/TestSHA1MultiBlockIntrinsics.java  |  10 +-
 .../sha/sanity/TestSHA256Intrinsics.java      |   6 +-
 .../TestSHA256MultiBlockIntrinsics.java       |  14 +-
 .../sha/sanity/TestSHA512Intrinsics.java      |   6 +-
 .../TestSHA512MultiBlockIntrinsics.java       |  14 +-
 .../sha/predicate/IntrinsicPredicates.java    |  24 +++
 .../classes/sun/security/provider/MD5.java    |  19 ++
 .../classes/sun/security/provider/SHA.java    |   4 +-
 48 files changed, 927 insertions(+), 327 deletions(-)
 rename hotspot/test/compiler/intrinsics/sha/{TestSHA.java => TestDigest.java} (53%)
 rename hotspot/test/compiler/intrinsics/sha/cli/{SHAOptionsBase.java => DigestOptionsBase.java} (55%)
 create mode 100644 hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnSupportedCPU.java
 create mode 100644 hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java
 rename hotspot/test/compiler/intrinsics/sha/sanity/{SHASanityTestBase.java => DigestSanityTestBase.java} (83%)
 create mode 100644 hotspot/test/compiler/intrinsics/sha/sanity/TestMD5Intrinsics.java
 create mode 100644 hotspot/test/compiler/intrinsics/sha/sanity/TestMD5MultiBlockIntrinsics.java

diff --git a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
index c024dec55..a3f93204e 100644
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
@@ -3064,6 +3064,7 @@ class StubGenerator: public StubCodeGenerator {
     }
 
 
+
   // Arguments:
   //
   // Inputs:
@@ -3174,6 +3175,196 @@ class StubGenerator: public StubCodeGenerator {
     return start;
   }
 
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - byte[]  source+offset
+  //   c_rarg1   - int[]   SHA.state
+  //   c_rarg2   - int     offset
+  //   c_rarg3   - int     limit
+  //
+  address generate_md5_implCompress(bool multi_block, const char *name) {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    address start = __ pc();
+
+    Register buf       = c_rarg0;
+    Register state     = c_rarg1;
+    Register ofs       = c_rarg2;
+    Register limit     = c_rarg3;
+    Register a         = r4;
+    Register b         = r5;
+    Register c         = r6;
+    Register d         = r7;
+    Register rscratch3 = r10;
+    Register rscratch4 = r11;
+
+    Label keys;
+    Label md5_loop;
+
+    __ BIND(md5_loop);
+
+    // Save hash values for addition after rounds
+    __ ldrw(a, Address(state,  0));
+    __ ldrw(b, Address(state,  4));
+    __ ldrw(c, Address(state,  8));
+    __ ldrw(d, Address(state, 12));
+
+#define FF(r1, r2, r3, r4, k, s, t)              \
+    __ eorw(rscratch3, r3, r4);                  \
+    __ movw(rscratch2, t);                       \
+    __ andw(rscratch3, rscratch3, r2);           \
+    __ addw(rscratch4, r1, rscratch2);           \
+    __ ldrw(rscratch1, Address(buf, k*4));       \
+    __ eorw(rscratch3, rscratch3, r4);           \
+    __ addw(rscratch3, rscratch3, rscratch1);    \
+    __ addw(rscratch3, rscratch3, rscratch4);    \
+    __ rorw(rscratch2, rscratch3, 32 - s);       \
+    __ addw(r1, rscratch2, r2);
+
+#define GG(r1, r2, r3, r4, k, s, t)              \
+    __ eorw(rscratch2, r2, r3);                  \
+    __ ldrw(rscratch1, Address(buf, k*4));       \
+    __ andw(rscratch3, rscratch2, r4);           \
+    __ movw(rscratch2, t);                       \
+    __ eorw(rscratch3, rscratch3, r3);           \
+    __ addw(rscratch4, r1, rscratch2);           \
+    __ addw(rscratch3, rscratch3, rscratch1);    \
+    __ addw(rscratch3, rscratch3, rscratch4);    \
+    __ rorw(rscratch2, rscratch3, 32 - s);       \
+    __ addw(r1, rscratch2, r2);
+
+#define HH(r1, r2, r3, r4, k, s, t)              \
+    __ eorw(rscratch3, r3, r4);                  \
+    __ movw(rscratch2, t);                       \
+    __ addw(rscratch4, r1, rscratch2);           \
+    __ ldrw(rscratch1, Address(buf, k*4));       \
+    __ eorw(rscratch3, rscratch3, r2);           \
+    __ addw(rscratch3, rscratch3, rscratch1);    \
+    __ addw(rscratch3, rscratch3, rscratch4);    \
+    __ rorw(rscratch2, rscratch3, 32 - s);       \
+    __ addw(r1, rscratch2, r2);
+
+#define II(r1, r2, r3, r4, k, s, t)              \
+    __ movw(rscratch3, t);                       \
+    __ ornw(rscratch2, r2, r4);                  \
+    __ addw(rscratch4, r1, rscratch3);           \
+    __ ldrw(rscratch1, Address(buf, k*4));       \
+    __ eorw(rscratch3, rscratch2, r3);           \
+    __ addw(rscratch3, rscratch3, rscratch1);    \
+    __ addw(rscratch3, rscratch3, rscratch4);    \
+    __ rorw(rscratch2, rscratch3, 32 - s);       \
+    __ addw(r1, rscratch2, r2);
+
+    // Round 1
+    FF(a, b, c, d,  0,  7, 0xd76aa478)
+    FF(d, a, b, c,  1, 12, 0xe8c7b756)
+    FF(c, d, a, b,  2, 17, 0x242070db)
+    FF(b, c, d, a,  3, 22, 0xc1bdceee)
+    FF(a, b, c, d,  4,  7, 0xf57c0faf)
+    FF(d, a, b, c,  5, 12, 0x4787c62a)
+    FF(c, d, a, b,  6, 17, 0xa8304613)
+    FF(b, c, d, a,  7, 22, 0xfd469501)
+    FF(a, b, c, d,  8,  7, 0x698098d8)
+    FF(d, a, b, c,  9, 12, 0x8b44f7af)
+    FF(c, d, a, b, 10, 17, 0xffff5bb1)
+    FF(b, c, d, a, 11, 22, 0x895cd7be)
+    FF(a, b, c, d, 12,  7, 0x6b901122)
+    FF(d, a, b, c, 13, 12, 0xfd987193)
+    FF(c, d, a, b, 14, 17, 0xa679438e)
+    FF(b, c, d, a, 15, 22, 0x49b40821)
+
+    // Round 2
+    GG(a, b, c, d,  1,  5, 0xf61e2562)
+    GG(d, a, b, c,  6,  9, 0xc040b340)
+    GG(c, d, a, b, 11, 14, 0x265e5a51)
+    GG(b, c, d, a,  0, 20, 0xe9b6c7aa)
+    GG(a, b, c, d,  5,  5, 0xd62f105d)
+    GG(d, a, b, c, 10,  9, 0x02441453)
+    GG(c, d, a, b, 15, 14, 0xd8a1e681)
+    GG(b, c, d, a,  4, 20, 0xe7d3fbc8)
+    GG(a, b, c, d,  9,  5, 0x21e1cde6)
+    GG(d, a, b, c, 14,  9, 0xc33707d6)
+    GG(c, d, a, b,  3, 14, 0xf4d50d87)
+    GG(b, c, d, a,  8, 20, 0x455a14ed)
+    GG(a, b, c, d, 13,  5, 0xa9e3e905)
+    GG(d, a, b, c,  2,  9, 0xfcefa3f8)
+    GG(c, d, a, b,  7, 14, 0x676f02d9)
+    GG(b, c, d, a, 12, 20, 0x8d2a4c8a)
+
+    // Round 3
+    HH(a, b, c, d,  5,  4, 0xfffa3942)
+    HH(d, a, b, c,  8, 11, 0x8771f681)
+    HH(c, d, a, b, 11, 16, 0x6d9d6122)
+    HH(b, c, d, a, 14, 23, 0xfde5380c)
+    HH(a, b, c, d,  1,  4, 0xa4beea44)
+    HH(d, a, b, c,  4, 11, 0x4bdecfa9)
+    HH(c, d, a, b,  7, 16, 0xf6bb4b60)
+    HH(b, c, d, a, 10, 23, 0xbebfbc70)
+    HH(a, b, c, d, 13,  4, 0x289b7ec6)
+    HH(d, a, b, c,  0, 11, 0xeaa127fa)
+    HH(c, d, a, b,  3, 16, 0xd4ef3085)
+    HH(b, c, d, a,  6, 23, 0x04881d05)
+    HH(a, b, c, d,  9,  4, 0xd9d4d039)
+    HH(d, a, b, c, 12, 11, 0xe6db99e5)
+    HH(c, d, a, b, 15, 16, 0x1fa27cf8)
+    HH(b, c, d, a,  2, 23, 0xc4ac5665)
+
+    // Round 4
+    II(a, b, c, d,  0,  6, 0xf4292244)
+    II(d, a, b, c,  7, 10, 0x432aff97)
+    II(c, d, a, b, 14, 15, 0xab9423a7)
+    II(b, c, d, a,  5, 21, 0xfc93a039)
+    II(a, b, c, d, 12,  6, 0x655b59c3)
+    II(d, a, b, c,  3, 10, 0x8f0ccc92)
+    II(c, d, a, b, 10, 15, 0xffeff47d)
+    II(b, c, d, a,  1, 21, 0x85845dd1)
+    II(a, b, c, d,  8,  6, 0x6fa87e4f)
+    II(d, a, b, c, 15, 10, 0xfe2ce6e0)
+    II(c, d, a, b,  6, 15, 0xa3014314)
+    II(b, c, d, a, 13, 21, 0x4e0811a1)
+    II(a, b, c, d,  4,  6, 0xf7537e82)
+    II(d, a, b, c, 11, 10, 0xbd3af235)
+    II(c, d, a, b,  2, 15, 0x2ad7d2bb)
+    II(b, c, d, a,  9, 21, 0xeb86d391)
+
+#undef FF
+#undef GG
+#undef HH
+#undef II
+
+    // write hash values back in the correct order
+    __ ldrw(rscratch1, Address(state,  0));
+    __ addw(rscratch1, rscratch1, a);
+    __ strw(rscratch1, Address(state,  0));
+
+    __ ldrw(rscratch2, Address(state,  4));
+    __ addw(rscratch2, rscratch2, b);
+    __ strw(rscratch2, Address(state,  4));
+
+    __ ldrw(rscratch3, Address(state,  8));
+    __ addw(rscratch3, rscratch3, c);
+    __ strw(rscratch3, Address(state,  8));
+
+    __ ldrw(rscratch4, Address(state, 12));
+    __ addw(rscratch4, rscratch4, d);
+    __ strw(rscratch4, Address(state, 12));
+
+    if (multi_block) {
+      __ add(buf, buf, 64);
+      __ add(ofs, ofs, 64);
+      __ cmp(ofs, limit);
+      __ br(Assembler::LE, md5_loop);
+      __ mov(c_rarg0, ofs); // return ofs
+    }
+
+    __ ret(lr);
+
+    return start;
+  }
+
+
   // Arguments:
   //
   // Inputs:
@@ -5017,6 +5208,11 @@ class StubGenerator: public StubCodeGenerator {
       StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt();
     }
 
+    if (UseMD5Intrinsics) {
+      StubRoutines::_md5_implCompress      = generate_md5_implCompress(false,    "md5_implCompress");
+      StubRoutines::_md5_implCompressMB    = generate_md5_implCompress(true,     "md5_implCompressMB");
+    }
+
     if (UseSHA1Intrinsics) {
       StubRoutines::_sha1_implCompress     = generate_sha1_implCompress(false,   "sha1_implCompress");
       StubRoutines::_sha1_implCompressMB   = generate_sha1_implCompress(true,    "sha1_implCompressMB");
diff --git a/hotspot/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp
index 05619ce7f..212e1030d 100644
--- a/hotspot/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp
+++ b/hotspot/src/cpu/aarch64/vm/stubRoutines_aarch64.hpp
@@ -37,7 +37,7 @@ static bool    returns_to_call_stub(address return_pc)   {
 
 enum platform_dependent_constants {
   code_size1 = 19000,          // simply increase if too small (assembler will crash if too small)
-  code_size2 = 32000           // simply increase if too small (assembler will crash if too small)
+  code_size2 = 45000           // simply increase if too small (assembler will crash if too small)
 };
 
 class aarch64 {
diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
index de636fb83..ff28cf939 100644
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
@@ -264,6 +264,10 @@ void VM_Version::get_processor_features() {
     UseCRC32Intrinsics = true;
   }
 
+  if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
+    UseMD5Intrinsics = true;
+  }
+
   if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) {
     if (FLAG_IS_DEFAULT(UseSHA)) {
       FLAG_SET_DEFAULT(UseSHA, true);
diff --git a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp
index fea8b1f87..a5a80d292 100644
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp
@@ -204,6 +204,11 @@ void VM_Version::initialize() {
     FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
   }
 
+  if (UseMD5Intrinsics) {
+    warning("MD5 intrinsics are not available on this CPU");
+    FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
+  }
+
   if (has_vshasig()) {
     if (FLAG_IS_DEFAULT(UseSHA)) {
       UseSHA = true;
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
index ce3037d76..41f827364 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
@@ -669,6 +669,11 @@ void VM_Version::get_processor_features() {
     FLAG_SET_DEFAULT(UseF2jBLASIntrinsics, false);
   }
 
+  if (UseMD5Intrinsics) {
+    warning("MD5 intrinsics are not available on this CPU");
+    FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
+  }
+
   // Adjust RTM (Restricted Transactional Memory) flags
   if (!supports_rtm() && UseRTMLocking) {
     // Can't continue because UseRTMLocking affects UseBiasedLocking flag
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp
index 9633e4609..74926f6a0 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp
@@ -435,7 +435,7 @@ int vmIntrinsics::predicates_needed(vmIntrinsics::ID id) {
   case vmIntrinsics::_counterMode_AESCrypt:
     return 1;
   case vmIntrinsics::_digestBase_implCompressMB:
-    return 3;
+    return 4;
   default:
     return 0;
   }
@@ -578,6 +578,9 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
       return true;
     }
     break;
+  case vmIntrinsics::_md5_implCompress:
+    if (!UseMD5Intrinsics) return true;
+    break;
   case vmIntrinsics::_sha_implCompress:
     if (!UseSHA1Intrinsics) return true;
     break;
@@ -588,7 +591,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
     if (!UseSHA512Intrinsics) return true;
     break;
   case vmIntrinsics::_digestBase_implCompressMB:
-    if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
+    if (!(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
     break;
   case vmIntrinsics::_ghash_processBlocks:
     if (!UseGHASHIntrinsics) return true;
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 242660259..5f2a9a720 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -848,11 +848,15 @@
    do_intrinsic(_counterMode_AESCrypt, com_sun_crypto_provider_counterMode, crypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
    do_name(     crypt_name,                                 "implCrypt")                                                    \
                                                                                                                         \
+  /* support for sun.security.provider.MD5 */                                                                           \
+  do_class(sun_security_provider_md5,                              "sun/security/provider/MD5")                         \
+  do_intrinsic(_md5_implCompress, sun_security_provider_md5, implCompress_name, implCompress_signature, F_R)            \
+   do_name(     implCompress_name,                                 "implCompress0")                                     \
+   do_signature(implCompress_signature,                            "([BI)V")                                            \
+                                                                                                                        \
   /* support for sun.security.provider.SHA */                                                                           \
   do_class(sun_security_provider_sha,                              "sun/security/provider/SHA")                         \
   do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R)            \
-   do_name(     implCompress_name,                                 "implCompress0")                                     \
-   do_signature(implCompress_signature,                            "([BI)V")                                            \
                                                                                                                         \
   /* support for com.github.fommil.netlib.F2jBLAS */                                                                    \
   do_class(com_github_fommil_netlib_f2jblas,                       "com/github/fommil/netlib/F2jBLAS")                  \
@@ -1359,6 +1363,9 @@ public:
   // false otherwise. Implements functionality common to the C1
   // and the C2 compiler.
   static bool is_disabled_by_flags(vmIntrinsics::ID id);
+  static bool is_intrinsic_available(vmIntrinsics::ID id) {
+    return !is_disabled_by_flags(id);
+  }
 };
 
 #endif // SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp
index 64de417f6..d2485ddfc 100644
--- a/hotspot/src/share/vm/opto/c2compiler.cpp
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp
@@ -417,6 +417,7 @@ bool C2Compiler::is_intrinsic_supported(methodHandle method, bool is_virtual) {
   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
   case vmIntrinsics::_counterMode_AESCrypt:
+  case vmIntrinsics::_md5_implCompress:
   case vmIntrinsics::_sha_implCompress:
   case vmIntrinsics::_sha2_implCompress:
   case vmIntrinsics::_sha5_implCompress:
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index a0e497f08..bd9b6a27b 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -954,6 +954,8 @@ void ConnectionGraph::process_call_arguments(CallNode *call) {
                   strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "counterMode_AESCrypt") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "md5_implCompress") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "md5_implCompressMB") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 ||
                   strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 ||
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 9ba5201f0..e85b31b62 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -317,13 +317,13 @@ class LibraryCallKit : public GraphKit {
   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
   bool inline_ghash_processBlocks();
-  bool inline_sha_implCompress(vmIntrinsics::ID id);
+  bool inline_digestBase_implCompress(vmIntrinsics::ID id);
   bool inline_digestBase_implCompressMB(int predicate);
-  bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
-                                 bool long_state, address stubAddr, const char *stubName,
-                                 Node* src_start, Node* ofs, Node* limit);
-  Node* get_state_from_sha_object(Node *sha_object);
-  Node* get_state_from_sha5_object(Node *sha_object);
+  bool inline_digestBase_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass,
+                                        bool long_state, address stubAddr, const char *stubName,
+                                        Node* src_start, Node* ofs, Node* limit);
+  Node* get_state_from_digest_object(Node *digestBase_object);
+  Node* get_long_state_from_digest_object(Node *digestBase_object);
   Node* inline_digestBase_implCompressMB_predicate(int predicate);
   bool inline_encodeISOArray();
   bool inline_updateCRC32();
@@ -677,10 +677,11 @@ bool LibraryCallKit::try_to_inline(int predicate) {
   case vmIntrinsics::_counterMode_AESCrypt:
     return inline_counterMode_AESCrypt(intrinsic_id());
 
+  case vmIntrinsics::_md5_implCompress:
   case vmIntrinsics::_sha_implCompress:
   case vmIntrinsics::_sha2_implCompress:
   case vmIntrinsics::_sha5_implCompress:
-    return inline_sha_implCompress(intrinsic_id());
+    return inline_digestBase_implCompress(intrinsic_id());
 
   case vmIntrinsics::_digestBase_implCompressMB:
     return inline_digestBase_implCompressMB(predicate);
@@ -6758,7 +6759,10 @@ bool LibraryCallKit::inline_ghash_processBlocks() {
   return true;
 }
 
-//------------------------------inline_sha_implCompress-----------------------
+//------------------------------inline_digestBase_implCompress-----------------------
+//
+// Calculate MD5 for single-block byte[] array.
+// void com.sun.security.provider.MD5.implCompress(byte[] buf, int ofs)
 //
 // Calculate SHA (i.e., SHA-1) for single-block byte[] array.
 // void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs)
@@ -6769,12 +6773,12 @@ bool LibraryCallKit::inline_ghash_processBlocks() {
 // Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array.
 // void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs)
 //
-bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
+bool LibraryCallKit::inline_digestBase_implCompress(vmIntrinsics::ID id) {
   assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters");
 
-  Node* sha_obj = argument(0);
-  Node* src     = argument(1); // type oop
-  Node* ofs     = argument(2); // type int
+  Node* digestBase_obj = argument(0);
+  Node* src            = argument(1); // type oop
+  Node* ofs            = argument(2); // type int
 
   const Type* src_type = src->Value(&_gvn);
   const TypeAryPtr* top_src = src_type->isa_aryptr();
@@ -6794,21 +6798,27 @@ bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
   const char *stubName;
 
   switch(id) {
+  case vmIntrinsics::_md5_implCompress:
+    assert(UseMD5Intrinsics, "need MD5 instruction support");
+    state = get_state_from_digest_object(digestBase_obj);
+    stubAddr = StubRoutines::md5_implCompress();
+    stubName = "md5_implCompress";
+    break;
   case vmIntrinsics::_sha_implCompress:
     assert(UseSHA1Intrinsics, "need SHA1 instruction support");
-    state = get_state_from_sha_object(sha_obj);
+    state = get_state_from_digest_object(digestBase_obj);
     stubAddr = StubRoutines::sha1_implCompress();
     stubName = "sha1_implCompress";
     break;
   case vmIntrinsics::_sha2_implCompress:
     assert(UseSHA256Intrinsics, "need SHA256 instruction support");
-    state = get_state_from_sha_object(sha_obj);
+    state = get_state_from_digest_object(digestBase_obj);
     stubAddr = StubRoutines::sha256_implCompress();
     stubName = "sha256_implCompress";
     break;
   case vmIntrinsics::_sha5_implCompress:
     assert(UseSHA512Intrinsics, "need SHA512 instruction support");
-    state = get_state_from_sha5_object(sha_obj);
+    state = get_long_state_from_digest_object(digestBase_obj);
     stubAddr = StubRoutines::sha512_implCompress();
     stubName = "sha512_implCompress";
     break;
@@ -6819,7 +6829,7 @@ bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
   if (state == NULL) return false;
 
   // Call the stub.
-  Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::sha_implCompress_Type(),
+  Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(),
                                  stubAddr, stubName, TypePtr::BOTTOM,
                                  src_start, state);
 
@@ -6828,13 +6838,13 @@ bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
 
 //------------------------------inline_digestBase_implCompressMB-----------------------
 //
-// Calculate SHA/SHA2/SHA5 for multi-block byte[] array.
+// Calculate MD5/SHA/SHA2/SHA5 for multi-block byte[] array.
 // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
 //
 bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
-  assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
-         "need SHA1/SHA256/SHA512 instruction support");
-  assert((uint)predicate < 3, "sanity");
+  assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
+         "need MD5/SHA1/SHA256/SHA512 instruction support");
+  assert((uint)predicate < 4, "sanity");
   assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters");
 
   Node* digestBase_obj = argument(0); // The receiver was checked for NULL already.
@@ -6856,64 +6866,71 @@ bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
   // 'src_start' points to src array + offset
   Node* src_start = array_element_address(src, ofs, src_elem);
 
-  const char* klass_SHA_name = NULL;
+  const char* klass_digestBase_name = NULL;
   const char* stub_name = NULL;
   address     stub_addr = NULL;
   bool        long_state = false;
 
   switch (predicate) {
   case 0:
+    if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_md5_implCompress)) {
+      klass_digestBase_name = "sun/security/provider/MD5";
+      stub_name = "md5_implCompressMB";
+      stub_addr = StubRoutines::md5_implCompressMB();
+    }
+    break;
+  case 1:
     if (UseSHA1Intrinsics) {
-      klass_SHA_name = "sun/security/provider/SHA";
+      klass_digestBase_name = "sun/security/provider/SHA";
       stub_name = "sha1_implCompressMB";
       stub_addr = StubRoutines::sha1_implCompressMB();
     }
     break;
-  case 1:
+  case 2:
     if (UseSHA256Intrinsics) {
-      klass_SHA_name = "sun/security/provider/SHA2";
+      klass_digestBase_name = "sun/security/provider/SHA2";
       stub_name = "sha256_implCompressMB";
       stub_addr = StubRoutines::sha256_implCompressMB();
     }
     break;
-  case 2:
+  case 3:
     if (UseSHA512Intrinsics) {
-      klass_SHA_name = "sun/security/provider/SHA5";
+      klass_digestBase_name = "sun/security/provider/SHA5";
       stub_name = "sha512_implCompressMB";
       stub_addr = StubRoutines::sha512_implCompressMB();
       long_state = true;
     }
     break;
   default:
-    fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
+    fatal(err_msg_res("unknown DigestBase intrinsic predicate: %d", predicate));
   }
-  if (klass_SHA_name != NULL) {
+  if (klass_digestBase_name != NULL) {
     // get DigestBase klass to lookup for SHA klass
     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
     assert(tinst != NULL, "digestBase_obj is not instance???");
     assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
 
-    ciKlass* klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
-    assert(klass_SHA->is_loaded(), "predicate checks that this class is loaded");
-    ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
-    return inline_sha_implCompressMB(digestBase_obj, instklass_SHA, long_state, stub_addr, stub_name, src_start, ofs, limit);
+    ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name));
+    assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded");
+    ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass();
+    return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, long_state, stub_addr, stub_name, src_start, ofs, limit);
   }
   return false;
 }
-//------------------------------inline_sha_implCompressMB-----------------------
-bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA,
-                                               bool long_state, address stubAddr, const char *stubName,
-                                               Node* src_start, Node* ofs, Node* limit) {
-  const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA);
+//------------------------------inline_digestBase_implCompressMB-----------------------
+bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase,
+                                                      bool long_state, address stubAddr, const char *stubName,
+                                                      Node* src_start, Node* ofs, Node* limit) {
+  const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
   const TypeOopPtr* xtype = aklass->as_instance_type();
-  Node* sha_obj = new (C) CheckCastPPNode(control(), digestBase_obj, xtype);
-  sha_obj = _gvn.transform(sha_obj);
+  Node* digest_obj = new (C) CheckCastPPNode(control(), digestBase_obj, xtype);
+  digest_obj = _gvn.transform(digest_obj);
 
   Node* state;
   if (long_state) {
-    state = get_state_from_sha5_object(sha_obj);
+    state = get_long_state_from_digest_object(digest_obj);
   } else {
-    state = get_state_from_sha_object(sha_obj);
+    state = get_state_from_digest_object(digest_obj);
   }
   if (state == NULL) return false;
 
@@ -6937,37 +6954,37 @@ bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceK
   return true;
 }
 
-//------------------------------get_state_from_sha_object-----------------------
-Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
-  Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
-  assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
-  if (sha_state == NULL) return (Node *) NULL;
+//------------------------------get_state_from_digest_object-----------------------
+Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object) {
+  Node* digest_state = load_field_from_object(digest_object, "state", "[I", /*is_exact*/ false);
+  assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2");
+  if (digest_state == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the state array
-  Node* state = array_element_address(sha_state, intcon(0), T_INT);
+  Node* state = array_element_address(digest_state, intcon(0), T_INT);
   return state;
 }
 
-//------------------------------get_state_from_sha5_object-----------------------
-Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {
-  Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false);
-  assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5");
-  if (sha_state == NULL) return (Node *) NULL;
+//------------------------------get_long_state_from_digest_object-----------------------
+Node * LibraryCallKit::get_long_state_from_digest_object(Node *digest_object) {
+  Node* digest_state = load_field_from_object(digest_object, "state", "[J", /*is_exact*/ false);
+  assert (digest_state != NULL, "wrong version of sun.security.provider.SHA5");
+  if (digest_state == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the state array
-  Node* state = array_element_address(sha_state, intcon(0), T_LONG);
+  Node* state = array_element_address(digest_state, intcon(0), T_LONG);
   return state;
 }
 
 //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
 // Return node representing slow path of predicate check.
 // the pseudo code we want to emulate with this predicate is:
-//    if (digestBaseObj instanceof SHA/SHA2/SHA5) do_intrinsic, else do_javapath
+//    if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5) do_intrinsic, else do_javapath
 //
 Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
-  assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
-         "need SHA1/SHA256/SHA512 instruction support");
-  assert((uint)predicate < 3, "sanity");
+  assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
+         "need MD5/SHA1/SHA256/SHA512 instruction support");
+  assert((uint)predicate < 4, "sanity");
 
   // The receiver was checked for NULL already.
   Node* digestBaseObj = argument(0);
@@ -6977,44 +6994,50 @@ Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate)
   assert(tinst != NULL, "digestBaseObj is null");
   assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
 
-  const char* klass_SHA_name = NULL;
+  const char* klass_name = NULL;
   switch (predicate) {
   case 0:
+    if (UseMD5Intrinsics) {
+      // we want to do an instanceof comparison against the MD5 class
+      klass_name = "sun/security/provider/MD5";
+    }
+    break;
+  case 1:
     if (UseSHA1Intrinsics) {
       // we want to do an instanceof comparison against the SHA class
-      klass_SHA_name = "sun/security/provider/SHA";
+      klass_name = "sun/security/provider/SHA";
     }
     break;
-  case 1:
+  case 2:
     if (UseSHA256Intrinsics) {
       // we want to do an instanceof comparison against the SHA2 class
-      klass_SHA_name = "sun/security/provider/SHA2";
+      klass_name = "sun/security/provider/SHA2";
     }
     break;
-  case 2:
+  case 3:
     if (UseSHA512Intrinsics) {
       // we want to do an instanceof comparison against the SHA5 class
-      klass_SHA_name = "sun/security/provider/SHA5";
+      klass_name = "sun/security/provider/SHA5";
     }
     break;
   default:
     fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
   }
 
-  ciKlass* klass_SHA = NULL;
-  if (klass_SHA_name != NULL) {
-    klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
+  ciKlass* klass = NULL;
+  if (klass_name != NULL) {
+    klass = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_name));
   }
-  if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
-    // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
+  if ((klass == NULL) || !klass->is_loaded()) {
+    // if none of MD5/SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
     Node* ctrl = control();
     set_control(top()); // no intrinsic path
     return ctrl;
   }
-  ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
+  ciInstanceKlass* instklass = klass->as_instance_klass();
 
-  Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
-  Node* cmp_instof = _gvn.transform(new (C) CmpINode(instofSHA, intcon(1)));
+  Node* instof = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass)));
+  Node* cmp_instof = _gvn.transform(new (C) CmpINode(instof, intcon(1)));
   Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne));
   Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
 
diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp
index 1c51be19b..468846ee8 100644
--- a/hotspot/src/share/vm/opto/runtime.cpp
+++ b/hotspot/src/share/vm/opto/runtime.cpp
@@ -1053,7 +1053,7 @@ const TypeFunc* OptoRuntime::counterMode_aescrypt_Type() {
 /*
  * void implCompress(byte[] buf, int ofs)
  */
-const TypeFunc* OptoRuntime::sha_implCompress_Type() {
+const TypeFunc* OptoRuntime::digestBase_implCompress_Type() {
   // create input type (domain)
   int num_args = 2;
   int argcnt = num_args;
diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp
index f27e7d507..3f786d304 100644
--- a/hotspot/src/share/vm/opto/runtime.hpp
+++ b/hotspot/src/share/vm/opto/runtime.hpp
@@ -301,7 +301,7 @@ private:
   static const TypeFunc* cipherBlockChaining_aescrypt_Type();
   static const TypeFunc* counterMode_aescrypt_Type();
 
-  static const TypeFunc* sha_implCompress_Type();
+  static const TypeFunc* digestBase_implCompress_Type();
   static const TypeFunc* digestBase_implCompressMB_Type();
 
   static const TypeFunc* multiplyToLen_Type();
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index ac9165031..179fad2da 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -750,6 +750,9 @@ class CommandLineFlags {
   product(bool, UseAESIntrinsics, false,                                    \
           "Use intrinsics for AES versions of crypto")                      \
                                                                             \
+  diagnostic(bool, UseMD5Intrinsics, false,                                 \
+          "Use intrinsics for MD5 crypto hash function")                    \
+                                                                            \
   product(bool, UseAESCTRIntrinsics, false,                                 \
           "Use intrinsics for the paralleled version of AES/CTR crypto")    \
                                                                             \
diff --git a/hotspot/src/share/vm/runtime/stubRoutines.cpp b/hotspot/src/share/vm/runtime/stubRoutines.cpp
index d66237137..3cee9c224 100644
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp
@@ -127,6 +127,8 @@ address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
 address StubRoutines::_counterMode_AESCrypt                = NULL;
 address StubRoutines::_ghash_processBlocks                 = NULL;
 
+address StubRoutines::_md5_implCompress      = NULL;
+address StubRoutines::_md5_implCompressMB    = NULL;
 address StubRoutines::_sha1_implCompress     = NULL;
 address StubRoutines::_sha1_implCompressMB   = NULL;
 address StubRoutines::_sha256_implCompress   = NULL;
diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp
index 9fb589540..fff13dbcb 100644
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp
@@ -205,6 +205,8 @@ class StubRoutines: AllStatic {
   static address _counterMode_AESCrypt;
   static address _ghash_processBlocks;
 
+  static address _md5_implCompress;
+  static address _md5_implCompressMB;
   static address _sha1_implCompress;
   static address _sha1_implCompressMB;
   static address _sha256_implCompress;
@@ -374,6 +376,8 @@ class StubRoutines: AllStatic {
   static address counterMode_AESCrypt() { return _counterMode_AESCrypt; }
   static address ghash_processBlocks() { return _ghash_processBlocks; }
 
+  static address md5_implCompress()      { return _md5_implCompress; }
+  static address md5_implCompressMB()    { return _md5_implCompressMB; }
   static address sha1_implCompress()     { return _sha1_implCompress; }
   static address sha1_implCompressMB()   { return _sha1_implCompressMB; }
   static address sha256_implCompress()   { return _sha256_implCompress; }
diff --git a/hotspot/test/compiler/intrinsics/sha/TestSHA.java b/hotspot/test/compiler/intrinsics/sha/TestDigest.java
similarity index 53%
rename from hotspot/test/compiler/intrinsics/sha/TestSHA.java
rename to hotspot/test/compiler/intrinsics/sha/TestDigest.java
index 08af909ee..5477c72e2 100644
--- a/hotspot/test/compiler/intrinsics/sha/TestSHA.java
+++ b/hotspot/test/compiler/intrinsics/sha/TestDigest.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,38 +20,75 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
  * @test
  * @bug 8035968
- * @summary C2 support for SHA on SPARC
+ * @summary C2 support for MD5/SHA-1/SHA-224/SHA-256/SHA-384/SHA-512
  *
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1   TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 TestSHA
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=MD5
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-224
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-256
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-384
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-512
+ *      compiler.intrinsics.sha.TestDigest
  *
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1   -Doffset=1 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 -Doffset=1 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Doffset=1 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 -Doffset=1 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 -Doffset=1 TestSHA
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=MD5   -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-1   -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-224 -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-256 -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-384 -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-512 -Doffset=1
+ *      compiler.intrinsics.sha.TestDigest
  *
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1   -Dalgorithm2=SHA-256 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1   -Dalgorithm2=SHA-512 TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Dalgorithm2=SHA-512 TestSHA
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-1   -Dalgorithm2=SHA-256
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-1   -Dalgorithm2=SHA-512
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-256 -Dalgorithm2=SHA-512
+ *      compiler.intrinsics.sha.TestDigest
  *
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1   -Dalgorithm2=MD5     TestSHA
- * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=MD5     -Dalgorithm2=SHA-1   TestSHA
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=SHA-1   -Dalgorithm2=MD5
+ *      compiler.intrinsics.sha.TestDigest
+ * @run main/othervm/timeout=600 -Xbatch
+ *      -Dalgorithm=MD5     -Dalgorithm2=SHA-1
+ *      compiler.intrinsics.sha.TestDigest
  */
 
+package compiler.intrinsics.sha;
+
 import java.security.MessageDigest;
 import java.util.Arrays;
 
-public class TestSHA {
+public class TestDigest {
     private static final int HASH_LEN = 64; /* up to 512-bit */
     private static final int ALIGN = 8;     /* for different data alignments */
 
@@ -63,14 +101,14 @@ public class TestSHA {
         int iters = (args.length > 0 ? Integer.valueOf(args[0]) : 100000);
         int warmupIters = (args.length > 1 ? Integer.valueOf(args[1]) : 20000);
 
-        testSHA(provider, algorithm, msgSize, offset, iters, warmupIters);
+        testDigest(provider, algorithm, msgSize, offset, iters, warmupIters);
 
         if (algorithm2.equals("") == false) {
-            testSHA(provider, algorithm2, msgSize, offset, iters, warmupIters);
+            testDigest(provider, algorithm2, msgSize, offset, iters, warmupIters);
         }
     }
 
-    static void testSHA(String provider, String algorithm, int msgSize,
+    public static void testDigest(String provider, String algorithm, int msgSize,
                         int offset, int iters, int warmupIters) throws Exception {
         System.out.println("provider = " + provider);
         System.out.println("algorithm = " + algorithm);
@@ -86,27 +124,27 @@ public class TestSHA {
         }
 
         try {
-            MessageDigest sha = MessageDigest.getInstance(algorithm, provider);
+            MessageDigest digest = MessageDigest.getInstance(algorithm, provider);
 
             /* do once, which doesn't use intrinsics */
-            sha.reset();
-            sha.update(data, offset, msgSize);
-            expectedHash = sha.digest();
+            digest.reset();
+            digest.update(data, offset, msgSize);
+            expectedHash = digest.digest();
 
             /* warm up */
             for (int i = 0; i < warmupIters; i++) {
-                sha.reset();
-                sha.update(data, offset, msgSize);
-                hash = sha.digest();
+                digest.reset();
+                digest.update(data, offset, msgSize);
+                hash = digest.digest();
             }
 
             /* check result */
             if (Arrays.equals(hash, expectedHash) == false) {
-                System.out.println("TestSHA Error: ");
+                System.out.println("TestDigest Error: ");
                 showArray(expectedHash, "expectedHash");
                 showArray(hash,         "computedHash");
                 //System.exit(1);
-                throw new Exception("TestSHA Error");
+                throw new Exception("TestDigest Error");
             } else {
                 showArray(hash, "hash");
             }
@@ -114,15 +152,15 @@ public class TestSHA {
             /* measure performance */
             long start = System.nanoTime();
             for (int i = 0; i < iters; i++) {
-                sha.reset();
-                sha.update(data, offset, msgSize);
-                hash = sha.digest();
+                digest.reset();
+                digest.update(data, offset, msgSize);
+                hash = digest.digest();
             }
             long end = System.nanoTime();
             double total = (double)(end - start)/1e9;         /* in seconds */
             double thruput = (double)msgSize*iters/1e6/total; /* in MB/s */
-            System.out.println("TestSHA runtime = " + total + " seconds");
-            System.out.println("TestSHA throughput = " + thruput + " MB/s");
+            System.out.println("TestDigest runtime = " + total + " seconds");
+            System.out.println("TestDigest throughput = " + thruput + " MB/s");
             System.out.println();
         } catch (Exception e) {
             System.out.println("Exception: " + e);
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java b/hotspot/test/compiler/intrinsics/sha/cli/DigestOptionsBase.java
similarity index 55%
rename from hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java
rename to hotspot/test/compiler/intrinsics/sha/cli/DigestOptionsBase.java
index 80a1131ec..109687a1d 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/DigestOptionsBase.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,29 +34,34 @@ import java.util.function.BooleanSupplier;
  * Instead of using huge complex tests for each option, each test is constructed
  * from several test cases shared among different tests.
  */
-public class SHAOptionsBase extends CommandLineOptionTest {
-    protected static final String USE_SHA_OPTION = "UseSHA";
-    protected static final String USE_SHA1_INTRINSICS_OPTION
+public class DigestOptionsBase extends CommandLineOptionTest {
+    public static final String USE_MD5_INTRINSICS_OPTION
+            = "UseMD5Intrinsics";
+    public static final String USE_SHA_OPTION = "UseSHA";
+    public static final String USE_SHA1_INTRINSICS_OPTION
             = "UseSHA1Intrinsics";
-    protected static final String USE_SHA256_INTRINSICS_OPTION
+    public static final String USE_SHA256_INTRINSICS_OPTION
             = "UseSHA256Intrinsics";
-    protected static final String USE_SHA512_INTRINSICS_OPTION
+    public static final String USE_SHA512_INTRINSICS_OPTION
             = "UseSHA512Intrinsics";
 
+    // Intrinsics flags are of diagnostic type
+    // and must be preceded by UnlockDiagnosticVMOptions.
+    public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS
+            = "-XX:+UnlockDiagnosticVMOptions";
+
     // Note that strings below will be passed to
     // CommandLineOptionTest.verifySameJVMStartup and thus are regular
     // expressions, not just a plain strings.
+    protected static final String MD5_INTRINSICS_ARE_NOT_AVAILABLE
+            = "MD5 intrinsics are not available on this CPU";
     protected static final String SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE
             = "SHA instructions are not available on this CPU";
-    protected static final String SHA1_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA1 instruction is not available on this CPU\\.";
-    protected static final String SHA256_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA256 instruction \\(for SHA-224 and SHA-256\\) "
-            + "is not available on this CPU\\.";
-    protected static final String SHA512_INSTRUCTION_IS_NOT_AVAILABLE
-            = "SHA512 instruction \\(for SHA-384 and SHA-512\\) "
-            + "is not available on this CPU\\.";
-    protected static final String SHA_INTRINSICS_ARE_NOT_AVAILABLE
+    protected static final String SHA1_INTRINSICS_ARE_NOT_AVAILABLE
+            = "SHA intrinsics are not available on this CPU";
+    protected static final String SHA256_INTRINSICS_ARE_NOT_AVAILABLE
+            = "SHA intrinsics are not available on this CPU";
+    protected static final String SHA512_INTRINSICS_ARE_NOT_AVAILABLE
             = "SHA intrinsics are not available on this CPU";
 
     private final TestCase[] testCases;
@@ -70,47 +76,20 @@ public class SHAOptionsBase extends CommandLineOptionTest {
      * @return A warning message that will be printed out to VM output if CPU
      *         instructions required by the option are not supported.
      */
-    protected static String getWarningForUnsupportedCPU(String optionName) {
-        if (Platform.isSparc()) {
-            switch (optionName) {
-                case SHAOptionsBase.USE_SHA_OPTION:
-                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
-                default:
-                    throw new Error("Unexpected option " + optionName);
-            }
-        } else if (Platform.isX64() || Platform.isX86()) {
-            switch (optionName) {
-                case SHAOptionsBase.USE_SHA_OPTION:
-                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA_INTRINSICS_ARE_NOT_AVAILABLE;
-                default:
-                    throw new Error("Unexpected option " + optionName);
-            }
-        } else if (Platform.isAArch64()) {
-            switch (optionName) {
-                case SHAOptionsBase.USE_SHA_OPTION:
-                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
-                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
-                    return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
-                default:
-                    throw new Error("Unexpected option " + optionName);
-            }
-        } else {
-            throw new Error("Support for CPUs other then X86 or SPARC is not "
-                    + "implemented.");
+    public static String getWarningForUnsupportedCPU(String optionName) {
+        switch (optionName) {
+        case DigestOptionsBase.USE_MD5_INTRINSICS_OPTION:
+            return DigestOptionsBase.MD5_INTRINSICS_ARE_NOT_AVAILABLE;
+        case DigestOptionsBase.USE_SHA_OPTION:
+            return DigestOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
+        case DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+            return DigestOptionsBase.SHA1_INTRINSICS_ARE_NOT_AVAILABLE;
+        case DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+            return DigestOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE;
+        case DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+            return DigestOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE;
+        default:
+            throw new Error("Unexpected option " + optionName);
         }
     }
 
@@ -123,22 +102,24 @@ public class SHAOptionsBase extends CommandLineOptionTest {
      * @return The predicate on availability of CPU instructions required by the
      *         option.
      */
-    protected static BooleanSupplier getPredicateForOption(String optionName) {
+    public static BooleanSupplier getPredicateForOption(String optionName) {
         switch (optionName) {
-            case SHAOptionsBase.USE_SHA_OPTION:
+            case DigestOptionsBase.USE_MD5_INTRINSICS_OPTION:
+                return IntrinsicPredicates.MD5_INSTRUCTION_AVAILABLE;
+            case DigestOptionsBase.USE_SHA_OPTION:
                 return IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE;
-            case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+            case DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION:
                 return IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE;
-            case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+            case DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION:
                 return IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE;
-            case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+            case DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION:
                 return IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE;
             default:
                 throw new Error("Unexpected option " + optionName);
         }
     }
 
-    public SHAOptionsBase(TestCase... testCases) {
+    public DigestOptionsBase(TestCase... testCases) {
         super(Boolean.TRUE::booleanValue);
         this.testCases = testCases;
     }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnSupportedCPU.java
new file mode 100644
index 000000000..93b6cf6ec
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnSupportedCPU.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8035968
+ * @summary Verify UseMD5Intrinsics option processing on supported CPU.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @build TestUseMD5IntrinsicsOptionOnSupportedCPU
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestUseMD5IntrinsicsOptionOnSupportedCPU
+ */
+
+public class TestUseMD5IntrinsicsOptionOnSupportedCPU {
+    public static void main(String args[]) throws Throwable {
+        new DigestOptionsBase(new GenericTestCaseForSupportedSparcCPU(
+                DigestOptionsBase.USE_MD5_INTRINSICS_OPTION)).test();
+    }
+}
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java
new file mode 100644
index 000000000..6851b0b86
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseMD5IntrinsicsOptionOnUnsupportedCPU.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8035968
+ * @summary Verify UseMD5Intrinsics option processing on unsupported CPU.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @build TestUseMD5IntrinsicsOptionOnUnsupportedCPU
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestUseMD5IntrinsicsOptionOnUnsupportedCPU
+ */
+
+public class TestUseMD5IntrinsicsOptionOnUnsupportedCPU {
+    public static void main(String args[]) throws Throwable {
+        new DigestOptionsBase(
+                new GenericTestCaseForUnsupportedX86CPU(
+                        DigestOptionsBase.USE_MD5_INTRINSICS_OPTION),
+                new GenericTestCaseForUnsupportedAArch64CPU(
+                        DigestOptionsBase.USE_MD5_INTRINSICS_OPTION),
+                new GenericTestCaseForOtherCPU(
+                        DigestOptionsBase.USE_MD5_INTRINSICS_OPTION)).test();
+    }
+}
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java
index 9eb23d3b8..c79fbf285 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java
@@ -34,10 +34,10 @@
  */
 public class TestUseSHA1IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForSupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForSupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java
index 972f7b5c1..0673913cb 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java
@@ -35,16 +35,16 @@
  */
 public class TestUseSHA1IntrinsicsOptionOnUnsupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java
index ac11f1456..172e046c3 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java
@@ -35,10 +35,10 @@
  */
 public class TestUseSHA256IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForSupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForSupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java
index 94ce52ea9..0abe91d14 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java
@@ -35,16 +35,16 @@
  */
 public class TestUseSHA256IntrinsicsOptionOnUnsupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java
index 65c8236d4..ce1c31cbb 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java
@@ -35,10 +35,10 @@
  */
 public class TestUseSHA512IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForSupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForSupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java
index d3c94ee0f..fa0053a3e 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java
@@ -35,16 +35,16 @@
  */
 public class TestUseSHA512IntrinsicsOptionOnUnsupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java
index 5c8b28409..96c1f1379 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java
@@ -34,12 +34,12 @@
  */
 public class TestUseSHAOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForSupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new UseSHASpecificTestCaseForSupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForSupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA_OPTION)).test();
+                        DigestOptionsBase.USE_SHA_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java
index f5dfc4897..e1ddb54a3 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java
@@ -34,16 +34,16 @@
  */
 public class TestUseSHAOptionOnUnsupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(
+        new DigestOptionsBase(
                 new GenericTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new UseSHASpecificTestCaseForUnsupportedSparcCPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForUnsupportedAArch64CPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
-                        SHAOptionsBase.USE_SHA_OPTION),
+                        DigestOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForOtherCPU(
-                        SHAOptionsBase.USE_SHA_OPTION)).test();
+                        DigestOptionsBase.USE_SHA_OPTION)).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java
index fa9a6f208..72d067f2c 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java
@@ -32,7 +32,7 @@ import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
  * non-SPARC CPUs.
  */
 public class GenericTestCaseForOtherCPU extends
-        SHAOptionsBase.TestCase {
+        DigestOptionsBase.TestCase {
     public GenericTestCaseForOtherCPU(String optionName) {
         // Execute the test case on any CPU except SPARC and X86
         super(optionName, new NotPredicate(new OrPredicate(Platform::isSparc,
@@ -47,26 +47,31 @@ public class GenericTestCaseForOtherCPU extends
         // options will not cause any warnings.
         CommandLineOptionTest.verifySameJVMStartup(null,
                 new String[] { ".*" + optionName + ".*" }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         CommandLineOptionTest.verifySameJVMStartup(null,
                 new String[] { ".*" + optionName + ".*" }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that option is disabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that option is disabled even if it was explicitly enabled
         // using CLI options.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that option is disabled when it explicitly disabled
         // using CLI options.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java
index 1c77ff055..a7bd40f9e 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java
@@ -31,63 +31,71 @@ import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
  * support instructions required by the tested option.
  */
 public class GenericTestCaseForSupportedAArch64CPU extends
-        SHAOptionsBase.TestCase {
+        DigestOptionsBase.TestCase {
     public GenericTestCaseForSupportedAArch64CPU(String optionName) {
         super(optionName, new AndPredicate(Platform::isAArch64,
-                SHAOptionsBase.getPredicateForOption(optionName)));
+                DigestOptionsBase.getPredicateForOption(optionName)));
     }
 
     @Override
     protected void verifyWarnings() throws Throwable {
         // Verify that there are no warning when option is explicitly enabled.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that option could be disabled even if +UseSHA was passed to
         // JVM.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
         // Verify that it is possible to enable the tested option and disable
         // all SHA intrinsics via -UseSHA without any warnings.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false),
+                        DigestOptionsBase.USE_SHA_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that on supported CPU option is enabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that it is possible to explicitly enable the option.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that it is possible to explicitly disable the option.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
         // verify that option is disabled when -UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false));
+                        DigestOptionsBase.USE_SHA_OPTION, false));
 
         // Verify that it is possible to explicitly disable the tested option
         // even if +UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java
index c8ce2d52c..d443609de 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java
@@ -31,63 +31,71 @@ import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
  * support instructions required by the tested option.
  */
 public class GenericTestCaseForSupportedSparcCPU extends
-        SHAOptionsBase.TestCase {
+        DigestOptionsBase.TestCase {
     public GenericTestCaseForSupportedSparcCPU(String optionName) {
         super(optionName, new AndPredicate(Platform::isSparc,
-                SHAOptionsBase.getPredicateForOption(optionName)));
+                DigestOptionsBase.getPredicateForOption(optionName)));
     }
 
     @Override
     protected void verifyWarnings() throws Throwable {
         // Verify that there are no warning when option is explicitly enabled.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that option could be disabled even if +UseSHA was passed to
         // JVM.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
         // Verify that it is possible to enable the tested option and disable
         // all SHA intrinsics via -UseSHA without any warnings.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false),
+                        DigestOptionsBase.USE_SHA_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that on supported CPU option is enabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that it is possible to explicitly enable the option.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that it is possible to explicitly disable the option.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
 
         // verify that option is disabled when -UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false));
+                        DigestOptionsBase.USE_SHA_OPTION, false));
 
         // Verify that it is possible to explicitly disable the tested option
         // even if +UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java
index 204979918..c3d5a6aff 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java
@@ -32,10 +32,10 @@ import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
  * support instruction required by the tested option.
  */
 public class GenericTestCaseForUnsupportedAArch64CPU extends
-        SHAOptionsBase.TestCase {
+        DigestOptionsBase.TestCase {
     public GenericTestCaseForUnsupportedAArch64CPU(String optionName) {
         super(optionName, new AndPredicate(Platform::isAArch64,
-                new NotPredicate(SHAOptionsBase.getPredicateForOption(
+                new NotPredicate(DigestOptionsBase.getPredicateForOption(
                         optionName))));
     }
 
@@ -43,24 +43,28 @@ public class GenericTestCaseForUnsupportedAArch64CPU extends
     protected void verifyWarnings() throws Throwable {
         //Verify that option could be disabled without any warnings.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that option is disabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that option is disabled even if it was explicitly enabled
         // using CLI options.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that option is disabled when +UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true));
+                        DigestOptionsBase.USE_SHA_OPTION, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java
index 43bda2fb0..42c4ece60 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java
@@ -32,10 +32,10 @@ import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
  * support instruction required by the tested option.
  */
 public class GenericTestCaseForUnsupportedSparcCPU extends
-        SHAOptionsBase.TestCase {
+        DigestOptionsBase.TestCase {
     public GenericTestCaseForUnsupportedSparcCPU(String optionName) {
         super(optionName, new AndPredicate(Platform::isSparc,
-                new NotPredicate(SHAOptionsBase.getPredicateForOption(
+                new NotPredicate(DigestOptionsBase.getPredicateForOption(
                         optionName))));
     }
 
@@ -43,24 +43,28 @@ public class GenericTestCaseForUnsupportedSparcCPU extends
     protected void verifyWarnings() throws Throwable {
         //Verify that option could be disabled without any warnings.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that option is disabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that option is disabled even if it was explicitly enabled
         // using CLI options.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that option is disabled when +UseSHA was passed to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true));
+                        DigestOptionsBase.USE_SHA_OPTION, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
index d7033e524..8a8dde4ad 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
@@ -31,7 +31,7 @@ import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
  * support SHA-related instructions.
  */
 public class GenericTestCaseForUnsupportedX86CPU
-        extends SHAOptionsBase.TestCase {
+        extends DigestOptionsBase.TestCase {
     public GenericTestCaseForUnsupportedX86CPU(String optionName) {
         super(optionName, new OrPredicate(Platform::isX64, Platform::isX86));
     }
@@ -41,31 +41,36 @@ public class GenericTestCaseForUnsupportedX86CPU
         // Verify that when the tested option is explicitly enabled, then
         // a warning will occur in VM output.
         CommandLineOptionTest.verifySameJVMStartup(new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, null, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that the tested option could be explicitly disabled without
         // a warning.
         CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, false));
     }
 
     @Override
     protected void verifyOptionValues() throws Throwable {
         // Verify that the tested option is disabled by default.
-        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
 
         // Verify that it is not possible to explicitly enable the option.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
 
         // Verify that the tested option is disabled even if +UseSHA was passed
         // to JVM.
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true));
+                        DigestOptionsBase.USE_SHA_OPTION, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java
index 4e208eec9..cdb7d458f 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java
@@ -37,7 +37,7 @@ import sha.predicate.IntrinsicPredicates;
  * sha512.
  */
 public class UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU
-        extends SHAOptionsBase.TestCase {
+        extends DigestOptionsBase.TestCase {
     public UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
             String optionName) {
         // execute test case on SPARC CPU that support any sha* instructions,
@@ -45,15 +45,16 @@ public class UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU
         super(optionName, new AndPredicate(Platform::isSparc,
                 new AndPredicate(
                         IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE,
-                        new NotPredicate(SHAOptionsBase.getPredicateForOption(
+                        new NotPredicate(DigestOptionsBase.getPredicateForOption(
                                 optionName)))));
     }
     @Override
     protected void verifyWarnings() throws Throwable {
         // Verify that attempt to enable the tested option will cause a warning.
         CommandLineOptionTest.verifySameJVMStartup(new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, null, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java
index f54756839..7ad103c0a 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java
@@ -33,13 +33,13 @@ import sha.predicate.IntrinsicPredicates;
  * instruction.
  */
 public class UseSHASpecificTestCaseForSupportedSparcCPU
-        extends SHAOptionsBase.TestCase {
+        extends DigestOptionsBase.TestCase {
     public UseSHASpecificTestCaseForSupportedSparcCPU(String optionName) {
-        super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
+        super(DigestOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
                 IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE));
 
-        Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION,
-                "Test case should be used for " + SHAOptionsBase.USE_SHA_OPTION
+        Asserts.assertEQ(optionName, DigestOptionsBase.USE_SHA_OPTION,
+                "Test case should be used for " + DigestOptionsBase.USE_SHA_OPTION
                         + " option only.");
     }
 
@@ -49,14 +49,15 @@ public class UseSHASpecificTestCaseForSupportedSparcCPU
         // all UseSHA*Intrinsics options were disabled.
         CommandLineOptionTest.verifySameJVMStartup(
                 null, new String[] { ".*UseSHA.*" }, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
     }
 
     @Override
@@ -64,38 +65,41 @@ public class UseSHASpecificTestCaseForSupportedSparcCPU
         // Verify that UseSHA is disabled when all UseSHA*Intrinscs are
         // disabled.
         CommandLineOptionTest.verifyOptionValueForSameVM(
-                SHAOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
 
         CommandLineOptionTest.verifyOptionValueForSameVM(
                 // Verify that UseSHA is disabled when all UseSHA*Intrinscs are
                 // disabled even if it was explicitly enabled.
-                SHAOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
 
         // Verify that explicitly disabled UseSHA option remains disabled even
         // if all UseSHA*Intrinsics options were enabled.
         CommandLineOptionTest.verifyOptionValueForSameVM(
-                SHAOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, false),
+                        DigestOptionsBase.USE_SHA_OPTION, false),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java
index 5aceed607..899ece621 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java
@@ -34,14 +34,14 @@ import sha.predicate.IntrinsicPredicates;
  * instructions.
  */
 public class UseSHASpecificTestCaseForUnsupportedSparcCPU
-        extends SHAOptionsBase.TestCase {
+        extends DigestOptionsBase.TestCase {
     public UseSHASpecificTestCaseForUnsupportedSparcCPU(String optionName) {
-        super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
+        super(DigestOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
                 new NotPredicate(
                         IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE)));
 
-        Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION,
-                "Test case should be used for " + SHAOptionsBase.USE_SHA_OPTION
+        Asserts.assertEQ(optionName, DigestOptionsBase.USE_SHA_OPTION,
+                "Test case should be used for " + DigestOptionsBase.USE_SHA_OPTION
                         + " option only.");
     }
 
@@ -49,8 +49,9 @@ public class UseSHASpecificTestCaseForUnsupportedSparcCPU
     protected void verifyWarnings() throws Throwable {
         // Verify that attempt to use UseSHA option will cause a warning.
         CommandLineOptionTest.verifySameJVMStartup(new String[] {
-                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                        DigestOptionsBase.getWarningForUnsupportedCPU(optionName)
                 }, null, ExitCode.OK,
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(optionName, true));
     }
 
@@ -59,25 +60,27 @@ public class UseSHASpecificTestCaseForUnsupportedSparcCPU
         // Verify that UseSHA option remains disabled even if all
         // UseSHA*Intrincs options were enabled.
         CommandLineOptionTest.verifyOptionValueForSameVM(
-                SHAOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
 
         // Verify that UseSHA option remains disabled even if all
         // UseSHA*Intrincs options were enabled and UseSHA was enabled as well.
         CommandLineOptionTest.verifyOptionValueForSameVM(
-                SHAOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.USE_SHA_OPTION, "false",
+                DigestOptionsBase.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA_OPTION, true),
+                        DigestOptionsBase.USE_SHA_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
+                        DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
                 CommandLineOptionTest.prepareBooleanFlag(
-                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
+                        DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/SHASanityTestBase.java b/hotspot/test/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java
similarity index 83%
rename from hotspot/test/compiler/intrinsics/sha/sanity/SHASanityTestBase.java
rename to hotspot/test/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java
index 13b10a512..d9c363f20 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/SHASanityTestBase.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,6 +22,7 @@
  * questions.
  */
 
+import compiler.intrinsics.sha.TestDigest;
 import intrinsics.Verifier;
 import sun.hotspot.WhiteBox;
 
@@ -33,7 +35,9 @@ import java.util.function.BooleanSupplier;
 /**
  * Base class for sanity tests on SHA intrinsics support.
  */
-public class SHASanityTestBase {
+public class DigestSanityTestBase {
+    protected static final String MD5_INTRINSIC_ID
+            = "_md5_implCompress";
     protected static final String SHA1_INTRINSIC_ID
             = "_sha_implCompress";
     protected static final String SHA256_INTRINSIC_ID
@@ -62,7 +66,7 @@ public class SHASanityTestBase {
      *                  be used.
      * @param intrinsicID The ID of the intrinsic to be tested.
      */
-    protected SHASanityTestBase(BooleanSupplier predicate, String intrinsicID) {
+    protected DigestSanityTestBase(BooleanSupplier predicate, String intrinsicID) {
         this.predicate = predicate;
         this.intrinsicID = intrinsicID;
     }
@@ -79,10 +83,10 @@ public class SHASanityTestBase {
 
         dumpProperties();
 
-        TestSHA.testSHA(SHASanityTestBase.PROVIDER, algorithm,
-                SHASanityTestBase.MSG_SIZE, SHASanityTestBase.OFFSET,
-                SHASanityTestBase.ITERATIONS,
-                SHASanityTestBase.WARMUP_ITERATIONS);
+        TestDigest.testDigest(DigestSanityTestBase.PROVIDER, algorithm,
+                DigestSanityTestBase.MSG_SIZE, DigestSanityTestBase.OFFSET,
+                DigestSanityTestBase.ITERATIONS,
+                DigestSanityTestBase.WARMUP_ITERATIONS);
     }
 
     /**
@@ -99,7 +103,7 @@ public class SHASanityTestBase {
                 String.valueOf(predicate.getAsBoolean()));
 
         String logFileName
-                = SHASanityTestBase.WHITE_BOX.getStringVMFlag("LogFile");
+                = DigestSanityTestBase.WHITE_BOX.getStringVMFlag("LogFile");
         FileOutputStream fileOutputStream = new FileOutputStream(logFileName
                 + Verifier.PROPERTY_FILE_SUFFIX);
 
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5Intrinsics.java
new file mode 100644
index 000000000..b29a54f1a
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5Intrinsics.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8035968
+ * @summary Verify that MD5 intrinsic is actually used.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @build TestDigest TestMD5Intrinsics intrinsics.Verifier
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
+ *                   -XX:Tier4InvocationThreshold=500
+ *                   -XX:+LogCompilation -XX:LogFile=positive.log
+ *                   -XX:CompileOnly=sun/security/provider/DigestBase
+ *                   -XX:CompileOnly=sun/security/provider/MD5
+ *                   -XX:+UseMD5Intrinsics
+ *                   -Dalgorithm=MD5
+ *                   TestMD5Intrinsics
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
+ *                   -XX:Tier4InvocationThreshold=500
+ *                   -XX:+LogCompilation -XX:LogFile=negative.log
+ *                   -XX:CompileOnly=sun/security/provider/DigestBase
+ *                   -XX:CompileOnly=sun/security/provider/MD5
+ *                   -XX:-UseMD5Intrinsics
+ *                   -Dalgorithm=MD5
+ *                   TestMD5Intrinsics
+ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
+ *                   intrinsics.Verifier positive.log negative.log
+ */
+
+
+import sha.predicate.IntrinsicPredicates;
+
+public class TestMD5Intrinsics {
+    public static void main(String args[]) throws Exception {
+        new DigestSanityTestBase(IntrinsicPredicates.isMD5IntrinsicAvailable(),
+                DigestSanityTestBase.MD5_INTRINSIC_ID).test();
+    }
+}
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5MultiBlockIntrinsics.java
new file mode 100644
index 000000000..7807cfcfd
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestMD5MultiBlockIntrinsics.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8035968
+ * @summary Verify that MD5 multi block intrinsic is actually used.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @build TestDigest intrinsics.Verifier TestMD5MultiBlockIntrinsics
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
+ *                   -XX:Tier4InvocationThreshold=500
+ *                   -XX:+LogCompilation -XX:LogFile=positive.log
+ *                   -XX:CompileOnly=sun/security/provider/DigestBase
+ *                   -XX:CompileOnly=sun/security/provider/MD5
+ *                   -XX:+UseMD5Intrinsics -XX:-UseSHA1Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
+ *                   -Dalgorithm=MD5
+ *                   TestMD5MultiBlockIntrinsics
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
+ *                   -XX:Tier4InvocationThreshold=500
+ *                   -XX:+LogCompilation -XX:LogFile=positive_def.log
+ *                   -XX:CompileOnly=sun/security/provider/DigestBase
+ *                   -XX:CompileOnly=sun/security/provider/MD5
+ *                   -XX:+UseMD5Intrinsics -Dalgorithm=MD5
+ *                   TestMD5MultiBlockIntrinsics
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
+ *                   -XX:Tier4InvocationThreshold=500
+ *                   -XX:+LogCompilation -XX:LogFile=negative.log
+ *                   -XX:CompileOnly=sun/security/provider/DigestBase
+ *                   -XX:CompileOnly=sun/security/provider/MD5
+ *                   -Dalgorithm=MD5
+ *                   TestMD5MultiBlockIntrinsics
+ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
+ *                   intrinsics.Verifier positive.log positive_def.log
+ *                   negative.log
+ */
+
+import sha.predicate.IntrinsicPredicates;
+
+public class TestMD5MultiBlockIntrinsics {
+    public static void main(String args[]) throws Exception {
+        new DigestSanityTestBase(IntrinsicPredicates.isMD5IntrinsicAvailable(),
+                DigestSanityTestBase.MB_INTRINSIC_ID).test();
+    }
+}
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java
index 123fed300..43e783f96 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java
@@ -26,7 +26,7 @@
  * @bug 8035968
  * @summary Verify that SHA-1 intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA1Intrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA1Intrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -52,7 +52,7 @@ import sha.predicate.IntrinsicPredicates;
 
 public class TestSHA1Intrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.SHA1_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.SHA1_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java
index 68e573335..4c74b849d 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java
@@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates;
  * @bug 8035968
  * @summary Verify that SHA-1 multi block intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA1MultiBlockIntrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA1MultiBlockIntrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -37,8 +37,8 @@ import sha.predicate.IntrinsicPredicates;
  *                   -XX:+LogCompilation -XX:LogFile=positive.log
  *                   -XX:CompileOnly=sun/security/provider/DigestBase
  *                   -XX:CompileOnly=sun/security/provider/SHA
- *                   -XX:+UseSHA1Intrinsics -XX:-UseSHA256Intrinsics
- *                   -XX:-UseSHA512Intrinsics
+ *                   -XX:+UseSHA1Intrinsics -XX:-UseMD5Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
  *                   -Dalgorithm=SHA-1 TestSHA1MultiBlockIntrinsics
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
@@ -61,7 +61,7 @@ import sha.predicate.IntrinsicPredicates;
  */
 public class TestSHA1MultiBlockIntrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.MB_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.MB_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java
index 2730ed35a..d6c3efc92 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java
@@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates;
  * @bug 8035968
  * @summary Verify that SHA-256 intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA256Intrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA256Intrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -69,7 +69,7 @@ import sha.predicate.IntrinsicPredicates;
  */
 public class TestSHA256Intrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.SHA256_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.SHA256_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java
index dda126dc8..8659a3cac 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java
@@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates;
  * @bug 8035968
  * @summary Verify that SHA-256 multi block intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA256MultiBlockIntrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA256MultiBlockIntrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -37,8 +37,8 @@ import sha.predicate.IntrinsicPredicates;
  *                   -XX:+LogCompilation -XX:LogFile=positive_224.log
  *                   -XX:CompileOnly=sun/security/provider/DigestBase
  *                   -XX:CompileOnly=sun/security/provider/SHA
- *                   -XX:+UseSHA256Intrinsics -XX:-UseSHA1Intrinsics
- *                   -XX:-UseSHA512Intrinsics
+ *                   -XX:+UseSHA1Intrinsics -XX:-UseMD5Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
  *                   -Dalgorithm=SHA-224 TestSHA256MultiBlockIntrinsics
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
@@ -61,8 +61,8 @@ import sha.predicate.IntrinsicPredicates;
  *                   -XX:+LogCompilation -XX:LogFile=positive_256.log
  *                   -XX:CompileOnly=sun/security/provider/DigestBase
  *                   -XX:CompileOnly=sun/security/provider/SHA
- *                   -XX:+UseSHA256Intrinsics -XX:-UseSHA1Intrinsics
- *                   -XX:-UseSHA512Intrinsics
+ *                   -XX:+UseSHA1Intrinsics -XX:-UseMD5Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
  *                   -Dalgorithm=SHA-256 TestSHA256MultiBlockIntrinsics
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
@@ -86,7 +86,7 @@ import sha.predicate.IntrinsicPredicates;
  */
 public class TestSHA256MultiBlockIntrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.MB_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.MB_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java
index 02c8ad698..c7a5d89ea 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java
@@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates;
  * @bug 8035968
  * @summary Verify that SHA-512 intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA512Intrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA512Intrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -69,7 +69,7 @@ import sha.predicate.IntrinsicPredicates;
  */
 public class TestSHA512Intrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.SHA512_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.SHA512_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java
index d958d489d..ed503b042 100644
--- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java
+++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java
@@ -28,7 +28,7 @@ import sha.predicate.IntrinsicPredicates;
  * @bug 8035968
  * @summary Verify that SHA-512 multi block intrinsic is actually used.
  * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
- * @build TestSHA intrinsics.Verifier TestSHA512MultiBlockIntrinsics
+ * @build TestDigest intrinsics.Verifier TestSHA512MultiBlockIntrinsics
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
@@ -37,8 +37,8 @@ import sha.predicate.IntrinsicPredicates;
  *                   -XX:+LogCompilation -XX:LogFile=positive_384.log
  *                   -XX:CompileOnly=sun/security/provider/DigestBase
  *                   -XX:CompileOnly=sun/security/provider/SHA
- *                   -XX:+UseSHA512Intrinsics -XX:-UseSHA1Intrinsics
- *                   -XX:-UseSHA256Intrinsics
+ *                   -XX:+UseSHA1Intrinsics -XX:-UseMD5Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
  *                   -Dalgorithm=SHA-384 TestSHA512MultiBlockIntrinsics
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
@@ -61,8 +61,8 @@ import sha.predicate.IntrinsicPredicates;
  *                   -XX:+LogCompilation -XX:LogFile=positive_512.log
  *                   -XX:CompileOnly=sun/security/provider/DigestBase
  *                   -XX:CompileOnly=sun/security/provider/SHA
- *                   -XX:+UseSHA512Intrinsics -XX:-UseSHA1Intrinsics
- *                   -XX:-UseSHA256Intrinsics
+ *                   -XX:+UseSHA1Intrinsics -XX:-UseMD5Intrinsics
+ *                   -XX:-UseSHA256Intrinsics -XX:-UseSHA512Intrinsics
  *                   -Dalgorithm=SHA-512 TestSHA512MultiBlockIntrinsics
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
@@ -86,7 +86,7 @@ import sha.predicate.IntrinsicPredicates;
  */
 public class TestSHA512MultiBlockIntrinsics {
     public static void main(String args[]) throws Exception {
-        new SHASanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
-                SHASanityTestBase.MB_INTRINSIC_ID).test();
+        new DigestSanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
+                DigestSanityTestBase.MB_INTRINSIC_ID).test();
     }
 }
diff --git a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java
index dc8c39840..ec4b3e335 100644
--- a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java
+++ b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java
@@ -29,6 +29,7 @@ import com.oracle.java.testlibrary.cli.predicate.CPUSpecificPredicate;
 import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
 import sun.hotspot.WhiteBox;
 
+import java.lang.reflect.Method;
 import java.util.function.BooleanSupplier;
 
 /**
@@ -58,6 +59,13 @@ public class IntrinsicPredicates {
         return Platform.isServer() && (!isTiered || maxLevelIsReachable);
     };
 
+    public static final BooleanSupplier MD5_INSTRUCTION_AVAILABLE
+            = new OrPredicate(new CPUSpecificPredicate("aarch64.*", null, null),
+              // x86 variants
+              new OrPredicate(new CPUSpecificPredicate("amd64.*",   null, null),
+                              new CPUSpecificPredicate("x86.*",     null, null)));
+
+
     public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE
             = new OrPredicate(
                     new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },
@@ -92,6 +100,13 @@ public class IntrinsicPredicates {
                             IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE,
                             IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE));
 
+    public static BooleanSupplier isMD5IntrinsicAvailable() {
+        return new AndPredicate(new AndPredicate(
+                IntrinsicPredicates.MD5_INSTRUCTION_AVAILABLE,
+                IntrinsicPredicates.COMPILABLE_BY_C2),
+            IntrinsicPredicates.booleanOptionValue("UseMD5Intrinsics"));
+    }
+
     public static final BooleanSupplier SHA1_INTRINSICS_AVAILABLE
             = new AndPredicate(new AndPredicate(
                     IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,
@@ -116,4 +131,13 @@ public class IntrinsicPredicates {
 
     private IntrinsicPredicates() {
     }
+
+        private static BooleanSupplier isIntrinsicAvailable(String klass, String method) {
+        try {
+            Method m = Class.forName(klass).getDeclaredMethod(method, byte[].class, int.class);
+            return () -> WHITE_BOX.isIntrinsicAvailable(m, (int)IntrinsicPredicates.TIERED_MAX_LEVEL);
+        } catch (Exception e) {
+            throw new RuntimeException("Intrinsified method " +  klass + "::" + method + " not found!");
+        }
+    };
 }
diff --git a/jdk/src/share/classes/sun/security/provider/MD5.java b/jdk/src/share/classes/sun/security/provider/MD5.java
index c168ace71..a530e7a58 100644
--- a/jdk/src/share/classes/sun/security/provider/MD5.java
+++ b/jdk/src/share/classes/sun/security/provider/MD5.java
@@ -26,6 +26,7 @@
 package sun.security.provider;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 import static sun.security.provider.ByteArrayAccess.*;
 
@@ -147,8 +148,26 @@ public final class MD5 extends DigestBase {
      * bytes from the buffer, beginning at the specified offset.
      */
     void implCompress(byte[] buf, int ofs) {
+        implCompressCheck(buf, ofs);
+        implCompress0(buf, ofs);
+    }
+
+    private void implCompressCheck(byte[] buf, int ofs) {
+        Objects.requireNonNull(buf);
+
+        // The checks performed by the method 'b2iBig64'
+        // are sufficient for the case when the method
+        // 'implCompressImpl' is replaced with a compiler
+        // intrinsic.
         b2iLittle64(buf, ofs, x);
+    }
 
+    // The method 'implCompress0 seems not to use its parameters.
+    // The method can, however, be replaced with a compiler intrinsic
+    // that operates directly on the array 'buf' (starting from
+    // offset 'ofs') and not on array 'x', therefore 'buf' and 'ofs'
+    // must be passed as parameter to the method.
+    void implCompress0(byte[] buf, int ofs) {
         int a = state[0];
         int b = state[1];
         int c = state[2];
diff --git a/jdk/src/share/classes/sun/security/provider/SHA.java b/jdk/src/share/classes/sun/security/provider/SHA.java
index dfa477adf..b96f19e5b 100644
--- a/jdk/src/share/classes/sun/security/provider/SHA.java
+++ b/jdk/src/share/classes/sun/security/provider/SHA.java
@@ -134,12 +134,12 @@ public final class SHA extends DigestBase {
 
         // The checks performed by the method 'b2iBig64'
         // are sufficient for the case when the method
-        // 'implCompressImpl' is replaced with a compiler
+        // 'implCompress0' is replaced with a compiler
         // intrinsic.
         b2iBig64(buf, ofs, W);
     }
 
-    // The method 'implCompressImpl seems not to use its parameters.
+    // The method 'implCompress0 seems not to use its parameters.
     // The method can, however, be replaced with a compiler intrinsic
     // that operates directly on the array 'buf' (starting from
     // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
-- 
2.22.0

