https://gcc.gnu.org/g:ec363f20c06bd7c978a203279cff0daf37394fc7

commit ec363f20c06bd7c978a203279cff0daf37394fc7
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Tue Mar 4 21:00:06 2025 +0100

    Ajout support TARGET_MEM_REF

Diff:
---
 gcc/cgraphunit.cc | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 264 insertions(+), 7 deletions(-)

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index a97fbec407c6..f29e9aa846b8 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -3366,6 +3366,9 @@ data_value::get_at (unsigned offset, unsigned width) const
       result.set_address (*get_address_at (offset));
       break;
 
+    case VAL_UNDEFINED:
+      break;
+
     default:
       gcc_unreachable ();
     }
@@ -3675,6 +3678,7 @@ exec_context::evaluate (tree expr) const
       break;
 
     case MEM_REF:
+    case TARGET_MEM_REF:
       {
        tree ptr = TREE_OPERAND (expr, 0);
        data_value val_ptr = evaluate (ptr);
@@ -3686,7 +3690,7 @@ exec_context::evaluate (tree expr) const
        tree offset_bytes = TREE_OPERAND (expr, 1);
        data_value val_off = evaluate (offset_bytes);
        gcc_assert (val_off.classify () == VAL_CONSTANT);
-       wide_int wi_off = val_off.get_cst () * CHAR_BIT;
+       wide_int wi_off = val_off.get_cst ();
        gcc_assert (wi::fits_uhwi_p (wi_off));
        unsigned offset = wi_off.to_uhwi ();
 
@@ -3694,7 +3698,24 @@ exec_context::evaluate (tree expr) const
        if (!get_constant_type_size (TREE_TYPE (expr), bit_width))
          gcc_unreachable ();
 
-       return storage_value.get_at (offset, bit_width);
+       if (code == TARGET_MEM_REF)
+         {
+           tree index = TREE_OPERAND (expr, 2);
+           data_value val_idx = evaluate (index);
+           gcc_assert (val_idx.classify () == VAL_CONSTANT);
+           wide_int wi_idx = val_idx.get_cst ();
+
+           tree step = TREE_OPERAND (expr, 3);
+           data_value val_step = evaluate (step);
+           gcc_assert (val_step.classify () == VAL_CONSTANT);
+           wide_int wi_step = val_step.get_cst ();
+
+           wide_int additional_off = wi_idx * wi_step;
+           gcc_assert (wi::fits_uhwi_p (additional_off));
+           offset += additional_off.to_uhwi ();
+         }
+
+       return storage_value.get_at (offset * CHAR_BIT, bit_width);
       }
       break;
 
@@ -3852,7 +3873,8 @@ void
 exec_context::decompose_ref (tree data_ref, data_storage * & storage, int & 
offset) const
 {
   offset = -1;
-  switch (TREE_CODE (data_ref))
+  enum tree_code code = TREE_CODE (data_ref);
+  switch (code)
     {
     case VAR_DECL:
     case SSA_NAME:
@@ -3908,6 +3930,7 @@ exec_context::decompose_ref (tree data_ref, data_storage 
* & storage, int & offs
       break;
 
     case MEM_REF:
+    case TARGET_MEM_REF:
       {
        tree var = TREE_OPERAND (data_ref, 0);
        data_value addr = evaluate (var);
@@ -3920,6 +3943,24 @@ exec_context::decompose_ref (tree data_ref, data_storage 
* & storage, int & offs
        wide_int wi_off = off_val.get_cst ();
        gcc_assert (wi::fits_uhwi_p (wi_off));
        unsigned HOST_WIDE_INT uhwi_off = wi_off.to_uhwi ();
+
+       if (code == TARGET_MEM_REF)
+         {
+           tree index = TREE_OPERAND (data_ref, 2);
+           data_value idx_val = evaluate (index);
+           gcc_assert (idx_val.classify () == VAL_CONSTANT);
+           wide_int wi_idx = idx_val.get_cst ();
+
+           tree step = TREE_OPERAND (data_ref, 3);
+           data_value step_val = evaluate (step);
+           gcc_assert (step_val.classify () == VAL_CONSTANT);
+           wide_int wi_step = step_val.get_cst ();
+
+           wide_int additional_off = wi_idx * wi_step;
+           gcc_assert (wi::fits_uhwi_p (additional_off));
+           uhwi_off += additional_off.to_uhwi ();
+         }
+
        gcc_assert (uhwi_off <= UINT_MAX / CHAR_BIT);
        offset = uhwi_off * CHAR_BIT;
       }
@@ -3937,10 +3978,6 @@ void
 exec_context::execute_assign (gassign *g)
 {
   tree lhs = gimple_assign_lhs (g);
-  gcc_assert (TREE_CODE (lhs) == MEM_REF
-             || TREE_CODE (lhs) == SSA_NAME
-             || TREE_CODE (lhs) == VAR_DECL
-             || TREE_CODE (lhs) == COMPONENT_REF);
   tree lhs_type = TREE_TYPE (lhs);
   data_value value (lhs_type);
 
@@ -5933,6 +5970,112 @@ exec_context_evaluate_tests ()
   wide_int wi_val6 = eval6.get_cst ();
   ASSERT_PRED1 (wi::fits_shwi_p, wi_val6);
   ASSERT_EQ (wi_val6.to_shwi (), 8);
+
+
+  tree c29 = build_array_type_nelts (char_type_node, 29);
+  tree a29 = create_var (c29, "a29");
+  tree ssa8 = make_node (SSA_NAME);
+  TREE_TYPE (ssa8) = size_type_node;
+  tree ssa9 = make_node (SSA_NAME);
+  TREE_TYPE (ssa9) = size_type_node;
+
+  vec<tree> decls8{};
+  decls8.safe_push (a29);
+  decls8.safe_push (ssa8);
+  decls8.safe_push (ssa9);
+
+  context_builder builder8;
+  builder8.add_decls (&decls8);
+  exec_context ctx8 = builder8.build (mem, printer);
+
+  data_storage * strg29 = ctx8.find_reachable_var (a29);
+  gcc_assert (strg29 != nullptr);
+
+  tree ref0 = build5 (TARGET_MEM_REF, char_type_node,
+                    build1 (ADDR_EXPR, ptr_type_node, a29),
+                    build_zero_cst (ptr_type_node),
+                    size_zero_node, size_zero_node, NULL_TREE);
+
+  wide_int cst21 = wi::shwi (21, CHAR_BIT);
+  data_value tmp29_0 (CHAR_BIT);
+  tmp29_0.set_cst (cst21);
+  strg29->set_at (tmp29_0, 0);
+
+  data_value val29_0 = ctx8.evaluate (ref0);
+
+  ASSERT_EQ (val29_0.get_bitwidth (), CHAR_BIT);
+  ASSERT_EQ (val29_0.classify (), VAL_CONSTANT);
+  wide_int wi29_0 = val29_0.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_0);
+  ASSERT_EQ  (wi29_0.to_uhwi (), 21);
+
+  tree ref3 = build5 (TARGET_MEM_REF, char_type_node,
+                    build1 (ADDR_EXPR, ptr_type_node, a29),
+                    build_int_cst (ptr_type_node, 3),
+                    size_zero_node, size_zero_node, NULL_TREE);
+
+  wide_int cst26 = wi::shwi (26, CHAR_BIT);
+  data_value tmp29_3 (CHAR_BIT);
+  tmp29_3.set_cst (cst26);
+  strg29->set_at (tmp29_3, 24);
+
+  data_value val29_3 = ctx8.evaluate (ref3);
+
+  ASSERT_EQ (val29_3.get_bitwidth (), CHAR_BIT);
+  ASSERT_EQ (val29_3.classify (), VAL_CONSTANT);
+  wide_int wi29_3 = val29_3.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_3);
+  ASSERT_EQ  (wi29_3.to_uhwi (), 26);
+
+  tree ref12 = build5 (TARGET_MEM_REF, char_type_node,
+                      build1 (ADDR_EXPR, ptr_type_node, a29),
+                      build_zero_cst (ptr_type_node),
+                      ssa8, build_int_cst (size_type_node, 4), NULL_TREE);
+
+  wide_int cst17 = wi::shwi (17, CHAR_BIT);
+  data_value tmp29_12 (CHAR_BIT);
+  tmp29_12.set_cst (cst17);
+  strg29->set_at (tmp29_12, 96);
+
+  wide_int cst3_bis = wi::shwi (3, sizeof (size_t) * CHAR_BIT);
+  data_value val3_bis (sizeof (size_t) * CHAR_BIT);
+  val3_bis.set_cst (cst3_bis);
+  data_storage * ssa8_strg = ctx8.find_reachable_var (ssa8);
+  gcc_assert (ssa8_strg != nullptr);
+  ssa8_strg->set (val3_bis);
+
+  data_value val29_12 = ctx8.evaluate (ref12);
+
+  ASSERT_EQ (val29_12.get_bitwidth (), CHAR_BIT);
+  ASSERT_EQ (val29_12.classify (), VAL_CONSTANT);
+  wide_int wi29_12 = val29_12.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_12);
+  ASSERT_EQ  (wi29_12.to_uhwi (), 17);
+
+  tree ref27 = build5 (TARGET_MEM_REF, char_type_node,
+                      build1 (ADDR_EXPR, ptr_type_node, a29),
+                      build_int_cst (ptr_type_node, 7),
+                      ssa9, build_int_cst (size_type_node, 4), NULL_TREE);
+
+  wide_int cst14_bis = wi::shwi (14, CHAR_BIT);
+  data_value tmp29_27 (CHAR_BIT);
+  tmp29_27.set_cst (cst14_bis);
+  strg29->set_at (tmp29_27, 216);
+
+  wide_int cst5 = wi::shwi (5, sizeof (size_t) * CHAR_BIT);
+  data_value val5_bis (sizeof (size_t) * CHAR_BIT);
+  val5_bis.set_cst (cst5);
+  data_storage * ssa9_strg = ctx8.find_reachable_var (ssa9);
+  gcc_assert (ssa9_strg != nullptr);
+  ssa9_strg->set (val5_bis);
+
+  data_value val29_27 = ctx8.evaluate (ref27);
+
+  ASSERT_EQ (val29_27.get_bitwidth (), CHAR_BIT);
+  ASSERT_EQ (val29_27.classify (), VAL_CONSTANT);
+  wide_int wi29_27 = val29_27.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_27);
+  ASSERT_EQ  (wi29_27.to_uhwi (), 14);
 }
 
 
@@ -6381,6 +6524,120 @@ exec_context_execute_assign_tests ()
   wide_int x_val = x_after.get_cst ();
   ASSERT_PRED1 (wi::fits_shwi_p, x_val);
   ASSERT_EQ (x_val.to_shwi (), 5);
+
+
+  tree c29 = build_array_type_nelts (char_type_node, 29);
+  tree a29 = create_var (c29, "a29");
+  tree ssa8 = make_node (SSA_NAME);
+  TREE_TYPE (ssa8) = size_type_node;
+  tree ssa9 = make_node (SSA_NAME);
+  TREE_TYPE (ssa9) = size_type_node;
+
+  vec<tree> decls8{};
+  decls8.safe_push (a29);
+  decls8.safe_push (ssa8);
+  decls8.safe_push (ssa9);
+
+  context_builder builder8;
+  builder8.add_decls (&decls8);
+  exec_context ctx8 = builder8.build (mem, printer);
+
+  data_storage * strg29 = ctx8.find_reachable_var (a29);
+  gcc_assert (strg29 != nullptr);
+
+  tree ref0 = build5 (TARGET_MEM_REF, char_type_node,
+                    build1 (ADDR_EXPR, ptr_type_node, a29),
+                    build_zero_cst (ptr_type_node),
+                    size_zero_node, size_zero_node, NULL_TREE);
+  tree cst21 = build_int_cst (char_type_node, 21);
+  gassign * assign29_0 = gimple_build_assign (ref0, cst21);
+
+  data_value val29_before0 = strg29->get_value ();
+  data_value val0_before = val29_before0.get_at (0, CHAR_BIT);
+  ASSERT_EQ (val0_before.classify (), VAL_UNDEFINED);
+
+  ctx8.execute (assign29_0);
+
+  data_value val29_after0 = strg29->get_value ();
+  data_value val0_after = val29_after0.get_at (0, CHAR_BIT);
+  ASSERT_EQ (val0_after.classify (), VAL_CONSTANT);
+  wide_int wi29_0 = val0_after.get_cst_at (0, CHAR_BIT);
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_0);
+  ASSERT_EQ  (wi29_0.to_uhwi (), 21);
+
+  tree ref3 = build5 (TARGET_MEM_REF, char_type_node,
+                    build1 (ADDR_EXPR, ptr_type_node, a29),
+                    build_int_cst (ptr_type_node, 3),
+                    size_zero_node, size_zero_node, NULL_TREE);
+  tree cst26 = build_int_cst (char_type_node, 26);
+  gassign * assign29_3 = gimple_build_assign (ref3, cst26);
+
+  data_value val29_before3 = strg29->get_value ();
+  data_value val3_before = val29_before3.get_at (24, CHAR_BIT);
+  ASSERT_EQ (val3_before.classify (), VAL_UNDEFINED);
+
+  ctx8.execute (assign29_3);
+
+  data_value val29_after3 = strg29->get_value ();
+  data_value val3_after = val29_after3.get_at (24, CHAR_BIT);
+  ASSERT_EQ (val3_after.classify (), VAL_CONSTANT);
+  wide_int wi29_3 = val3_after.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_3);
+  ASSERT_EQ  (wi29_3.to_uhwi (), 26);
+
+  tree ref12 = build5 (TARGET_MEM_REF, char_type_node,
+                      build1 (ADDR_EXPR, ptr_type_node, a29),
+                      build_zero_cst (ptr_type_node),
+                      ssa8, build_int_cst (size_type_node, 4), NULL_TREE);
+  tree cst17 = build_int_cst (char_type_node, 17);
+  gassign * assign29_12 = gimple_build_assign (ref12, cst17);
+
+  wide_int cst3_bis = wi::shwi (3, sizeof (size_t) * CHAR_BIT);
+  data_value val3_bis (sizeof (size_t) * CHAR_BIT);
+  val3_bis.set_cst (cst3_bis);
+  data_storage * ssa8_strg = ctx8.find_reachable_var (ssa8);
+  gcc_assert (ssa8_strg != nullptr);
+  ssa8_strg->set (val3_bis);
+
+  data_value val29_before12 = strg29->get_value ();
+  data_value val12_before = val29_before12.get_at (96, CHAR_BIT);
+  ASSERT_EQ (val12_before.classify (), VAL_UNDEFINED);
+
+  ctx8.execute (assign29_12);
+
+  data_value val29_after12 = strg29->get_value ();
+  data_value val12_after = val29_after12.get_at (96, CHAR_BIT);
+  ASSERT_EQ (val12_after.classify (), VAL_CONSTANT);
+  wide_int wi29_12 = val12_after.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_12);
+  ASSERT_EQ  (wi29_12.to_uhwi (), 17);
+
+  tree ref27 = build5 (TARGET_MEM_REF, char_type_node,
+                      build1 (ADDR_EXPR, ptr_type_node, a29),
+                      build_int_cst (ptr_type_node, 7),
+                      ssa9, build_int_cst (size_type_node, 4), NULL_TREE);
+  tree cst14 = build_int_cst (char_type_node, 14);
+  gassign * assign29_27 = gimple_build_assign (ref27, cst14);
+
+  wide_int cst5 = wi::shwi (5, sizeof (size_t) * CHAR_BIT);
+  data_value val5_bis (sizeof (size_t) * CHAR_BIT);
+  val5_bis.set_cst (cst5);
+  data_storage * ssa9_strg = ctx8.find_reachable_var (ssa9);
+  gcc_assert (ssa9_strg != nullptr);
+  ssa9_strg->set (val5_bis);
+
+  data_value val29_before27 = strg29->get_value ();
+  data_value val27_before = val29_before27.get_at (216, CHAR_BIT);
+  ASSERT_EQ (val27_before.classify (), VAL_UNDEFINED);
+
+  ctx8.execute (assign29_27);
+
+  data_value val29_after27 = strg29->get_value ();
+  data_value val27_after = val29_after27.get_at (216, CHAR_BIT);
+  ASSERT_EQ (val27_after.classify (), VAL_CONSTANT);
+  wide_int wi29_27 = val27_after.get_cst ();
+  ASSERT_PRED1 (wi::fits_uhwi_p, wi29_27);
+  ASSERT_EQ  (wi29_27.to_uhwi (), 14);
 }
 
 void

Reply via email to