On 10/19/22 13:41, Jakub Jelinek wrote: > On Wed, Oct 19, 2022 at 07:39:05PM +0200, Jakub Jelinek via Gcc-patches wrote: >> On Wed, Oct 19, 2022 at 12:55:12PM -0400, Andrew MacLeod via Gcc-patches wrote: >>>> Not sure I understand this part. op is whatever we pass as the ith >>>> argument to IFN_ASSUME. I'd expect that at this point one needs to >>>> remap that to the (i-1)th PARM_DECL of assume_id (so e.g. when you >>>> have the above loop you could as well start with DECL_ARGUMENTS and move >>>> that to DECL_CHAIN at the end of every iteration. And then >>>> query ssa_default_def (DECL_STRUCT_FUNCTION (assume_id), parm) >>>> in each case and get global range of what that returns. >>> OK, this is the bit of code I dont know how to write :-) >>> >>> yes, op is the name of the value within this current function, and yes, that >>> needs to be mapped to the argument decl in the assume function.   Then we >>> need to query what range was given to that name during the assume pass. >>> when that is returned, the add_range (op, range) will inject it as a side >>> effect. >>> >>> Can you write that loop? >> I meant something like (untested code): >> && gimple_call_internal_fn (s) == IFN_ASSUME) >> { >> tree assume_id = gimple_call_arg (s, 0); >> - for (unsigned i = 1; i < gimple_call_num_args (s); i++) >> + tree parm = DECL_ARGUMENTS (assume_id); >> + struct function *fun = DECL_STRUCT_FUNCTION (assume_id); >> + for (unsigned i = 1; >> + i < gimple_call_num_args (s) && parm; >> + i++, parm = DECL_CHAIN (parm)) >> { >> tree op = gimple_call_arg (s, i); >> tree type = TREE_TYPE (op); >> + tree arg = ssa_default_def (fun, parm); >> + if (arg == NULL_TREE) >> + continue; >> if (gimple_range_ssa_p (op) && Value_Range::supports_type_p (type)) >> { >> Value_Range assume_range (type); >> and querying SSA_NAME_RANGE_INFO of arg rather than op. Thanks, I had actually come to most of those conclusions already, except for the DECL_STRUCT_FUNCTION bit.. I was stuck on that :-) So the SSA_NAMEs for default_defs are never disposed of?  so I can query them even though they are not in the current function decl?  huh. I did not know that. OK, attached is the latest set of patches.  not bootstrapped or anything, but very interesting. from.assumption  pass: ;; Function _Z3bari._assume.0 (_Z3bari._assume.0, funcdef_no=5, decl_uid=2184, cgraph_uid=7, symbol_order=7) Assumptions : -------------- x_1(D) -> [irange] int [42, 42] NONZERO 0x2a __attribute__((no_icf, noclone, noinline, noipa)) bool _Z3bari._assume.0 (int x) {   bool _2; ;;   basic block 2, loop depth 0 ;;    pred:       ENTRY   _2 = x_1(D) == 42;   return _2; ;;    succ:       EXIT } and in the VRP2 pass, I see: _Z3bari._assume.0 assume inferred range of x_1(D) (param x) = [irange] int [42, 42] NONZERO 0x2a int bar (int x) {   [local count: 1073741824]:   .ASSUME (_Z3bari._assume.0, x_1(D));   return 42; } Huh.  lookit that..... Anyway, let me clean this up a bit more, but so far so good. I'll try bootstrapping and  such Andrew