On Mon, Apr 28, 2025 at 2:56 PM Qing Zhao <qing.z...@oracle.com> wrote:
>
>
>
> > On Apr 28, 2025, at 06:49, Richard Biener <richard.guent...@gmail.com> 
> > wrote:
> >
> > On Wed, Apr 23, 2025 at 6:09 PM Qing Zhao <qing.z...@oracle.com> wrote:
> >>
> >> Richard,
> >>
> >> Thanks a lot for the hint.
> >>
> >>> On Apr 23, 2025, at 04:17, Richard Biener <richard.guent...@gmail.com> 
> >>> wrote:
> >>>
> >>>> I have met the following issue when I tried to implement the following 
> >>>> into tree-object-size.cc:
> >>>> (And this took me quite some time, still don’t know what’s the best 
> >>>> solution)
> >>>>
> >>>>> On Apr 16, 2025, at 10:46, Qing Zhao <qing.z...@oracle.com> wrote:
> >>>>>
> >>>>> 3. When generating the reference to the field member in 
> >>>>> tree-object-size, we should guard this reference with a checking
> >>>>>  on the pointer to the structure is valid. i.e:
> >>>>>
> >>>>> struct annotated {
> >>>>> size_t count;
> >>>>> char array[] __attribute__((counted_by (count)));
> >>>>> };
> >>>>>
> >>>>> static size_t __attribute__((__noinline__)) size_of (struct annotated * 
> >>>>> obj)
> >>>>> {
> >>>>> return __builtin_dynamic_object_size (obj, 1);
> >>>>> }
> >>>>>
> >>>>> When we try to generate the reference to obj->count when evaluating 
> >>>>> __builtin_dynamic_object_size (obj, 1),
> >>>>> We should generate the following:
> >>>>>
> >>>>> If (obj != NULL)
> >>>>>   * (&obj->count)
> >>>>>
> >>>>> To make sure that the pointer to the structure object is valid first.
> >>>>>
> >>>>
> >>>> Then as I generate the following size_expr in tree-object-size.cc:
> >>>>
> >>>> Breakpoint 1, gimplify_size_expressions (osi=0xffffffffdf30)
> >>>>   at ../../latest-gcc-write/gcc/tree-object-size.cc:1178
> >>>> 1178       force_gimple_operand (size_expr, &seq, true, NULL);
> >>>> (gdb) call debug_generic_expr(size_expr)
> >>>> _4 = obj_2(D) != 0B ? (sizetype) (int) MAX_EXPR <(sizetype) MAX_EXPR 
> >>>> <MEM <int> [(void *)&*obj_2(D)], 0> + 4, 4> : 18446744073709551615
> >>>>
> >>>> When calling “force_gimple_operand” for the above size_expr, I got the 
> >>>> following ICE in gimplify_modify_expr, at gimplify.cc:7505:
> >>>
> >>> You shouldn't really force_gimple_operand to a MODIFY_EXPR but instead
> >>> only to its RHS.
> >>
> >> Do you mean: instead of
> >>
> >> force_gimple_operand (size_expr, &seq, true, NULL);
> >>
> >> I should
> >>
> >> 1178               if (TREE_CODE (size_expr) == MODIFY_EXPR)
> >> 1179                 {
> >> 1180                   tree rhs = TREE_OPERAND (size_expr, 1);
> >> 1181                   force_gimple_operand (rhs, &seq, true, NULL);
> >> 1182                 }
> >>
> >> ?
> >>
> >> However, with this change, I got the exactly same error at the above line 
> >> 1181.
> >> (gdb) call debug_generic_expr(rhs)
> >> obj_2(D) != 0B ? (sizetype) (int) MAX_EXPR <(sizetype) MAX_EXPR <MEM <int> 
> >> [(void *)&*obj_2(D)], 0> + 4, 4> : 18446744073709551615
> >>
> >> The issue is still the same as before.
> >> So, I am wondering whether the above size expression I generated has some 
> >> issue?
> >> Or the routine “force_gimple_operand” has some bug  when the tree expr is 
> >> a COND_EXPR expression?
> >
> > Well, one issue is that the true case can trap while the false case
> > does not, and force_gimple_operand
> > cannot create a CFG to preserve the conditional execution.  If that's
> > not an issue you need to
> > create the COND_EXPR in gimple form from the start and not try to do
> > easy by going though
> > gimpification.
>
> Okay, so, I need to create the following:
>
> If (obj  != NULL)
>   size = (sizetype) (int) MAX_EXPR <(sizetype) MAX_EXPR <MEM <int> [(void 
> *)&*obj_2(D)], 0> + 4, 4>
> else
>   size = -1;
>
> Directly in gimple form and insert it to the control flow of the routine.

I guess so.

> Is there a similar example in gcc source code I can take a look at?

I think the sanitizers insert control flow, the profiling code definitely does.

> Thanks a lot.
>
> Qing
>
> > Richard.
> >
> >>
> >> Thanks.
> >>
> >> Qing
> >>
> >> The size_expr is a COND_EXPR:
> >>
> >> (gdb) call debug_tree(rhs)
> >> <cond_expr 0x7fffea281e10
> >>    type <integer_type 0x7fffea282000 sizetype public unsigned DI
> >>        size <integer_cst 0x7fffea262f60 constant 64>
> >>        unit-size <integer_cst 0x7fffea262f78 constant 8>
> >>        align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
> >> 0x7fffea282000 precision:64 min <integer_cst 0x7fffea262f90 0> max 
> >> <integer_cst 0x7fffea263640 18446744073709551615>>
> >>
> >>    arg:0 <ne_expr 0x7fffea0cd0f0
> >>        type <boolean_type 0x7fffea282b28 _Bool public unsigned QI
> >>            size <integer_cst 0x7fffea284060 constant 8>
> >>            unit-size <integer_cst 0x7fffea284078 constant 1>
> >>            align:8 warn_if_not_align:0 symtab:0 alias-set -1 
> >> canonical-type 0x7fffea282b28 precision:1 min <integer_cst 0x7fffea2842b8 
> >> 0> max <integer_cst 0x7fffea2842e8 1>>
> >>                arg:0 <ssa_name 0x7fffea26d9d8 type <pointer_type 
> >> 0x7fffea0bc7e0>
> >>            visited var <parm_decl 0x7fffea0bb440 obj>
> >>            def_stmt GIMPLE_NOP
> >>            version:2
> >>            ptr-info 0x7fffea091918>
> >>        arg:1 <integer_cst 0x7fffea091780 constant 0>>
> >>    arg:1 <nop_expr 0x7fffea0c2680 type <integer_type 0x7fffea282000 
> >> sizetype>
> >>                arg:0 <nop_expr 0x7fffea0c2660 type <integer_type 
> >> 0x7fffea2825e8 int>
> >>                        arg:0 <max_expr 0x7fffea0cd0a0 type <integer_type 
> >> 0x7fffea282000 sizetype>
> >>                                arg:0 <plus_expr 0x7fffea0cd078 type 
> >> <integer_type 0x7fffea282000 sizetype>
> >>                                        arg:0 <nop_expr 0x7fffea0c2640 type 
> >> <integer_type 0x7fffea282000 sizetype>
> >>                                                arg:0 <max_expr 
> >> 0x7fffea0cd050 type <integer_type 0x7fffea2825e8 int>
> >>                            arg:0 <mem_ref 0x7fffea0cd000> arg:1 
> >> <integer_cst 0x7fffea284300 0>>>
> >>                    arg:1 <integer_cst 0x7fffea2841c8 constant 4>> arg:1 
> >> <integer_cst 0x7fffea2841c8 4>>>>
> >>    arg:2 <integer_cst 0x7fffea263640 type <integer_type 0x7fffea282000 
> >> sizetype> constant 18446744073709551615>>
> >>
> >>>
> >>>> (gdb) c
> >>>> Continuing.
> >>>> during GIMPLE pass: objsz
> >>>> dump file: a-t.c.110t.objsz1
> >>>> In function ‘size_of’:
> >>>> cc1: internal compiler error: in gimplify_modify_expr, at 
> >>>> gimplify.cc:7505
> >>>> 0x36feb67 internal_error(char const*, ...)
> >>>> ../../latest-gcc-write/gcc/diagnostic-global-context.cc:517
> >>>> 0x36ccd67 fancy_abort(char const*, int, char const*)
> >>>> ../../latest-gcc-write/gcc/diagnostic.cc:1749
> >>>> 0x14fa8ab gimplify_modify_expr
> >>>> ../../latest-gcc-write/gcc/gimplify.cc:7505
> >>>> 0x15354c3 gimplify_expr(tree_node**, gimple**, gimple**, bool 
> >>>> (*)(tree_node*), int)
> >>>> ../../latest-gcc-write/gcc/gimplify.cc:19530
> >>>> 0x14fe1b3 gimplify_stmt(tree_node**, gimple**)
> >>>> ../../latest-gcc-write/gcc/gimplify.cc:8458
> >>>> ….
> >>>> 0x1b07757 gimplify_size_expressions
> >>>> ../../latest-gcc-write/gcc/tree-object-size.cc:1178
> >>>>
> >>>> I debugged into this a little bit, and found that the following are the 
> >>>> reason for the assertion failure in the routine “gimplify_modify_expr” 
> >>>> of gimplify.cc:
> >>>>
> >>>> 1. The assertion failure is:
> >>>>
> >>>> 7502   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
> >>>> 7503     {
> >>>> 7504       /* We should have got an SSA name from the start.  */
> >>>> 7505       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
> >>>> 7506                   || ! gimple_in_ssa_p (cfun));
> >>>> 7507     }
> >>>>
> >>>> 2. The above assertion failure is issued for the following temporary 
> >>>> tree:
> >>>>
> >>>> (gdb) call debug_generic_expr(*to_p)
> >>>> iftmp.2
> >>>> (gdb) call debug_generic_expr(*expr_p)
> >>>> iftmp.2 = (sizetype) _10
> >>>>
> >>>> In the above, the temporary variable “iftmp.2” triggered the assertion 
> >>>> since it’s NOT a SSA_NAME but the gimple_in_ssa_p (cfun) is TRUE.
> >>>>
> >>>> 3. As I checked, this temporary variable “iftmp.2” was generated at line 
> >>>> 5498 in the routine “gimplify_cond_expr” of gimplify.cc:
> >>>>
> >>>> 5477   /* If this COND_EXPR has a value, copy the values into a 
> >>>> temporary within
> >>>> 5478      the arms.  */
> >>>> 5479   if (!VOID_TYPE_P (type))
> >>>> 5480     {
> >>>> …..
> >>>> 5498           tmp = create_tmp_var (type, "iftmp”);
> >>>> ...
> >>>> 5537     }
> >>>>
> >>>> 4. And then later, this temporary created here “iftmp.2” triggered the 
> >>>> assertion failure.
> >>>>
> >>>> Right now, I have the following questions:
> >>>>
> >>>> 1. Can I generate a size_expr as complicate as the following in 
> >>>> tree-object-size.cc:
> >>>>
> >>>> _4 = obj_2(D) != 0B ? (sizetype) (int) MAX_EXPR <(sizetype) MAX_EXPR 
> >>>> <MEM <int> [(void *)&*obj_2(D)], 0> + 4, 4> : 18446744073709551615
> >>>>
> >>>> 2. If Yes to 1, is this a bug in “gimplify_cond_expr”? Shall we call 
> >>>> “make_ssa_name” after the call to “create_tmp_var” if 
> >>>> “gimple_in_ssa_p(cfun)” is TRUE?
> >>>>
> >>>> 3. If No to 1, how can we check whether the pointer is zero before 
> >>>> dereference from it to access its field?
> >>>>
> >>>> Thanks a lot for any hints.
> >>>>
> >>>> Qing
>
>

Reply via email to