On Mon, Jul 07, 2025 at 07:51:52PM -0400, Siddhesh Poyarekar wrote: > On 2025-07-07 17:47, Jakub Jelinek wrote: > > Even 6 arguments is IMHO too much. > > /* Expand the IFN_ACCESS_WITH_SIZE function: > > ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE, CLASS_OF_SIZE, > > TYPE_OF_SIZE, ACCESS_MODE) > > which returns the REF_TO_OBJ same as the 1st argument; > > > > 1st argument REF_TO_OBJ: The reference to the object; > > 2nd argument REF_TO_SIZE: The reference to the size of the object, > > 3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE > > represents > > 0: the number of bytes. > > 1: the number of the elements of the object type; > > 4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as > > the TYPE > > of the object referenced by REF_TO_SIZE > > Wouldn't this always be TREE_TYPE(TREE_TYPE(REF_TO_SIZE))?
No. Because (most of the) pointer conversions are useless, if you have _2 = &something.fam[0]; ... _4 = &something.fam; _5 = .ACCESS_WITH_SIZE (_4, ...); (or whatever else where _4 has the carefully chosen pointer type for the behavior of the IFN), if e.g. SCCVN finds out that _2 and _4 must have the same value, regardless of different type, if useless_type_conversion_p (TREE_TYPE (_4), TREE_TYPE (_2)), it will happily replace _4 with _2, and all of sudden you have a different type. The INTEGER_CST with a special type is a known work-around for that, nothing will try to propagate an INTEGER_CST with a different type but same value into it. > > > 5th argument ACCESS_MODE: > > -1: Unknown access semantics > > 0: none > > 1: read_only > > 2: write_only > > 3: read_write > > 6th argument: A constant 0 with the pointer TYPE to the original > > flexible > > array type. > > Likewise, wouldn't this always be TREE_TYPE(TREE_TYPE(REF_TO_OBJ))? For a > FAM, the frontend does array_to_pointer, so with the INDIRECT_REF at the end > of build_access_with_size_for_counted_by gone, I reckon you should be able > to get the type of the array element. Likewise if it was a pointer and not > a FAM. > > TYPE_SIZE_UNIT may not work for them like you said, but there ought to be a > usable expression that we can reach from the type, no? No. The IL must clearly use the value (the size of the element), otherwise DCE or other passes will happily optimize it away, they don't keep some expression computation around just because it is referenced in TYPE_SIZE_UNIT of some type somewhere. Consider e.g. void bar (int *); void foo (int n, int m) { typedef int A[m]; struct S { int n, m; A a[2]; A b[] __attribute__((counted_by (n))); } *p; p = __builtin_malloc (sizeof (struct S) + sizeof (A) * n); p->n = n; p->m = m; int *q = &p->b[1][0]; bar (q); q = &p->b[0][1]; bar (q); } There is a reason why e.g. COMPONENT_REF has 3 arguments rather than 2, the last one used solely for the variable length structures (primarily Ada, or GNU C extension like above). Jakub