--- a/gcc/tree-vect-patterns.cc	2026-08-31 17:12:13.972850769 +0200
+++ b/gcc/tree-vect-patterns.cc	2026-09-01 12:42:48.214480599 +0200
@@ -2318,6 +2318,17 @@ vect_recog_popcount_clz_ctz_ffs_pattern
   vect_pattern_detected ("vec_recog_popcount_clz_ctz_ffs_pattern",
 			 call_stmt);
 
+  tree orig_lhs_type = lhs_type;
+  gimple *cast_stmt = NULL;
+  if (!type_has_mode_precision_p (lhs_type))
+    {
+      lhs_type = TREE_TYPE (vec_type);
+      cast_stmt
+	= gimple_build_assign (vect_recog_temp_ssa_var (lhs_type, NULL),
+			       NOP_EXPR, unprom_diff.op);
+      unprom_diff.op = gimple_assign_lhs (cast_stmt);
+    }
+
   /* Create B = .POPCOUNT (A).  */
   new_var = vect_recog_temp_ssa_var (lhs_type, NULL);
   tree arg2 = NULL_TREE;
@@ -2358,12 +2369,24 @@ vect_recog_popcount_clz_ctz_ffs_pattern
 	= vect_recog_ctz_ffs_pattern (vinfo, new_stmt_info, type_out);
       if (pattern_stmt == NULL)
 	return NULL;
+      if (cast_stmt)
+	append_pattern_def_seq (vinfo, stmt_vinfo, cast_stmt, vec_type);
       if (gimple_seq seq = STMT_VINFO_PATTERN_DEF_SEQ (new_stmt_info))
 	{
 	  gimple_seq *pseq = &STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo);
 	  gimple_seq_add_seq_without_update (pseq, seq);
 	}
     }
+  else if (cast_stmt)
+    append_pattern_def_seq (vinfo, stmt_vinfo, cast_stmt, vec_type);
+
+  if (cast_stmt)
+    {
+      append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, vec_type);
+      tree ret_var = vect_recog_temp_ssa_var (orig_lhs_type, NULL);
+      pattern_stmt = gimple_build_assign (ret_var, NOP_EXPR,
+					  gimple_get_lhs (pattern_stmt));
+    }
   return pattern_stmt;
 }
 
--- a/gcc/testsuite/gcc.dg/bitint-142.c	2026-09-01 12:51:40.839450937 +0200
+++ b/gcc/testsuite/gcc.dg/bitint-142.c	2026-09-01 12:51:21.346708207 +0200
@@ -0,0 +1,38 @@
+/* PR tree-optimization/127149 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-O3" } */
+
+typedef unsigned _BitInt(7) B;
+
+[[gnu::noipa]] void
+foo (B *restrict y, const B *restrict x)
+{
+  for (unsigned i = 0; i < 16; ++i)
+    y[i] = __builtin_popcountg (x[i]);
+}
+
+[[gnu::noipa]] void
+bar (B *restrict y, const B *restrict x)
+{
+  for (unsigned i = 0; i < 16; ++i)
+    y[i] = __builtin_ctzg (x[i], 8);
+}
+
+int
+main ()
+{
+  B x[16], y[16], z, w[16];
+  B e[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+  B f[16] = { 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
+  for (unsigned i = 0; i < 16; ++i)
+    x[i] = i;
+  z = ~0;
+  __builtin_clear_padding (&z);
+  for (unsigned i = 0; i < 16; ++i)
+    ((unsigned char *) &x[0])[i] |= ~*(unsigned char *) &z;
+  foo (y, x);
+  bar (w, x);
+  for (unsigned i = 0; i < 16; ++i)
+    if (y[i] != e[i] || w[i] != f[i])
+    __builtin_abort ();
+}
