#include "gomp-constants.h"
#include "omp-general.h"
#include "tree-dfa.h"
+#include "gimple-ssa.h"
+#include "tree-ssa-live.h"
+#include "tree-outof-ssa.h"
struct target_builtins default_target_builtins;
#if SWITCHABLE_TARGET
rtx val;
machine_mode old_mode;
+ if (TREE_CODE (exp) == SSA_NAME
+ && TYPE_MODE (TREE_TYPE (exp)) != mode)
+ {
+ /* Undo argument promotion if possible, as combine might not
+ be able to do it later due to MEM_VOLATILE_P uses in the
+ patterns. */
+ gimple *g = get_gimple_for_ssa_name (exp);
+ if (g && gimple_assign_cast_p (g))
+ {
+ tree rhs = gimple_assign_rhs1 (g);
+ tree_code code = gimple_assign_rhs_code (g);
+ if (CONVERT_EXPR_CODE_P (code)
+ && TYPE_MODE (TREE_TYPE (rhs)) == mode
+ && INTEGRAL_TYPE_P (TREE_TYPE (exp))
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
+ && (TYPE_PRECISION (TREE_TYPE (exp))
+ > TYPE_PRECISION (TREE_TYPE (rhs))))
+ exp = rhs;
+ }
+ }
+
val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
/* If VAL is promoted to a wider mode, convert it back to MODE. Take care
of CONST_INTs, where we know the old_mode only from the call argument. */
--- /dev/null
+/* PR target/96176 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "\tmovzbl\t" } } */
+
+unsigned char v;
+
+void
+foo (unsigned char *x, unsigned char y, unsigned char z)
+{
+ __atomic_compare_exchange_n (x, &y, z, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ v = y;
+}