Snap for 11494200 from e7e84e1b4a4328faf8c4f458109d07f52ab7ed8d to 24Q2-release

Change-Id: Ic495c6421f91e3ae8d645ee3fb661a00a9d62a12
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h
index c147217..c534513 100644
--- a/compiler/utils/assembler_test_base.h
+++ b/compiler/utils/assembler_test_base.h
@@ -147,7 +147,7 @@
                 "--compile",
                 "-target",
                 "riscv64-linux-gnu",
-                "-march=rv64imafdv_zba_zbb",
+                "-march=rv64imafdcv_zba_zbb_zca_zcd_zcb",
                 // Force the assembler to fully emit branch instructions instead of leaving
                 // offsets unresolved with relocation information for the linker.
                 "-mno-relax"};
@@ -175,7 +175,7 @@
                 "--no-print-imm-hex",
                 "--no-show-raw-insn",
                 // Disassemble Standard Extensions supported by the assembler.
-                "--mattr=+F,+D,+A,+V,+Zba,+Zbb",
+                "--mattr=+F,+D,+A,+C,+V,+Zba,+Zbb,+Zca,+Zcd,+Zcb",
                 "-M",
                 "no-aliases"};
       default:
diff --git a/compiler/utils/riscv64/assembler_riscv64_test.cc b/compiler/utils/riscv64/assembler_riscv64_test.cc
index 3f7d617..87c7641 100644
--- a/compiler/utils/riscv64/assembler_riscv64_test.cc
+++ b/compiler/utils/riscv64/assembler_riscv64_test.cc
@@ -52,51 +52,39 @@
 
   InstructionSet GetIsa() override { return InstructionSet::kRiscv64; }
 
-  // Clang's assembler takes advantage of certain extensions for emitting constants with `li`
-  // but our assembler does not. For now, we use a simple `-march` to avoid the divergence.
-  // TODO(riscv64): Implement these more efficient patterns in assembler.
-  void SetUseSimpleMarch(bool value) {
-    use_simple_march_ = value;
-  }
-
-  void SetCompressedMode(bool value) { compressed_mode_ = value; }
-
-  struct ScopedCompressedMode {
-    AssemblerRISCV64Test* test_;
-    bool old_cm_, old_sa_;
-
-    explicit ScopedCompressedMode(AssemblerRISCV64Test* test)
-        : test_(test), old_cm_(test->compressed_mode_), old_sa_(test->use_simple_march_) {
-      test->SetUseSimpleMarch(true);
-      test->SetCompressedMode(true);
+  class ScopedMarchOverride {
+   public:
+    ScopedMarchOverride(AssemblerRISCV64Test* test, const std::string& march)
+        : test_(test), old_override_(test->march_override_) {
+      test->march_override_ = march;
     }
 
-    ~ScopedCompressedMode() {
-      test_->SetCompressedMode(old_cm_);
-      test_->SetUseSimpleMarch(old_sa_);
+    ~ScopedMarchOverride() {
+      test_->march_override_ = old_override_;
     }
+
+   private:
+    AssemblerRISCV64Test* const test_;
+    std::optional<std::string> const old_override_;
+  };
+
+  class ScopedCSuppression {
+   public:
+    explicit ScopedCSuppression(AssemblerRISCV64Test* test)
+        : smo_(test, "-march=rv64imafdv_zba_zbb") {}
+
+   private:
+    ScopedMarchOverride smo_;
   };
 
   std::vector<std::string> GetAssemblerCommand() override {
     std::vector<std::string> result = Base::GetAssemblerCommand();
-    if (use_simple_march_) {
+    if (march_override_.has_value()) {
       auto it = std::find_if(result.begin(),
                              result.end(),
                              [](const std::string& s) { return StartsWith(s, "-march="); });
       CHECK(it != result.end());
-      *it = compressed_mode_ ? "-march=rv64imafdcv_zca_zcb_zba_zbb" : "-march=rv64imafdv";
-    }
-    return result;
-  }
-
-  std::vector<std::string> GetDisassemblerCommand() override {
-    std::vector<std::string> result = Base::GetDisassemblerCommand();
-    if (use_simple_march_) {
-      auto it = std::find_if(result.begin(),
-                             result.end(),
-                             [](const std::string& s) { return StartsWith(s, "--mattr="); });
-      CHECK(it != result.end());
-      *it = compressed_mode_ ? "--mattr=+F,+D,+A,+V,+C" : "--mattr=+F,+D,+A,+V";
+      *it = march_override_.value();
     }
     return result;
   }
@@ -2199,13 +2187,13 @@
   std::map<XRegister, std::string, RISCV64CpuRegisterCompare> secondary_register_names_;
 
   std::unique_ptr<const Riscv64InstructionSetFeatures> instruction_set_features_;
-  bool use_simple_march_ = false;
-  bool compressed_mode_ = false;
+  std::optional<std::string> march_override_;
 };
 
 TEST_F(AssemblerRISCV64Test, Toolchain) { EXPECT_TRUE(CheckTools()); }
 
 TEST_F(AssemblerRISCV64Test, Lui) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRIb(&Riscv64Assembler::Lui, 20, "lui {reg}, {imm}"), "Lui");
 }
 
@@ -2214,21 +2202,25 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Jal) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-19, 2" to "-20, 1" for "C" Standard Extension.
   DriverStr(RepeatRIbS(&Riscv64Assembler::Jal, -19, 2, "jal {reg}, {imm}\n"), "Jal");
 }
 
 TEST_F(AssemblerRISCV64Test, Jalr) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension.
   DriverStr(RepeatRRIb(&Riscv64Assembler::Jalr, -12, "jalr {reg1}, {reg2}, {imm}\n"), "Jalr");
 }
 
 TEST_F(AssemblerRISCV64Test, Beq) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension.
   DriverStr(RepeatRRIbS(&Riscv64Assembler::Beq, -11, 2, "beq {reg1}, {reg2}, {imm}\n"), "Beq");
 }
 
 TEST_F(AssemblerRISCV64Test, Bne) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension.
   DriverStr(RepeatRRIbS(&Riscv64Assembler::Bne, -11, 2, "bne {reg1}, {reg2}, {imm}\n"), "Bne");
 }
@@ -2254,50 +2246,62 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Lb) {
+  // Note: There is no 16-bit instruction for `Lb()`.
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lb, -12, "lb {reg1}, {imm}({reg2})"), "Lb");
 }
 
 TEST_F(AssemblerRISCV64Test, Lh) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lh, -12, "lh {reg1}, {imm}({reg2})"), "Lh");
 }
 
 TEST_F(AssemblerRISCV64Test, Lw) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lw, -12, "lw {reg1}, {imm}({reg2})"), "Lw");
 }
 
 TEST_F(AssemblerRISCV64Test, Ld) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Ld, -12, "ld {reg1}, {imm}({reg2})"), "Ld");
 }
 
 TEST_F(AssemblerRISCV64Test, Lbu) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lbu, -12, "lbu {reg1}, {imm}({reg2})"), "Lbu");
 }
 
 TEST_F(AssemblerRISCV64Test, Lhu) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lhu, -12, "lhu {reg1}, {imm}({reg2})"), "Lhu");
 }
 
 TEST_F(AssemblerRISCV64Test, Lwu) {
+  // Note: There is no 16-bit instruction for `Lwu()`.
   DriverStr(RepeatRRIb(&Riscv64Assembler::Lwu, -12, "lwu {reg1}, {imm}({reg2})"), "Lwu");
 }
 
 TEST_F(AssemblerRISCV64Test, Sb) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Sb, -12, "sb {reg1}, {imm}({reg2})"), "Sb");
 }
 
 TEST_F(AssemblerRISCV64Test, Sh) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Sh, -12, "sh {reg1}, {imm}({reg2})"), "Sh");
 }
 
 TEST_F(AssemblerRISCV64Test, Sw) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Sw, -12, "sw {reg1}, {imm}({reg2})"), "Sw");
 }
 
 TEST_F(AssemblerRISCV64Test, Sd) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Sd, -12, "sd {reg1}, {imm}({reg2})"), "Sd");
 }
 
 TEST_F(AssemblerRISCV64Test, Addi) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Addi, -12, "addi {reg1}, {reg2}, {imm}"), "Addi");
 }
 
@@ -2318,26 +2322,32 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Andi) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Andi, -12, "andi {reg1}, {reg2}, {imm}"), "Andi");
 }
 
 TEST_F(AssemblerRISCV64Test, Slli) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Slli, 6, "slli {reg1}, {reg2}, {imm}"), "Slli");
 }
 
 TEST_F(AssemblerRISCV64Test, Srli) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Srli, 6, "srli {reg1}, {reg2}, {imm}"), "Srli");
 }
 
 TEST_F(AssemblerRISCV64Test, Srai) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Srai, 6, "srai {reg1}, {reg2}, {imm}"), "Srai");
 }
 
 TEST_F(AssemblerRISCV64Test, Add) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Add, "add {reg1}, {reg2}, {reg3}"), "Add");
 }
 
 TEST_F(AssemblerRISCV64Test, Sub) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Sub, "sub {reg1}, {reg2}, {reg3}"), "Sub");
 }
 
@@ -2350,14 +2360,17 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Xor) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Xor, "xor {reg1}, {reg2}, {reg3}"), "Xor");
 }
 
 TEST_F(AssemblerRISCV64Test, Or) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Or, "or {reg1}, {reg2}, {reg3}"), "Or");
 }
 
 TEST_F(AssemblerRISCV64Test, And) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::And, "and {reg1}, {reg2}, {reg3}"), "And");
 }
 
@@ -2374,6 +2387,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Addiw) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRIb(&Riscv64Assembler::Addiw, -12, "addiw {reg1}, {reg2}, {imm}"), "Addiw");
 }
 
@@ -2393,10 +2407,12 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Addw) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Addw, "addw {reg1}, {reg2}, {reg3}"), "Addw");
 }
 
 TEST_F(AssemblerRISCV64Test, Subw) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Subw, "subw {reg1}, {reg2}, {reg3}"), "Subw");
 }
 
@@ -2418,6 +2434,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Ebreak) {
+  ScopedCSuppression scs(this);
   __ Ebreak();
   DriverStr("ebreak\n", "Ebreak");
 }
@@ -2468,6 +2485,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Mul) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRRR(&Riscv64Assembler::Mul, "mul {reg1}, {reg2}, {reg3}"), "Mul");
 }
 
@@ -2660,18 +2678,22 @@
 }
 
 TEST_F(AssemblerRISCV64Test, FLw) {
+  // Note: 16-bit variants of `flw` are not available on riscv64.
   DriverStr(RepeatFRIb(&Riscv64Assembler::FLw, -12, "flw {reg1}, {imm}({reg2})"), "FLw");
 }
 
 TEST_F(AssemblerRISCV64Test, FLd) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatFRIb(&Riscv64Assembler::FLd, -12, "fld {reg1}, {imm}({reg2})"), "FLw");
 }
 
 TEST_F(AssemblerRISCV64Test, FSw) {
+  // Note: 16-bit variants of `fsw` are not available on riscv64.
   DriverStr(RepeatFRIb(&Riscv64Assembler::FSw, 2, "fsw {reg1}, {imm}({reg2})"), "FSw");
 }
 
 TEST_F(AssemblerRISCV64Test, FSd) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatFRIb(&Riscv64Assembler::FSd, 2, "fsd {reg1}, {imm}({reg2})"), "FSd");
 }
 
@@ -3102,7 +3124,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLwsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CLwsp,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3114,7 +3135,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLdsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CLdsp,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3126,14 +3146,12 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CFLdsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCFImm(
                 &Riscv64Assembler::CFLdsp, /*imm_bits=*/6, /*shift=*/3, "c.fldsp {reg}, {imm}(sp)"),
             "CFLdsp");
 }
 
 TEST_F(AssemblerRISCV64Test, CSwsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CSwsp,
                         /*is_short=*/false,
                         /*no_zero_reg=*/false,
@@ -3145,7 +3163,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSdsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CSdsp,
                         /*is_short=*/false,
                         /*no_zero_reg=*/false,
@@ -3157,28 +3174,24 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CFSdsp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCFImm(
                 &Riscv64Assembler::CFSdsp, /*imm_bits=*/6, /*shift=*/3, "c.fsdsp {reg}, {imm}(sp)"),
             "CFLdsp");
 }
 
 TEST_F(AssemblerRISCV64Test, CLw) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(
                 &Riscv64Assembler::CLw, /*imm_bits=*/5, /*shift=*/2, "c.lw {reg1}, {imm}({reg2})"),
             "CLw");
 }
 
 TEST_F(AssemblerRISCV64Test, CLd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(
                 &Riscv64Assembler::CLd, /*imm_bits=*/5, /*shift=*/3, "c.ld {reg1}, {imm}({reg2})"),
             "CLd");
 }
 
 TEST_F(AssemblerRISCV64Test, CFLd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCFRImm(&Riscv64Assembler::CFLd,
                          /*imm_bits=*/5,
                          /*shift=*/3,
@@ -3187,21 +3200,18 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSw) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(
                 &Riscv64Assembler::CSw, /*imm_bits=*/5, /*shift=*/2, "c.sw {reg1}, {imm}({reg2})"),
             "CSw");
 }
 
 TEST_F(AssemblerRISCV64Test, CSd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(
                 &Riscv64Assembler::CSd, /*imm_bits=*/5, /*shift=*/3, "c.sd {reg1}, {imm}({reg2})"),
             "CSd");
 }
 
 TEST_F(AssemblerRISCV64Test, CFSd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCFRImm(&Riscv64Assembler::CFSd,
                          /*imm_bits=*/5,
                          /*shift=*/3,
@@ -3210,7 +3220,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLi) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CLi,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3222,7 +3231,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLui) {
-  ScopedCompressedMode cm(this);
   std::string str;
   auto imms = CreateImmediateValuesBits(/*imm_bits=*/5, /*as_uint=*/true);
   for (uint32_t v = 0xfffe0; v <= 0xfffff; ++v) {
@@ -3254,7 +3262,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CAddi) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CAddi,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3266,7 +3273,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CAddiw) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CAddiw,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3278,7 +3284,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CAddi16Sp) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatImm(&Riscv64Assembler::CAddi16Sp,
                       /*no_zero_imm=*/true,
                       /*imm_bits=*/-6,
@@ -3288,7 +3293,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CAddi4Spn) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CAddi4Spn,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3300,7 +3304,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSlli) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CSlli,
                         /*is_short=*/false,
                         /*no_zero_reg=*/true,
@@ -3312,7 +3315,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSRli) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CSrli,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3324,7 +3326,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSRai) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CSrai,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3336,7 +3337,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CAndi) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CAndi,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3348,47 +3348,38 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CMv) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRNonZero(&Riscv64Assembler::CMv, "c.mv {reg1}, {reg2}"), "CMv");
 }
 
 TEST_F(AssemblerRISCV64Test, CAdd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRNonZero(&Riscv64Assembler::CAdd, "c.add {reg1}, {reg2}"), "CAdd");
 }
 
 TEST_F(AssemblerRISCV64Test, CAnd) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CAnd, "c.and {reg1}, {reg2}"), "CAnd");
 }
 
 TEST_F(AssemblerRISCV64Test, COr) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::COr, "c.or {reg1}, {reg2}"), "COr");
 }
 
 TEST_F(AssemblerRISCV64Test, CXor) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CXor, "c.xor {reg1}, {reg2}"), "CXor");
 }
 
 TEST_F(AssemblerRISCV64Test, CSub) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CSub, "c.sub {reg1}, {reg2}"), "CSub");
 }
 
 TEST_F(AssemblerRISCV64Test, CAddw) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CAddw, "c.addw {reg1}, {reg2}"), "CAddw");
 }
 
 TEST_F(AssemblerRISCV64Test, CSubw) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CSubw, "c.subw {reg1}, {reg2}"), "CSubw");
 }
 
 TEST_F(AssemblerRISCV64Test, CLbu) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(&Riscv64Assembler::CLbu,
                          /*imm_bits=*/2,
                          /*shift=*/0,
@@ -3397,7 +3388,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLhu) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(&Riscv64Assembler::CLhu,
                          /*imm_bits=*/1,
                          /*shift=*/1,
@@ -3406,7 +3396,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CLh) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(&Riscv64Assembler::CLh,
                          /*imm_bits=*/1,
                          /*shift=*/1,
@@ -3415,7 +3404,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSb) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(&Riscv64Assembler::CSb,
                          /*imm_bits=*/2,
                          /*shift=*/0,
@@ -3424,7 +3412,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CSh) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRImm(&Riscv64Assembler::CSh,
                          /*imm_bits=*/1,
                          /*shift=*/1,
@@ -3433,42 +3420,34 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CZext_b) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CZext_b, "c.zext.b {reg}"), "CZext_b");
 }
 
 TEST_F(AssemblerRISCV64Test, CSext_b) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CSext_b, "c.sext.b {reg}"), "CSext_b");
 }
 
 TEST_F(AssemblerRISCV64Test, CZext_h) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CZext_h, "c.zext.h {reg}"), "CZext_h");
 }
 
 TEST_F(AssemblerRISCV64Test, CSext_h) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CSext_h, "c.sext.h {reg}"), "CSext_h");
 }
 
 TEST_F(AssemblerRISCV64Test, CZext_w) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CZext_w, "c.zext.w {reg}"), "CZext_w");
 }
 
 TEST_F(AssemblerRISCV64Test, CNot) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRShort(&Riscv64Assembler::CNot, "c.not {reg}"), "CNot");
 }
 
 TEST_F(AssemblerRISCV64Test, CMul) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRRShort(&Riscv64Assembler::CMul, "c.mul {reg1}, {reg2}"), "CMul");
 }
 
 TEST_F(AssemblerRISCV64Test, CJ) {
-  ScopedCompressedMode cm(this);
   DriverStr(
       RepeatImm(
           &Riscv64Assembler::CJ, /*no_zero_imm=*/false, /*imm_bits=*/-11, /*shift=*/1, "c.j {imm}"),
@@ -3476,17 +3455,14 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CJr) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatRNoZero(&Riscv64Assembler::CJr, "c.jr {reg}"), "CJr");
 }
 
 TEST_F(AssemblerRISCV64Test, CJalr) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatRNoZero(&Riscv64Assembler::CJalr, "c.jalr {reg}"), "CJalr");
 }
 
 TEST_F(AssemblerRISCV64Test, CBeqz) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CBeqz,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3498,7 +3474,6 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CBnez) {
-  ScopedCompressedMode cm(this);
   DriverStr(RepeatCRImm(&Riscv64Assembler::CBnez,
                         /*is_short=*/true,
                         /*no_zero_reg=*/false,
@@ -3510,24 +3485,22 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CEbreak) {
-  ScopedCompressedMode cm(this);
   __ CEbreak();
   DriverStr("c.ebreak", "CEbreak");
 }
 
 TEST_F(AssemblerRISCV64Test, CNop) {
-  ScopedCompressedMode cm(this);
   __ CNop();
   DriverStr("c.nop", "CNop");
 }
 
 TEST_F(AssemblerRISCV64Test, CUnimp) {
-  ScopedCompressedMode cm(this);
   __ CUnimp();
   DriverStr("c.unimp", "CUnimp");
 }
 
 TEST_F(AssemblerRISCV64Test, AddUw) {
+  ScopedCSuppression scs(this);  // Avoid `c.zext.w`.
   DriverStr(RepeatRRR(&Riscv64Assembler::AddUw, "add.uw {reg1}, {reg2}, {reg3}"), "AddUw");
 }
 
@@ -3645,14 +3618,17 @@
 }
 
 TEST_F(AssemblerRISCV64Test, ZbbSextB) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::ZbbSextB, "sext.b {reg1}, {reg2}"), "ZbbSextB");
 }
 
 TEST_F(AssemblerRISCV64Test, ZbbSextH) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::ZbbSextH, "sext.h {reg1}, {reg2}"), "ZbbSextH");
 }
 
 TEST_F(AssemblerRISCV64Test, ZbbZextH) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::ZbbZextH, "zext.h {reg1}, {reg2}"), "ZbbZextH");
 }
 
@@ -7868,22 +7844,25 @@
 
 // Pseudo instructions.
 TEST_F(AssemblerRISCV64Test, Nop) {
+  ScopedCSuppression scs(this);
   __ Nop();
   DriverStr("addi zero,zero,0", "Nop");
 }
 
 TEST_F(AssemblerRISCV64Test, Li) {
-  SetUseSimpleMarch(true);
+  ScopedMarchOverride smo(this, "-march=rv64imafd");
   TestLoadConst64("Li",
                   /*can_use_tmp=*/ false,
                   [&](XRegister rd, int64_t value) { __ Li(rd, value); });
 }
 
 TEST_F(AssemblerRISCV64Test, Mv) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::Mv, "addi {reg1}, {reg2}, 0"), "Mv");
 }
 
 TEST_F(AssemblerRISCV64Test, Not) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::Not, "xori {reg1}, {reg2}, -1"), "Not");
 }
 
@@ -7896,6 +7875,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, SextB) {
+  ScopedCSuppression scs(this);
   // Note: SEXT.B from the Zbb extension is not supported.
   DriverStr(RepeatRR(&Riscv64Assembler::SextB,
                      "slli {reg1}, {reg2}, 56\n"
@@ -7904,6 +7884,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, SextH) {
+  ScopedCSuppression scs(this);
   // Note: SEXT.H from the Zbb extension is not supported.
   DriverStr(RepeatRR(&Riscv64Assembler::SextH,
                      "slli {reg1}, {reg2}, 48\n"
@@ -7912,14 +7893,17 @@
 }
 
 TEST_F(AssemblerRISCV64Test, SextW) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::SextW, "addiw {reg1}, {reg2}, 0\n"), "SextW");
 }
 
 TEST_F(AssemblerRISCV64Test, ZextB) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::ZextB, "andi {reg1}, {reg2}, 255"), "ZextB");
 }
 
 TEST_F(AssemblerRISCV64Test, ZextH) {
+  ScopedCSuppression scs(this);
   // Note: ZEXT.H from the Zbb extension is not supported.
   DriverStr(RepeatRR(&Riscv64Assembler::ZextH,
                      "slli {reg1}, {reg2}, 48\n"
@@ -7928,6 +7912,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, ZextW) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::ZextW,
                      "slli {reg1}, {reg2}, 32\n"
                      "srli {reg1}, {reg1}, 32"),
@@ -7975,11 +7960,13 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Beqz) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension.
   DriverStr(RepeatRIbS(&Riscv64Assembler::Beqz, -11, 2, "beq {reg}, zero, {imm}\n"), "Beqz");
 }
 
 TEST_F(AssemblerRISCV64Test, Bnez) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension.
   DriverStr(RepeatRIbS(&Riscv64Assembler::Bnez, -11, 2, "bne {reg}, zero, {imm}\n"), "Bnez");
 }
@@ -8025,6 +8012,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, J) {
+  ScopedCSuppression scs(this);
   // TODO(riscv64): Change "-19, 2" to "-20, 1" for "C" Standard Extension.
   DriverStr(RepeatIbS<int32_t>(&Riscv64Assembler::J, -19, 2, "j {imm}\n"), "J");
 }
@@ -8035,18 +8023,22 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Jr) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatR(&Riscv64Assembler::Jr, "jr {reg}\n"), "Jr");
 }
 
 TEST_F(AssemblerRISCV64Test, JalrRA) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatR(&Riscv64Assembler::Jalr, "jalr {reg}\n"), "JalrRA");
 }
 
 TEST_F(AssemblerRISCV64Test, Jalr0) {
+  ScopedCSuppression scs(this);
   DriverStr(RepeatRR(&Riscv64Assembler::Jalr, "jalr {reg1}, {reg2}\n"), "Jalr0");
 }
 
 TEST_F(AssemblerRISCV64Test, Ret) {
+  ScopedCSuppression scs(this);
   __ Ret();
   DriverStr("ret\n", "Ret");
 }
@@ -8099,6 +8091,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, LoadConst32) {
+  ScopedCSuppression scs(this);
   // `LoadConst32()` emits the same code sequences as `Li()` for 32-bit values.
   ScratchRegisterScope srs(GetAssembler());
   srs.ExcludeXRegister(TMP);
@@ -8107,13 +8100,14 @@
 }
 
 TEST_F(AssemblerRISCV64Test, LoadConst64) {
-  SetUseSimpleMarch(true);
+  ScopedMarchOverride smo(this, "-march=rv64imafd");
   TestLoadConst64("LoadConst64",
                   /*can_use_tmp=*/ true,
                   [&](XRegister rd, int64_t value) { __ LoadConst64(rd, value); });
 }
 
 TEST_F(AssemblerRISCV64Test, AddConst32) {
+  ScopedCSuppression scs(this);
   auto emit_op = [&](XRegister rd, XRegister rs1, int64_t value) {
     __ AddConst32(rd, rs1, dchecked_integral_cast<int32_t>(value));
   };
@@ -8121,7 +8115,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, AddConst64) {
-  SetUseSimpleMarch(true);
+  ScopedMarchOverride smo(this, "-march=rv64imafd");
   auto emit_op = [&](XRegister rd, XRegister rs1, int64_t value) {
     __ AddConst64(rd, rs1, value);
   };
@@ -8129,38 +8123,47 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BcondForward3KiB) {
+  ScopedCSuppression scs(this);
   TestBcondForward("BcondForward3KiB", 3 * KB, "1", GetPrintBcond());
 }
 
 TEST_F(AssemblerRISCV64Test, BcondForward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestBcondForward("BcondForward3KiB", 3 * KB, "1", GetPrintBcond(), /*is_bare=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, BcondBackward3KiB) {
+  ScopedCSuppression scs(this);
   TestBcondBackward("BcondBackward3KiB", 3 * KB, "1", GetPrintBcond());
 }
 
 TEST_F(AssemblerRISCV64Test, BcondBackward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestBcondBackward("BcondBackward3KiB", 3 * KB, "1", GetPrintBcond(), /*is_bare=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, BcondForward5KiB) {
+  ScopedCSuppression scs(this);
   TestBcondForward("BcondForward5KiB", 5 * KB, "1", GetPrintBcondOppositeAndJ("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, BcondBackward5KiB) {
+  ScopedCSuppression scs(this);
   TestBcondBackward("BcondBackward5KiB", 5 * KB, "1", GetPrintBcondOppositeAndJ("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, BcondForward2MiB) {
+  ScopedCSuppression scs(this);
   TestBcondForward("BcondForward2MiB", 2 * MB, "1", GetPrintBcondOppositeAndTail("2", "3"));
 }
 
 TEST_F(AssemblerRISCV64Test, BcondBackward2MiB) {
+  ScopedCSuppression scs(this);
   TestBcondBackward("BcondBackward2MiB", 2 * MB, "1", GetPrintBcondOppositeAndTail("2", "3"));
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset13Forward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Forward("BeqA0A1MaxOffset13Forward",
                      MaxOffset13ForwardDistance() - /*BEQ*/ 4u,
                      "1",
@@ -8168,6 +8171,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset13ForwardBare) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Forward("BeqA0A1MaxOffset13ForwardBare",
                      MaxOffset13ForwardDistance() - /*BEQ*/ 4u,
                      "1",
@@ -8176,6 +8180,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset13Backward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Backward("BeqA0A1MaxOffset13Forward",
                       MaxOffset13BackwardDistance(),
                       "1",
@@ -8183,6 +8188,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset13BackwardBare) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Backward("BeqA0A1MaxOffset13ForwardBare",
                       MaxOffset13BackwardDistance(),
                       "1",
@@ -8191,6 +8197,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1OverMaxOffset13Forward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Forward("BeqA0A1OverMaxOffset13Forward",
                      MaxOffset13ForwardDistance() - /*BEQ*/ 4u + /*Exceed max*/ 4u,
                      "1",
@@ -8198,6 +8205,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1OverMaxOffset13Backward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Backward("BeqA0A1OverMaxOffset13Forward",
                       MaxOffset13BackwardDistance() + /*Exceed max*/ 4u,
                       "1",
@@ -8205,6 +8213,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Forward("BeqA0A1MaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u,
                      "1",
@@ -8212,6 +8221,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1MaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Backward("BeqA0A1MaxOffset21Backward",
                       MaxOffset21BackwardDistance() - /*BNE*/ 4u,
                       "1",
@@ -8219,6 +8229,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1OverMaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Forward("BeqA0A1OverMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u + /*Exceed max*/ 4u,
                      "1",
@@ -8226,6 +8237,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1OverMaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1Backward("BeqA0A1OverMaxOffset21Backward",
                       MaxOffset21BackwardDistance() - /*BNE*/ 4u + /*Exceed max*/ 4u,
                       "1",
@@ -8233,15 +8245,18 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1AlmostCascade) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1MaybeCascade("BeqA0A1AlmostCascade", /*cascade=*/ false, GetPrintBcond());
 }
 
 TEST_F(AssemblerRISCV64Test, BeqA0A1Cascade) {
+  ScopedCSuppression scs(this);
   TestBeqA0A1MaybeCascade(
       "BeqA0A1AlmostCascade", /*cascade=*/ true, GetPrintBcondOppositeAndJ("1"));
 }
 
 TEST_F(AssemblerRISCV64Test, BcondElimination) {
+  ScopedCSuppression scs(this);
   Riscv64Label label;
   __ Bind(&label);
   __ Nop();
@@ -8256,6 +8271,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, BcondUnconditional) {
+  ScopedCSuppression scs(this);
   Riscv64Label label;
   __ Bind(&label);
   __ Nop();
@@ -8274,54 +8290,67 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdForward3KiB) {
+  ScopedCSuppression scs(this);
   TestJalRdForward("JalRdForward3KiB", 3 * KB, "1", GetPrintJalRd());
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdForward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestJalRdForward("JalRdForward3KiB", 3 * KB, "1", GetPrintJalRd(), /*is_bare=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdBackward3KiB) {
+  ScopedCSuppression scs(this);
   TestJalRdBackward("JalRdBackward3KiB", 3 * KB, "1", GetPrintJalRd());
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdBackward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestJalRdBackward("JalRdBackward3KiB", 3 * KB, "1", GetPrintJalRd(), /*is_bare=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdForward2MiB) {
+  ScopedCSuppression scs(this);
   TestJalRdForward("JalRdForward2MiB", 2 * MB, "1", GetPrintCallRd("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, JalRdBackward2MiB) {
+  ScopedCSuppression scs(this);
   TestJalRdBackward("JalRdBackward2MiB", 2 * MB, "1", GetPrintCallRd("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, JForward3KiB) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JForward3KiB", 3 * KB, "1", GetEmitJ(), GetPrintJ());
 }
 
 TEST_F(AssemblerRISCV64Test, JForward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JForward3KiB", 3 * KB, "1", GetEmitJ(/*is_bare=*/ true), GetPrintJ());
 }
 
 TEST_F(AssemblerRISCV64Test, JBackward3KiB) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JBackward3KiB", 3 * KB, "1", GetEmitJ(), GetPrintJ());
 }
 
 TEST_F(AssemblerRISCV64Test, JBackward3KiBBare) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JBackward3KiB", 3 * KB, "1", GetEmitJ(/*is_bare=*/ true), GetPrintJ());
 }
 
 TEST_F(AssemblerRISCV64Test, JForward2MiB) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JForward2MiB", 2 * MB, "1", GetEmitJ(), GetPrintTail("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, JBackward2MiB) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JBackward2MiB", 2 * MB, "1", GetEmitJ(), GetPrintTail("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, JMaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u,
                      "1",
@@ -8330,6 +8359,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JMaxOffset21ForwardBare) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u,
                      "1",
@@ -8338,6 +8368,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JMaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JMaxOffset21Backward",
                       MaxOffset21BackwardDistance(),
                       "1",
@@ -8346,6 +8377,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JMaxOffset21BackwardBare) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JMaxOffset21Backward",
                       MaxOffset21BackwardDistance(),
                       "1",
@@ -8354,6 +8386,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JOverMaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("JOverMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u + /*Exceed max*/ 4u,
                      "1",
@@ -8362,6 +8395,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, JOverMaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("JMaxOffset21Backward",
                       MaxOffset21BackwardDistance() + /*Exceed max*/ 4u,
                       "1",
@@ -8370,22 +8404,27 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CallForward3KiB) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("CallForward3KiB", 3 * KB, "1", GetEmitJal(), GetPrintJal());
 }
 
 TEST_F(AssemblerRISCV64Test, CallBackward3KiB) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("CallBackward3KiB", 3 * KB, "1", GetEmitJal(), GetPrintJal());
 }
 
 TEST_F(AssemblerRISCV64Test, CallForward2MiB) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("CallForward2MiB", 2 * MB, "1", GetEmitJal(), GetPrintCall("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, CallBackward2MiB) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("CallBackward2MiB", 2 * MB, "1", GetEmitJal(), GetPrintCall("2"));
 }
 
 TEST_F(AssemblerRISCV64Test, CallMaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("CallMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u,
                      "1",
@@ -8394,6 +8433,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CallMaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("CallMaxOffset21Backward",
                       MaxOffset21BackwardDistance(),
                       "1",
@@ -8402,6 +8442,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CallOverMaxOffset21Forward) {
+  ScopedCSuppression scs(this);
   TestBuncondForward("CallOverMaxOffset21Forward",
                      MaxOffset21ForwardDistance() - /*J*/ 4u + /*Exceed max*/ 4u,
                      "1",
@@ -8410,6 +8451,7 @@
 }
 
 TEST_F(AssemblerRISCV64Test, CallOverMaxOffset21Backward) {
+  ScopedCSuppression scs(this);
   TestBuncondBackward("CallMaxOffset21Backward",
                       MaxOffset21BackwardDistance() + /*Exceed max*/ 4u,
                       "1",
@@ -8418,66 +8460,82 @@
 }
 
 TEST_F(AssemblerRISCV64Test, Loadb) {
+  ScopedCSuppression scs(this);  // Suppress 16-bit instructions for address formation.
   TestLoadStoreArbitraryOffset("Loadb", "lb", &Riscv64Assembler::Loadb, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadh) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Loadh", "lh", &Riscv64Assembler::Loadh, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadw) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Loadw", "lw", &Riscv64Assembler::Loadw, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadd) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Loadd", "ld", &Riscv64Assembler::Loadd, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadbu) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Loadbu", "lbu", &Riscv64Assembler::Loadbu, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadhu) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Loadhu", "lhu", &Riscv64Assembler::Loadhu, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Loadwu) {
+  ScopedCSuppression scs(this);  // Suppress 16-bit instructions for address formation.
   TestLoadStoreArbitraryOffset("Loadwu", "lwu", &Riscv64Assembler::Loadwu, /*is_store=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, Storeb) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Storeb", "sb", &Riscv64Assembler::Storeb, /*is_store=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, Storeh) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Storeh", "sh", &Riscv64Assembler::Storeh, /*is_store=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, Storew) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Storew", "sw", &Riscv64Assembler::Storew, /*is_store=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, Stored) {
+  ScopedCSuppression scs(this);
   TestLoadStoreArbitraryOffset("Stored", "sd", &Riscv64Assembler::Stored, /*is_store=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, FLoadw) {
+  ScopedCSuppression scs(this);  // Suppress 16-bit instructions for address formation.
   TestFPLoadStoreArbitraryOffset("FLoadw", "flw", &Riscv64Assembler::FLoadw);
 }
 
 TEST_F(AssemblerRISCV64Test, FLoadd) {
+  ScopedCSuppression scs(this);
   TestFPLoadStoreArbitraryOffset("FLoadd", "fld", &Riscv64Assembler::FLoadd);
 }
 
 TEST_F(AssemblerRISCV64Test, FStorew) {
+  ScopedCSuppression scs(this);  // Suppress 16-bit instructions for address formation.
   TestFPLoadStoreArbitraryOffset("FStorew", "fsw", &Riscv64Assembler::FStorew);
 }
 
 TEST_F(AssemblerRISCV64Test, FStored) {
+  ScopedCSuppression scs(this);
   TestFPLoadStoreArbitraryOffset("FStored", "fsd", &Riscv64Assembler::FStored);
 }
 
 TEST_F(AssemblerRISCV64Test, Unimp) {
+  ScopedCSuppression scs(this);
   __ Unimp();
   DriverStr("unimp\n", "Unimp");
 }
@@ -8507,14 +8565,17 @@
 }
 
 TEST_F(AssemblerRISCV64Test, LoadLiteralWithPaddingForLong) {
+  ScopedCSuppression scs(this);
   TestLoadLiteral("LoadLiteralWithPaddingForLong", /*with_padding_for_long=*/ true);
 }
 
 TEST_F(AssemblerRISCV64Test, LoadLiteralWithoutPaddingForLong) {
+  ScopedCSuppression scs(this);
   TestLoadLiteral("LoadLiteralWithoutPaddingForLong", /*with_padding_for_long=*/ false);
 }
 
 TEST_F(AssemblerRISCV64Test, JumpTable) {
+  ScopedCSuppression scs(this);
   std::string expected;
   expected += EmitNops(sizeof(uint32_t));
   Riscv64Label targets[4];
diff --git a/compiler/utils/riscv64/jni_macro_assembler_riscv64_test.cc b/compiler/utils/riscv64/jni_macro_assembler_riscv64_test.cc
index be6feeb..9717930 100644
--- a/compiler/utils/riscv64/jni_macro_assembler_riscv64_test.cc
+++ b/compiler/utils/riscv64/jni_macro_assembler_riscv64_test.cc
@@ -46,6 +46,18 @@
  protected:
   InstructionSet GetIsa() override { return InstructionSet::kRiscv64; }
 
+  std::vector<std::string> GetAssemblerCommand() override {
+    std::vector<std::string> result = AssemblerTestBase::GetAssemblerCommand();
+    if (march_override_.has_value()) {
+      auto it = std::find_if(result.begin(),
+                             result.end(),
+                             [](const std::string& s) { return StartsWith(s, "-march="); });
+      CHECK(it != result.end());
+      *it = march_override_.value();
+    }
+    return result;
+  }
+
   void DriverStr(const std::string& assembly_text, const std::string& test_name) {
     assembler_.FinalizeCode();
     size_t cs = assembler_.CodeSize();
@@ -76,6 +88,9 @@
   MallocArenaPool pool_;
   ArenaAllocator allocator_;
   Riscv64JNIMacroAssembler assembler_;
+
+  // TODO: Implement auto-compression and remove this override.
+  std::optional<std::string> march_override_ = "-march=rv64imafdv_zba_zbb";
 };
 
 TEST_F(JniMacroAssemblerRiscv64Test, StackFrame) {
diff --git a/disassembler/disassembler_riscv64.cc b/disassembler/disassembler_riscv64.cc
index 41a6b3f..09e9faf 100644
--- a/disassembler/disassembler_riscv64.cc
+++ b/disassembler/disassembler_riscv64.cc
@@ -163,7 +163,7 @@
 
   // Extracts the immediate from a compressed instruction
   // where `imm[5]` is in bit `[12]` and `imm[4:0]` is in bits `[6:2]`
-  // and performes sign-extension if required
+  // and performs sign-extension if required
   template <typename T>
   static T Decode16Imm6(uint32_t insn16) {
     DCHECK(IsUint<16>(insn16));
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 484324e..e9c26c5 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -34,7 +34,6 @@
         "native_loader.cpp",
     ],
     header_libs: [
-        "art_libartbase_headers",
         "libnativehelper_header_only",
     ],
     shared_libs: [
@@ -67,7 +66,6 @@
             ],
             static_libs: [
                 "libPlatformProperties",
-                "libmodules-utils-build",
             ],
         },
     },
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index bd186c1..e2b2729 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -85,7 +85,6 @@
 
 const std::regex kVendorPathRegex("(/system)?/vendor/.*");
 const std::regex kProductPathRegex("(/system)?/product/.*");
-const std::regex kSystemPathRegex("/system(_ext)?/.*");  // MUST be tested last.
 
 jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) {
   jclass class_loader_class = env->FindClass("java/lang/ClassLoader");
@@ -104,9 +103,6 @@
   if (is_product_treblelized() && std::regex_match(path.begin(), path.end(), kProductPathRegex)) {
     return API_DOMAIN_PRODUCT;
   }
-  if (std::regex_match(path.begin(), path.end(), kSystemPathRegex)) {
-    return API_DOMAIN_SYSTEM;
-  }
   return API_DOMAIN_DEFAULT;
 }
 
diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h
index b932a55..ae1cd88 100644
--- a/libnativeloader/library_namespaces.h
+++ b/libnativeloader/library_namespaces.h
@@ -53,7 +53,6 @@
   API_DOMAIN_DEFAULT = 0,  // Locations other than those below, in particular for ordinary apps
   API_DOMAIN_VENDOR = 1,   // Vendor partition
   API_DOMAIN_PRODUCT = 2,  // Product partition
-  API_DOMAIN_SYSTEM = 3,   // System and system_ext partitions
 };
 
 ApiDomain GetApiDomainFromPath(const std::string_view path);
diff --git a/libnativeloader/library_namespaces_test.cpp b/libnativeloader/library_namespaces_test.cpp
index 8e00e2b..7780418 100644
--- a/libnativeloader/library_namespaces_test.cpp
+++ b/libnativeloader/library_namespaces_test.cpp
@@ -31,45 +31,40 @@
 using ::android::base::testing::WithMessage;
 using ::testing::StartsWith;
 
-static ApiDomain GetProductApiDomain(ApiDomain fallback_domain) {
+TEST(LibraryNamespacesTest, TestGetApiDomainFromPath) {
   // GetApiDomainFromPath returns API_DOMAIN_PRODUCT only if the device is
   // trebleized and has an unbundled product partition.
-  return is_product_treblelized() ? API_DOMAIN_PRODUCT : fallback_domain;
-}
+  ApiDomain api_domain_product = is_product_treblelized() ? API_DOMAIN_PRODUCT : API_DOMAIN_DEFAULT;
 
-TEST(LibraryNamespacesTest, TestGetApiDomainFromPath) {
   EXPECT_EQ(GetApiDomainFromPath("/data/somewhere"), API_DOMAIN_DEFAULT);
-  EXPECT_EQ(GetApiDomainFromPath("/system/somewhere"), API_DOMAIN_SYSTEM);
-  EXPECT_EQ(GetApiDomainFromPath("/system_ext/somewhere"), API_DOMAIN_SYSTEM);
-  EXPECT_EQ(GetApiDomainFromPath("/systemext/somewhere"), API_DOMAIN_DEFAULT);
-  EXPECT_EQ(GetApiDomainFromPath("/product/somewhere"), GetProductApiDomain(API_DOMAIN_DEFAULT));
+  EXPECT_EQ(GetApiDomainFromPath("/system/somewhere"), API_DOMAIN_DEFAULT);
+  EXPECT_EQ(GetApiDomainFromPath("/product/somewhere"), api_domain_product);
   EXPECT_EQ(GetApiDomainFromPath("/vendor/somewhere"), API_DOMAIN_VENDOR);
-  EXPECT_EQ(GetApiDomainFromPath("/system/product/somewhere"),
-            GetProductApiDomain(API_DOMAIN_SYSTEM));
+  EXPECT_EQ(GetApiDomainFromPath("/system/product/somewhere"), api_domain_product);
   EXPECT_EQ(GetApiDomainFromPath("/system/vendor/somewhere"), API_DOMAIN_VENDOR);
 
   EXPECT_EQ(GetApiDomainFromPath(""), API_DOMAIN_DEFAULT);
   EXPECT_EQ(GetApiDomainFromPath("/"), API_DOMAIN_DEFAULT);
   EXPECT_EQ(GetApiDomainFromPath("product/somewhere"), API_DOMAIN_DEFAULT);
   EXPECT_EQ(GetApiDomainFromPath("/product"), API_DOMAIN_DEFAULT);
-  EXPECT_EQ(GetApiDomainFromPath("/product/"), GetProductApiDomain(API_DOMAIN_DEFAULT));
+  EXPECT_EQ(GetApiDomainFromPath("/product/"), api_domain_product);
   EXPECT_EQ(GetApiDomainFromPath(":/product/"), API_DOMAIN_DEFAULT);
 
   EXPECT_EQ(GetApiDomainFromPath("/data/somewhere:/product/somewhere"), API_DOMAIN_DEFAULT);
   EXPECT_EQ(GetApiDomainFromPath("/vendor/somewhere:/product/somewhere"), API_DOMAIN_VENDOR);
-  EXPECT_EQ(GetApiDomainFromPath("/product/somewhere:/vendor/somewhere"),
-            GetProductApiDomain(API_DOMAIN_DEFAULT));
+  EXPECT_EQ(GetApiDomainFromPath("/product/somewhere:/vendor/somewhere"), api_domain_product);
 }
 
 TEST(LibraryNamespacesTest, TestGetApiDomainFromPathList) {
+  // GetApiDomainFromPath returns API_DOMAIN_PRODUCT only if the device is
+  // trebleized and has an unbundled product partition.
+  ApiDomain api_domain_product = is_product_treblelized() ? API_DOMAIN_PRODUCT : API_DOMAIN_DEFAULT;
+
   EXPECT_THAT(GetApiDomainFromPathList("/data/somewhere"), HasValue(API_DOMAIN_DEFAULT));
-  EXPECT_THAT(GetApiDomainFromPathList("/system/somewhere"), HasValue(API_DOMAIN_SYSTEM));
-  EXPECT_THAT(GetApiDomainFromPathList("/system_ext/somewhere"), HasValue(API_DOMAIN_SYSTEM));
-  EXPECT_THAT(GetApiDomainFromPathList("/product/somewhere"),
-              HasValue(GetProductApiDomain(API_DOMAIN_DEFAULT)));
+  EXPECT_THAT(GetApiDomainFromPathList("/system/somewhere"), HasValue(API_DOMAIN_DEFAULT));
+  EXPECT_THAT(GetApiDomainFromPathList("/product/somewhere"), HasValue(api_domain_product));
   EXPECT_THAT(GetApiDomainFromPathList("/vendor/somewhere"), HasValue(API_DOMAIN_VENDOR));
-  EXPECT_THAT(GetApiDomainFromPathList("/system/product/somewhere"),
-              HasValue(GetProductApiDomain(API_DOMAIN_SYSTEM)));
+  EXPECT_THAT(GetApiDomainFromPathList("/system/product/somewhere"), HasValue(api_domain_product));
   EXPECT_THAT(GetApiDomainFromPathList("/system/vendor/somewhere"), HasValue(API_DOMAIN_VENDOR));
 
   EXPECT_THAT(GetApiDomainFromPathList(""), HasValue(API_DOMAIN_DEFAULT));
@@ -78,17 +73,13 @@
   EXPECT_THAT(GetApiDomainFromPathList("/vendor/somewhere:"), HasValue(API_DOMAIN_VENDOR));
 
   EXPECT_THAT(GetApiDomainFromPathList("/data/somewhere:/product/somewhere"),
-              HasValue(GetProductApiDomain(API_DOMAIN_DEFAULT)));
-  if (GetProductApiDomain(API_DOMAIN_DEFAULT) == API_DOMAIN_PRODUCT) {
+              HasValue(api_domain_product));
+  if (api_domain_product == API_DOMAIN_PRODUCT) {
     EXPECT_THAT(GetApiDomainFromPathList("/vendor/somewhere:/product/somewhere"),
                 HasError(WithMessage(StartsWith("Path list crosses partition boundaries"))));
     EXPECT_THAT(GetApiDomainFromPathList("/product/somewhere:/vendor/somewhere"),
                 HasError(WithMessage(StartsWith("Path list crosses partition boundaries"))));
   }
-  EXPECT_THAT(GetApiDomainFromPathList("/system/somewhere:/vendor/somewhere"),
-              HasError(WithMessage(StartsWith("Path list crosses partition boundaries"))));
-  EXPECT_THAT(GetApiDomainFromPathList("/system_ext/somewhere:/vendor/somewhere"),
-              HasError(WithMessage(StartsWith("Path list crosses partition boundaries"))));
 }
 
 }  // namespace
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 5b4988a..6192543 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -25,7 +25,6 @@
 #include <memory>
 #include <mutex>
 #include <optional>
-#include <regex>
 #include <string>
 #include <vector>
 
@@ -33,13 +32,11 @@
 #include "android-base/macros.h"
 #include "android-base/strings.h"
 #include "android-base/thread_annotations.h"
-#include "base/macros.h"
 #include "nativebridge/native_bridge.h"
 #include "nativehelper/scoped_utf_chars.h"
 #include "public_libraries.h"
 
 #ifdef ART_TARGET_ANDROID
-#include "android-modules-utils/sdk_level.h"
 #include "library_namespaces.h"
 #include "log/log.h"
 #include "nativeloader/dlext_namespaces.h"
@@ -54,9 +51,6 @@
 using ::android::base::Result;
 using ::android::nativeloader::LibraryNamespaces;
 
-const std::regex kPartitionNativeLibPathRegex(
-    "/(system(_ext)?|(system/)?(vendor|product))/lib(64)?/.*");
-
 // NATIVELOADER_DEFAULT_NAMESPACE_LIBS is an environment variable that can be
 // used to list extra libraries (separated by ":") that libnativeloader will
 // load from the default namespace. The libraries must be listed without paths,
@@ -93,23 +87,6 @@
   return std::nullopt;
 }
 
-Result<NativeLoaderNamespace> GetNamespaceForApiDomain(nativeloader::ApiDomain api_domain,
-                                                       bool is_bridged) {
-  switch (api_domain) {
-    case nativeloader::API_DOMAIN_VENDOR:
-      return NativeLoaderNamespace::GetExportedNamespace(nativeloader::kVendorNamespaceName,
-                                                         is_bridged);
-    case nativeloader::API_DOMAIN_PRODUCT:
-      return NativeLoaderNamespace::GetExportedNamespace(nativeloader::kProductNamespaceName,
-                                                         is_bridged);
-    case nativeloader::API_DOMAIN_SYSTEM:
-      return NativeLoaderNamespace::GetSystemNamespace(is_bridged);
-    default:
-      LOG_FATAL("Invalid API domain %d", api_domain);
-      UNREACHABLE();
-  }
-}
-
 Result<void> CreateNativeloaderDefaultNamespaceLibsLink(NativeLoaderNamespace& ns)
     REQUIRES(g_namespaces_mutex) {
   const char* links = getenv("NATIVELOADER_DEFAULT_NAMESPACE_LIBS");
@@ -334,61 +311,6 @@
     return handle;
   }
 
-  // If the caller is in any of the system image partitions and the library is
-  // in the same partition then load it without regards to public library
-  // restrictions. This is only done if the library is specified by an absolute
-  // path, so we don't affect the lookup process for libraries specified by name
-  // only.
-  if (caller_location != nullptr &&
-      // Check that the library is in the partition-wide native library
-      // location. Apps in the partition may have their own native libraries,
-      // and those should still be loaded with the app's classloader namespace.
-      std::regex_match(path, kPartitionNativeLibPathRegex) &&
-      // Don't do this if the system image is older than V, to avoid any compat
-      // issues with apps and shared libs in them.
-      android::modules::sdklevel::IsAtLeastV()) {
-    nativeloader::ApiDomain caller_api_domain = nativeloader::GetApiDomainFromPath(caller_location);
-    if (caller_api_domain != nativeloader::API_DOMAIN_DEFAULT) {
-      nativeloader::ApiDomain library_api_domain = nativeloader::GetApiDomainFromPath(path);
-
-      if (library_api_domain == caller_api_domain) {
-        bool is_bridged = false;
-        if (library_path_j != nullptr) {
-          ScopedUtfChars library_path_utf_chars(env, library_path_j);
-          if (library_path_utf_chars[0] != '\0') {
-            is_bridged = NativeBridgeIsPathSupported(library_path_utf_chars.c_str());
-          }
-        }
-
-        Result<NativeLoaderNamespace> ns = GetNamespaceForApiDomain(caller_api_domain, is_bridged);
-        if (!ns.ok()) {
-          ALOGD("Failed to find ns for caller %s in API domain %d to load %s (is_bridged=%b): %s",
-                caller_location,
-                caller_api_domain,
-                path,
-                is_bridged,
-                ns.error().message().c_str());
-          *error_msg = strdup(ns.error().message().c_str());
-          return nullptr;
-        }
-
-        *needs_native_bridge = ns.value().IsBridged();
-        Result<void*> handle = ns.value().Load(path);
-        ALOGD("Load %s using ns %s for caller %s in same partition (is_bridged=%b): %s",
-              path,
-              ns.value().name().c_str(),
-              caller_location,
-              is_bridged,
-              handle.ok() ? "ok" : handle.error().message().c_str());
-        if (!handle.ok()) {
-          *error_msg = strdup(handle.error().message().c_str());
-          return nullptr;
-        }
-        return handle.value();
-      }
-    }
-  }
-
   std::lock_guard<std::mutex> guard(g_namespaces_mutex);
 
   {
diff --git a/libnativeloader/test/src/android/test/app/DataAppTest.java b/libnativeloader/test/src/android/test/app/DataAppTest.java
index 44aa911..905b5bb 100644
--- a/libnativeloader/test/src/android/test/app/DataAppTest.java
+++ b/libnativeloader/test/src/android/test/app/DataAppTest.java
@@ -67,18 +67,11 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemSharedLib() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work because the findLibrary call in
-            // loadLibrary0 in Runtime.java searches the system libs and converts
-            // them to absolute paths.
-            SystemSharedLib.loadLibrary("system_private2");
-            SystemSharedLib.loadLibrary("systemext_private2");
-        } else {
-            TestUtils.assertLibraryInaccessible(
-                    () -> { SystemSharedLib.loadLibrary("system_private2"); });
-            TestUtils.assertLibraryInaccessible(
-                    () -> { SystemSharedLib.loadLibrary("systemext_private2"); });
-        }
+        // TODO(b/237577392): Loading a private native system library via a shared system library
+        // ought to work.
+        TestUtils.assertLibraryInaccessible(() -> SystemSharedLib.loadLibrary("system_private2"));
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemSharedLib.loadLibrary("systemext_private2"));
 
         if (!TestUtils.skipPublicProductLibTests()) {
             TestUtils.assertLibraryInaccessible(
@@ -90,18 +83,12 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work because the findLibrary call in
-            // loadLibrary0 in Runtime.java searches the system libs and converts
-            // them to absolute paths.
-            SystemExtSharedLib.loadLibrary("system_private3");
-            SystemExtSharedLib.loadLibrary("systemext_private3");
-        } else {
-            TestUtils.assertLibraryInaccessible(
-                    () -> { SystemExtSharedLib.loadLibrary("system_private3"); });
-            TestUtils.assertLibraryInaccessible(
-                    () -> { SystemExtSharedLib.loadLibrary("systemext_private3"); });
-        }
+        // TODO(b/237577392): Loading a private native system library via a shared system library
+        // ought to work.
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemExtSharedLib.loadLibrary("system_private3"));
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemExtSharedLib.loadLibrary("systemext_private3"));
 
         if (!TestUtils.skipPublicProductLibTests()) {
             TestUtils.assertLibraryInaccessible(
diff --git a/libnativeloader/test/src/android/test/app/ProductAppTest.java b/libnativeloader/test/src/android/test/app/ProductAppTest.java
index a42d191..4cf379c 100644
--- a/libnativeloader/test/src/android/test/app/ProductAppTest.java
+++ b/libnativeloader/test/src/android/test/app/ProductAppTest.java
@@ -72,21 +72,14 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemSharedLib() {
-        if (TestUtils.productAppsAreShared() || TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work in the
-            // canLoadPrivateLibsFromSamePartition case because the findLibrary
-            // call in loadLibrary0 in Runtime.java searches the system libs and
-            // converts them to absolute paths.
-            SystemSharedLib.loadLibrary("system_private2");
-            SystemSharedLib.loadLibrary("systemext_private2");
-        } else {
+        if (!TestUtils.productAppsAreShared()) {
+            // TODO(b/237577392): Loading a private native system library via a shared system
+            // library ought to work.
             TestUtils.assertLibraryInaccessible(
                     () -> SystemSharedLib.loadLibrary("system_private2"));
             TestUtils.assertLibraryInaccessible(
                     () -> SystemSharedLib.loadLibrary("systemext_private2"));
-        }
 
-        if (!TestUtils.productAppsAreShared()) {
             TestUtils.assertLibraryInaccessible(
                     () -> SystemSharedLib.loadLibrary("product_private2"));
         }
@@ -96,21 +89,14 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
-        if (TestUtils.productAppsAreShared() || TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work in the
-            // canLoadPrivateLibsFromSamePartition case because the findLibrary
-            // call in loadLibrary0 in Runtime.java searches the system libs and
-            // converts them to absolute paths.
-            SystemExtSharedLib.loadLibrary("system_private3");
-            SystemExtSharedLib.loadLibrary("systemext_private3");
-        } else {
+        if (!TestUtils.productAppsAreShared()) {
+            // TODO(b/237577392): Loading a private native system library via a shared system
+            // library ought to work.
             TestUtils.assertLibraryInaccessible(
                     () -> SystemExtSharedLib.loadLibrary("system_private3"));
             TestUtils.assertLibraryInaccessible(
                     () -> SystemExtSharedLib.loadLibrary("systemext_private3"));
-        }
 
-        if (!TestUtils.productAppsAreShared()) {
             TestUtils.assertLibraryInaccessible(
                     () -> SystemExtSharedLib.loadLibrary("product_private3"));
         }
diff --git a/libnativeloader/test/src/android/test/app/VendorAppTest.java b/libnativeloader/test/src/android/test/app/VendorAppTest.java
index b0e141c..377f670 100644
--- a/libnativeloader/test/src/android/test/app/VendorAppTest.java
+++ b/libnativeloader/test/src/android/test/app/VendorAppTest.java
@@ -71,18 +71,11 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemSharedLib() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work because the findLibrary call in
-            // loadLibrary0 in Runtime.java searches the system libs and converts
-            // them to absolute paths.
-            SystemSharedLib.loadLibrary("system_private2");
-            SystemSharedLib.loadLibrary("systemext_private2");
-        } else {
-            TestUtils.assertLibraryInaccessible(
-                    () -> SystemSharedLib.loadLibrary("system_private2"));
-            TestUtils.assertLibraryInaccessible(
-                    () -> SystemSharedLib.loadLibrary("systemext_private2"));
-        }
+        // TODO(b/237577392): Loading a private native system library via a shared system library
+        // ought to work.
+        TestUtils.assertLibraryInaccessible(() -> SystemSharedLib.loadLibrary("system_private2"));
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemSharedLib.loadLibrary("systemext_private2"));
 
         if (!TestUtils.skipPublicProductLibTests()) {
             TestUtils.assertLibraryInaccessible(
@@ -94,18 +87,12 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()) {
-            // TODO(b/186729817): These loads work because the findLibrary call in
-            // loadLibrary0 in Runtime.java searches the system libs and converts
-            // them to absolute paths.
-            SystemExtSharedLib.loadLibrary("system_private3");
-            SystemExtSharedLib.loadLibrary("systemext_private3");
-        } else {
-            TestUtils.assertLibraryInaccessible(
-                    () -> SystemExtSharedLib.loadLibrary("system_private3"));
-            TestUtils.assertLibraryInaccessible(
-                    () -> SystemExtSharedLib.loadLibrary("systemext_private3"));
-        }
+        // TODO(b/237577392): Loading a private native system library via a shared system library
+        // ought to work.
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemExtSharedLib.loadLibrary("system_private3"));
+        TestUtils.assertLibraryInaccessible(
+                () -> SystemExtSharedLib.loadLibrary("systemext_private3"));
 
         if (!TestUtils.skipPublicProductLibTests()) {
             TestUtils.assertLibraryInaccessible(
diff --git a/libnativeloader/test/src/android/test/lib/AppTestCommon.java b/libnativeloader/test/src/android/test/lib/AppTestCommon.java
index 75d45b5..51f4655 100644
--- a/libnativeloader/test/src/android/test/lib/AppTestCommon.java
+++ b/libnativeloader/test/src/android/test/lib/AppTestCommon.java
@@ -41,6 +41,7 @@
     private boolean systemPrivateLibsAccessibleFromAppNamespace() {
         // Currently it only works from system apps. It also works from product
         // apps on old versions where they were treated like system apps.
+        // TODO(b/237577392): Fix this to work from system shared libs.
         return getAppLocation() == AppLocation.SYSTEM
                 || (getAppLocation() == AppLocation.PRODUCT && TestUtils.productAppsAreShared());
     }
@@ -51,6 +52,7 @@
         // In old versions where product apps were treated like system apps, the
         // product private libs were included in the system namespace, so
         // they're accessible both from system and product apps.
+        // TODO(b/237577392): Fix this to work from product shared libs.
         return (getAppLocation() == AppLocation.SYSTEM || getAppLocation() == AppLocation.PRODUCT)
                 && TestUtils.productAppsAreShared();
     }
@@ -58,9 +60,7 @@
     // Detect exception where we don't switch from a shared system namespace to
     // a product or vendor "unbundled" namespace when calling into
     // ProductSharedLib and VendorSharedLib. That means they still can load
-    // private system libs but not private libs in their own partition (however
-    // the latter works anyway when canLoadPrivateLibsFromSamePartition() is
-    // true).
+    // private system libs but not private libs in their own partition.
     // TODO(mast): Stop propagating the shared property (isBundledApp in
     // LoadedApk.java) down to public and vendor shared java libs?
     private boolean noSwitchToVendorOrProductNamespace() {
@@ -72,8 +72,7 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemSharedLibWithAbsolutePaths() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()
-                || systemPrivateLibsAccessibleFromAppNamespace()) {
+        if (systemPrivateLibsAccessibleFromAppNamespace()) {
             SystemSharedLib.load(TestUtils.libPath("/system", "system_private7"));
             SystemSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private7"));
         } else {
@@ -99,8 +98,7 @@
 
     @Test
     public void testLoadPrivateLibrariesViaSystemExtSharedLibWithAbsolutePaths() {
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()
-                || systemPrivateLibsAccessibleFromAppNamespace()) {
+        if (systemPrivateLibsAccessibleFromAppNamespace()) {
             SystemExtSharedLib.load(TestUtils.libPath("/system", "system_private8"));
             SystemExtSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private8"));
         } else {
@@ -147,8 +145,7 @@
             loadPrivateProductLib = getAppLocation() == AppLocation.SYSTEM
                     || getAppLocation() == AppLocation.PRODUCT;
         } else {
-            loadPrivateProductLib = TestUtils.canLoadPrivateLibsFromSamePartition()
-                    || !noSwitchToVendorOrProductNamespace();
+            loadPrivateProductLib = !noSwitchToVendorOrProductNamespace();
         }
         if (loadPrivateProductLib) {
             ProductSharedLib.load(TestUtils.libPath("/product", "product_private9"));
@@ -184,8 +181,7 @@
             });
         }
 
-        if (TestUtils.canLoadPrivateLibsFromSamePartition()
-                || !noSwitchToVendorOrProductNamespace()) {
+        if (!noSwitchToVendorOrProductNamespace()) {
             VendorSharedLib.load(TestUtils.libPath("/vendor", "vendor_private10"));
         } else {
             TestUtils.assertLibraryInaccessible(() -> {
diff --git a/libnativeloader/test/src/android/test/lib/TestUtils.java b/libnativeloader/test/src/android/test/lib/TestUtils.java
index 00b486e..5f5cd91 100644
--- a/libnativeloader/test/src/android/test/lib/TestUtils.java
+++ b/libnativeloader/test/src/android/test/lib/TestUtils.java
@@ -55,12 +55,6 @@
         return !SdkLevel.isAtLeastU() && SystemProperties.get("ro.product.vndk.version").isEmpty();
     }
 
-    // True if apps and shared java libs in system/product/vendor partitions are
-    // able to load private native libs in the same partition.
-    public static boolean canLoadPrivateLibsFromSamePartition() {
-        return SdkLevel.isAtLeastV();
-    }
-
     // Test that private libs are present, as a safeguard so that the dlopen
     // failures we expect in other tests aren't due to them not being there.
     public static void testPrivateLibsExist(String libDir, String libStem) {
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index bbe3970..2a364f3 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -958,12 +958,12 @@
     if (class_linker->IsBootClassLoader(loader)) {
       loader = nullptr;
       class_loader = nullptr;
-    }
-    if (caller_class != nullptr) {
-      ObjPtr<mirror::Class> caller = soa.Decode<mirror::Class>(caller_class);
-      ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
-      if (dex_cache != nullptr) {
-        caller_location = dex_cache->GetLocation()->ToModifiedUtf8();
+      if (caller_class != nullptr) {
+        ObjPtr<mirror::Class> caller = soa.Decode<mirror::Class>(caller_class);
+        ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
+        if (dex_cache != nullptr) {
+          caller_location = dex_cache->GetLocation()->ToModifiedUtf8();
+        }
       }
     }
 
diff --git a/tools/luci/config/generated/cr-buildbucket.cfg b/tools/luci/config/generated/cr-buildbucket.cfg
index 6708ed1..1e207d5 100644
--- a/tools/luci/config/generated/cr-buildbucket.cfg
+++ b/tools/luci/config/generated/cr-buildbucket.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see BuildbucketCfg message:
-#   https://luci-config.appspot.com/schemas/projects:buildbucket.cfg
+#   https://config.luci.app/schemas/projects:buildbucket.cfg
 
 buckets {
   name: "ci"
@@ -585,6 +585,35 @@
       }
     }
     builders {
+      name: "qemu-armv8-ndebug"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "os:Linux"
+      dimensions: "pool:luci.art.ci"
+      recipe {
+        name: "art"
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        properties_j: "builder_group:\"client.art\""
+        properties_j: "concurrent_collector:true"
+        properties_j: "debug:false"
+        properties_j: "device:\"qemu-armv8\""
+        properties_j: "generational_cc:true"
+        properties_j: "on_virtual_machine:true"
+      }
+      execution_timeout_secs: 108000
+      expiration_secs: 61200
+      caches {
+        name: "art"
+        path: "art"
+      }
+      build_numbers: YES
+      service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+    }
+    builders {
       name: "qemu-riscv64-ndebug"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "os:Linux"
diff --git a/tools/luci/config/generated/luci-logdog.cfg b/tools/luci/config/generated/luci-logdog.cfg
index adc75be..01a3912 100644
--- a/tools/luci/config/generated/luci-logdog.cfg
+++ b/tools/luci/config/generated/luci-logdog.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see ProjectConfig message:
-#   https://luci-config.appspot.com/schemas/projects:luci-logdog.cfg
+#   https://config.luci.app/schemas/projects:luci-logdog.cfg
 
 reader_auth_groups: "all"
 writer_auth_groups: "luci-logdog-chromium-writers"
diff --git a/tools/luci/config/generated/luci-milo.cfg b/tools/luci/config/generated/luci-milo.cfg
index 8863af6..979a5d1 100644
--- a/tools/luci/config/generated/luci-milo.cfg
+++ b/tools/luci/config/generated/luci-milo.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see Project message:
-#   https://luci-config.appspot.com/schemas/projects:luci-milo.cfg
+#   https://config.luci.app/schemas/projects:luci-milo.cfg
 
 consoles {
   id: "luci"
diff --git a/tools/luci/config/generated/luci-notify.cfg b/tools/luci/config/generated/luci-notify.cfg
index 4456fa3..a281a82 100644
--- a/tools/luci/config/generated/luci-notify.cfg
+++ b/tools/luci/config/generated/luci-notify.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see ProjectConfig message:
-#   https://luci-config.appspot.com/schemas/projects:luci-notify.cfg
+#   https://config.luci.app/schemas/projects:luci-notify.cfg
 
 notifiers {
   notifications {
@@ -274,6 +274,19 @@
   }
   builders {
     bucket: "ci"
+    name: "qemu-armv8-ndebug"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    on_new_status: INFRA_FAILURE
+    email {
+      recipients: "art-team+chromium-buildbot@google.com"
+    }
+  }
+  builders {
+    bucket: "ci"
     name: "qemu-riscv64-ndebug"
   }
 }
diff --git a/tools/luci/config/generated/luci-scheduler.cfg b/tools/luci/config/generated/luci-scheduler.cfg
index 291ed09..4794473 100644
--- a/tools/luci/config/generated/luci-scheduler.cfg
+++ b/tools/luci/config/generated/luci-scheduler.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see ProjectConfig message:
-#   https://luci-config.appspot.com/schemas/projects:luci-scheduler.cfg
+#   https://config.luci.app/schemas/projects:luci-scheduler.cfg
 
 job {
   id: "angler-armv7-debug"
@@ -205,6 +205,16 @@
   }
 }
 job {
+  id: "qemu-armv8-ndebug"
+  realm: "ci"
+  acl_sets: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "qemu-armv8-ndebug"
+  }
+}
+job {
   id: "qemu-riscv64-ndebug"
   realm: "ci"
   acl_sets: "ci"
@@ -278,6 +288,7 @@
   triggers: "host-x86_64-ndebug"
   triggers: "host-x86_64-non-gen-cc"
   triggers: "host-x86_64-poison-debug"
+  triggers: "qemu-armv8-ndebug"
   triggers: "qemu-riscv64-ndebug"
   triggers: "qemu-riscv64-ndebug-build_only"
   triggers: "walleye-armv7-poison-debug"
@@ -312,6 +323,7 @@
   triggers: "host-x86_64-ndebug"
   triggers: "host-x86_64-non-gen-cc"
   triggers: "host-x86_64-poison-debug"
+  triggers: "qemu-armv8-ndebug"
   triggers: "qemu-riscv64-ndebug"
   triggers: "qemu-riscv64-ndebug-build_only"
   triggers: "walleye-armv7-poison-debug"
@@ -346,6 +358,7 @@
   triggers: "host-x86_64-ndebug"
   triggers: "host-x86_64-non-gen-cc"
   triggers: "host-x86_64-poison-debug"
+  triggers: "qemu-armv8-ndebug"
   triggers: "qemu-riscv64-ndebug"
   triggers: "qemu-riscv64-ndebug-build_only"
   triggers: "walleye-armv7-poison-debug"
@@ -380,6 +393,7 @@
   triggers: "host-x86_64-ndebug"
   triggers: "host-x86_64-non-gen-cc"
   triggers: "host-x86_64-poison-debug"
+  triggers: "qemu-armv8-ndebug"
   triggers: "qemu-riscv64-ndebug"
   triggers: "qemu-riscv64-ndebug-build_only"
   triggers: "walleye-armv7-poison-debug"
diff --git a/tools/luci/config/generated/project.cfg b/tools/luci/config/generated/project.cfg
index 584e84f..d517637 100644
--- a/tools/luci/config/generated/project.cfg
+++ b/tools/luci/config/generated/project.cfg
@@ -2,12 +2,12 @@
 # Do not modify manually.
 #
 # For the schema of this file, see ProjectCfg message:
-#   https://luci-config.appspot.com/schemas/projects:project.cfg
+#   https://config.luci.app/schemas/projects:project.cfg
 
 name: "art"
 access: "group:all"
 lucicfg {
-  version: "1.38.1"
+  version: "1.43.4"
   package_dir: ".."
   config_dir: "generated"
   entry_point: "main.star"
diff --git a/tools/luci/config/generated/realms.cfg b/tools/luci/config/generated/realms.cfg
index 777f868..c453176 100644
--- a/tools/luci/config/generated/realms.cfg
+++ b/tools/luci/config/generated/realms.cfg
@@ -2,7 +2,7 @@
 # Do not modify manually.
 #
 # For the schema of this file, see RealmsCfg message:
-#   https://luci-config.appspot.com/schemas/projects:realms.cfg
+#   https://config.luci.app/schemas/projects:realms.cfg
 
 realms {
   name: "@root"
diff --git a/tools/luci/config/main.star b/tools/luci/config/main.star
index af746d6..aa5dcd5 100755
--- a/tools/luci/config/main.star
+++ b/tools/luci/config/main.star
@@ -465,6 +465,18 @@
         }
     )
     ci_builder(
+        name="qemu-armv8-ndebug",
+        category="qemu|armv8",
+        short_name="ndbg",
+        dimensions=host_dims,
+        is_fyi=True,
+        properties={
+            "debug": False,
+            "device": "qemu-armv8",
+            "on_virtual_machine": True,
+        }
+    )
+    ci_builder(
         name="qemu-riscv64-ndebug",
         category="qemu|riscv64",
         short_name="ndbg",