https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115961
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Li Pan from comment #3) > Only x86 implemented the .SAT_TRUNC for scalar, so I bet it is almost the > same as this https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115863 ? No it is a different issue. here we have a uint:4; an unsigned integer with 4 bit precision which is not the same precision as QImode (8bit). Since the optabs are only mode, we only check the mode of the type which is QImode but the type has a lower precision than the mode itself. So we get a SAT_TRUNC which is using the QImode sat_truncate opcode but we really need 4bit sat_truncate. This is why I mentioned there is a missing check for type_has_mode_precision_p here. type_has_mode_precision_p is defined as: ``` inline bool type_has_mode_precision_p (const_tree t) { return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t))); } ``` I wonder if we have the same issue with some other direct calls internal functions too. But I have not looked into others that is accessible except for __builtin_clzg which always does the right thing.