Hi Richard, I do not see the said patch applied in ToT yet. When do you expect it to be available in ToT?
- Thanks and regards, Sameera D. On 30 March 2018 at 17:01, Sameera Deshpande <sameera.deshpa...@linaro.org> wrote: > Hi Richard, > > The testcase is working with the patch you suggested, thanks for > pointing that out. > > On 30 March 2018 at 16:54, Sameera Deshpande > <sameera.deshpa...@linaro.org> wrote: >> On 30 March 2018 at 16:39, Richard Sandiford >> <richard.sandif...@linaro.org> wrote: >>>> Hi Sudakshina, >>>> >>>> Thanks for pointing that out. Updated the conditions for attribute >>>> length to take care of boundary conditions for offset range. >>>> >>>> Please find attached the updated patch. >>>> >>>> I have tested it for gcc testsuite and the failing testcase. Ok for trunk? >>>> >>>> On 22 March 2018 at 19:06, Sudakshina Das <sudi....@arm.com> wrote: >>>>> Hi Sameera >>>>> >>>>> On 22/03/18 02:07, Sameera Deshpande wrote: >>>>>> >>>>>> Hi Sudakshina, >>>>>> >>>>>> As per the ARMv8 ARM, for the offset range (-1048576 ,1048572), the >>>>>> far branch instruction offset is inclusive of both the offsets. Hence, >>>>>> I am using <=||=> and not <||>= as it was in previous implementation. >>>>> >>>>> >>>>> I have to admit earlier I was only looking at the patch mechanically and >>>>> found a difference with the previous implementation in offset comparison. >>>>> After you pointed out, I looked up the ARMv8 ARM and I have a couple of >>>>> doubts: >>>>> >>>>> 1. My understanding is that any offset in [-1048576 ,1048572] both >>>>> inclusive >>>>> qualifies as an 'in range' offset. However, the code for both attribute >>>>> length and far_branch has been using [-1048576 ,1048572), that is, ( >= >>>>> && < >>>>> ). If the far_branch was incorrectly calculated, then maybe the length >>>>> calculations with similar magic numbers should also be corrected? Of >>>>> course, >>>>> I am not an expert in this and maybe this was a conscience decision so I >>>>> would ask Ramana to maybe clarify if he remembers. >>>>> >>>>> 2. Now to come back to your patch, if my understanding is correct, I >>>>> think a >>>>> far_branch would be anything outside of this range, that is, >>>>> (offset < -1048576 || offset > 1048572), anything that can not be >>>>> represented in the 21-bit range. >>>>> >>>>> Thanks >>>>> Sudi >>> >>> [...] >>> >>>> @@ -466,14 +459,9 @@ >>>> [(set_attr "type" "branch") >>>> (set (attr "length") >>>> (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int >>>> -1048576)) >>>> - (lt (minus (match_dup 2) (pc)) (const_int >>>> 1048572))) >>>> + (le (minus (match_dup 2) (pc)) (const_int >>>> 1048572))) >>>> (const_int 4) >>>> - (const_int 8))) >>> >>> Sorry for not replying earlier, but I think the use of "lt" rather than >>> "le" in the current length attribute is deliberate. Distances measured >>> from (pc) in "length" are a bit special in that backward distances are >>> measured from the start of the instruction and forward distances are >>> measured from the end of the instruction: >>> >>> /* The address of the current insn. We implement this actually as the >>> address of the current insn for backward branches, but the last >>> address of the next insn for forward branches, and both with >>> adjustments that account for the worst-case possible stretching of >>> intervening alignments between this insn and its destination. */ >>> >>> This avoids the chicken-and-egg situation of the length of the branch >>> depending on the forward distance and the forward distance depending >>> on the length of the branch. >>> >>> In contrast, this code: >>> >>>> @@ -712,7 +695,11 @@ >>>> { >>>> if (get_attr_length (insn) == 8) >>>> { >>>> - if (get_attr_far_branch (insn) == 1) >>>> + long long int offset; >>>> + offset = INSN_ADDRESSES (INSN_UID (XEXP (operands[2], 0))) >>>> + - INSN_ADDRESSES (INSN_UID (insn)); >>>> + >>>> + if (offset < -1048576 || offset > 1048572) >>>> return aarch64_gen_far_branch (operands, 2, "Ltb", >>>> "<inv_tb>\\t%<w>0, %1, "); >>>> else >>> >>> is reading the final computed addresses, so the code is right to use >>> the real instruction range. (FWIW I agree with Kyrill that using >>> IN_RANGE with hex constants would be clearer.) >>> >>> That said... a possible problem comes from situations like: >>> >>> address length insn >>> ......c 8 A >>> ..align to 8 bytes... >>> ......8 B >>> ......c 4 C >>> ..align to 16 bytes... >>> ......0 D, branch to B >>> >>> when D is at the maximum extent of the branch range and when GCC's length >>> for A is only a conservative estimate. If the length of A turns out to >>> be 4 rather than 8 at assembly time, the alignment to 8 bytes will be >>> a no-op and the address of B and C will be 8 less than we calculated. >>> But the alignment to 16 bytes will then insert 8 bytes of padding rather >>> than none, and the address of D won't change. The branch will then be >>> out of range even though the addresses calculated by GCC showed it as >>> being in range. insn_current_reference_address accounts for this, and >>> so copes correctly with conservative lengths. >>> >>> The length can legitimately be conservative for things like asm >>> statements, so I guess using the far_branch attribute is best >>> after all. Sorry for the wrong turn. >>> >>> On the face of it (without access to the testcase), the only problem >>> with using far_branch in the output template is that insn_last_address >>> is not set, but needs to be for insn_current_reference_address to do >>> the right thing for forward branches. Does the patch below work for >>> your testcase? >>> >>> (As the documentation you mentioned in the original covering message >>> says, it wouldn't be correct to use far_branch in anything other >>> than final, since only the "length" attribute can respond to changes >>> in addresses while the lengths are being calculated. But using it >>> in final should be fine.) >>> >>> Thanks, >>> Richard >>> >>> >>> 2018-03-31 Richard Sandiford <richard.sandif...@linaro.org> >>> >>> gcc/ >>> * final.c (final_1): Set insn_last_address to the same value as >>> insn_current_address. >>> >>> Index: gcc/final.c >>> =================================================================== >>> --- gcc/final.c 2018-03-30 11:54:02.058881968 +0100 >>> +++ gcc/final.c 2018-03-30 11:54:02.228869184 +0100 >>> @@ -2081,6 +2081,9 @@ final_1 (rtx_insn *first, FILE *file, in >>> } >>> else >>> insn_current_address = INSN_ADDRESSES (INSN_UID (insn)); >>> + /* final can be seen as an iteration of shorten_branches that >>> + does nothing (since a fixed point has already been reached). >>> */ >>> + insn_last_address = insn_current_address; >>> } >>> >>> dump_basic_block_info (file, insn, start_to_bb, end_to_bb, >> >> Hi Richard, >> >> Thanks for the explanation. The problem was indeed because correct >> insn_last_address was not set properly, because of which the attribute >> FAR_BRANCH didn't work appropriately. However, I am not sure if that >> was the only problem. Will check the testcase with the ToT sans my >> changes, and will revert. >> >> -- >> - Thanks and regards, >> Sameera D. > > > > -- > - Thanks and regards, > Sameera D. -- - Thanks and regards, Sameera D.