diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 0d7b9afab5ee4..42d9b519c147f 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -546,8 +546,20 @@ fn encode_ty<'tcx>(
             if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) {
                 // Use user-defined CFI encoding for type
                 if let Some(value_str) = cfi_encoding.value_str() {
-                    if !value_str.to_string().trim().is_empty() {
-                        s.push_str(value_str.to_string().trim());
+                    let value_str = value_str.to_string();
+                    let str = value_str.trim();
+                    if !str.is_empty() {
+                        s.push_str(str);
+                        // Don't compress user-defined builtin types (see
+                        // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
+                        // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
+                        let builtin_types = [
+                            "v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y",
+                            "n", "o", "f", "d", "e", "g", "z",
+                        ];
+                        if !builtin_types.contains(&str) {
+                            compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
+                        }
                     } else {
                         #[allow(
                             rustc::diagnostic_outside_of_impl,
@@ -563,7 +575,6 @@ fn encode_ty<'tcx>(
                 } else {
                     bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
                 }
-                compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             } else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() {
                 // For cross-language LLVM CFI support, the encoding must be compatible at the FFI
                 // boundary. For instance:
diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
index f15ca30b7e362..be4af9b7962d7 100644
--- a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
+++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
@@ -18,6 +18,13 @@ extern {
 #[repr(transparent)]
 pub struct Type3(i32);
 
+#[cfi_encoding = "i"]
+pub struct Type4(i32);
+
+#[cfi_encoding = "j"]
+#[repr(transparent)]
+pub struct Type5(u32);
+
 pub fn foo0(_: Type1) { }
 // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 pub fn foo1(_: Type1, _: Type1) { }
@@ -36,6 +43,18 @@ pub fn foo7(_: *mut Type3, _: *mut Type3) { }
 // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { }
 // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo9(_: Type4) { }
+// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo10(_: Type4, _: Type4) { }
+// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo11(_: Type4, _: Type4, _: Type4) { }
+// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo12(_: Type5) { }
+// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo13(_: Type5, _: Type5) { }
+// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo14(_: Type5, _: Type5, _: Type5) { }
+// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 
 // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFv3FooE"}
 // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFv3FooS_E"}
@@ -46,3 +65,9 @@ pub fn foo8(_: *mut Type3, _: *mut Type3, _: *mut Type3) { }
 // CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvP3BazE"}
 // CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvP3BazS0_E"}
 // CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvP3BazS0_S0_E"}
+// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFviE"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFviiE"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFviiiE"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvjE"}
+// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvjjE"}
+// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvjjjE"}