https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80880
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- (gdb) p debug_generic_expr (exp) __builtin_ia32_bndret (0B) And sinking does: Sinking __bound_tmp.0_3 = __builtin_ia32_bndret (_2); from bb 2 to bb 3 int* fn1.chkp() () { __bounds_type __bound_tmp.0; int * _2; <bb 2> [100.00%]: _2 = fn1.chkp (); if (_2 == 0B) goto <bb 3>; [33.47%] else goto <bb 4>; [66.53%] <bb 3> [33.47%]: __bound_tmp.0_3 = __builtin_ia32_bndret (_2); return 0B, __bound_tmp.0_3; <bb 4> [66.53%]: return; nothing wrong with that. Now we can do the conditional replacement of _2 with 0. Thus expansion issue. We absolutely need to deal with constant pointers here, even if just in a conservative way. chkp_get_rtl_bounds suggests that returning NULL_RTX is ok thus @@ -37584,8 +37601,10 @@ ix86_expand_builtin (tree exp, rtx targe case IX86_BUILTIN_BNDRET: arg0 = CALL_EXPR_ARG (exp, 0); - gcc_assert (TREE_CODE (arg0) == SSA_NAME); - target = chkp_get_rtl_bounds (arg0); + if (TREE_CODE (arg0) == SSA_NAME) + target = chkp_get_rtl_bounds (arg0); + else + target = NULL; /* If no bounds were specified for returned value, then use INIT bounds. It usually happens when or simply adjust chkp_get_rtl_bounds as there seems to be a single caller only.