[4.9][PR69082]Backport "[PATCH][ARM]Tighten the conditions for arm_movw, arm_movt"

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Tue Jan 12 16:28:00 GMT 2016


On 12/01/16 15:31, Renlin Li wrote:
> Hi all,
> 
> Here I backport r227129 to branch 4.9 to fix exactly the same issue
> reported in PR69082.
> It's been already committed on trunk and backportted to branch 5.
> 
> 
> I have quoted the original message for the explanation.
> The patch applies to branch 4.9 without any modifications.
> Test case is not added as the one provided in the bugzilla ticket is too
> big and complex.
> 
> arm-none-linux-gnueabihf regression tested without any issues.
> 
> Is Okay to backport to branch 4.9?
> 
> Renlin Li
> 
> 
> gcc/ChangeLog
> 
> 2016-01-08  Renlin Li  <renlin.li@arm.com>
> 
>         PR target/69082
>         Backport from mainline:
>         2015-08-24  Renlin Li  <renlin.li@arm.com>
> 
>     * config/arm/arm-protos.h (arm_valid_symbolic_address_p): Declare.
>     * config/arm/arm.c (arm_valid_symbolic_address_p): Define.
>     * config/arm/arm.md (arm_movt): Use arm_valid_symbolic_address_p.
>     * config/arm/constraints.md ("j"): Add check for high code
> 
> 

OK.

R.

> On 19/08/15 15:37, Renlin Li wrote:
>>
>>> On 19/08/15 12:49, Renlin Li wrote:
>>>> Hi all,
>>>>
>>>> This simple patch will tighten the conditions when matching movw and
>>>> arm_movt rtx pattern.
>>>> Those two patterns will generate the following assembly:
>>>>
>>>> movw w1, #:lower16: dummy + addend
>>>> movt w1, #:upper16: dummy + addend
>>>>
>>>> The addend here is optional. However, it should be an 16-bit signed
>>>> value with in the range -32768 <= A <= 32768.
>>>>
>>>> By impose this restriction explicitly, it will prevent LRA/reload code
>>>> from generation invalid high/lo_sum code for arm target.
>>>> In process_address_1(), if the address is not legitimate, it will
>>>> try to
>>>> generate high/lo_sum pair to put the address into register. It will
>>>> check if the target support those newly generated reload instructions.
>>>> By define those two patterns, arm will reject them if conditions is not
>>>> meet.
>>>>
>>>> Otherwise, it might generate movw/movt instructions with addend larger
>>>> than 32768, this will cause a GAS error. GAS will produce '''offset out
>>>> of range'' error message when the addend for MOVW/MOVT REL
>>>> relocation is
>>>> too large.
>>>>
>>>>
>>>> arm-none-eabi regression tests Okay, Okay to commit to the trunk and
>>>> backport to 5.0?
>>>>
>>>> Regards,
>>>> Renlin
>>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2015-08-19  Renlin Li  <renlin.li@arm.com>
>>>>
>>>>        * config/arm/arm-protos.h (arm_valid_symbolic_address_p):
>>>> Declare.
>>>>        * config/arm/arm.c (arm_valid_symbolic_address_p): Define.
>>>>        * config/arm/arm.md (arm_movt): Use
>>>> arm_valid_symbolic_address_p.
>>>>        * config/arm/constraints.md ("j"): Add check for high code.
>>
>> Thank you,
>> Renlin
>>
> 
> 
> backport.diff
> 
> 
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index cef9eec..ff168bf 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -319,6 +319,7 @@ extern int vfp3_const_double_for_bits (rtx);
>  
>  extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
>  					   rtx);
> +extern bool arm_valid_symbolic_address_p (rtx);
>  extern bool arm_validize_comparison (rtx *, rtx *, rtx *);
>  #endif /* RTX_CODE */
>  
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index c2095a3..7cc4d93 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -28664,6 +28664,38 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
>    #undef BRANCH
>  }
>  
> +/* Returns true if the pattern is a valid symbolic address, which is either a
> +   symbol_ref or (symbol_ref + addend).
> +
> +   According to the ARM ELF ABI, the initial addend of REL-type relocations
> +   processing MOVW and MOVT instructions is formed by interpreting the 16-bit
> +   literal field of the instruction as a 16-bit signed value in the range
> +   -32768 <= A < 32768.  */
> +
> +bool
> +arm_valid_symbolic_address_p (rtx addr)
> +{
> +  rtx xop0, xop1 = NULL_RTX;
> +  rtx tmp = addr;
> +
> +  if (GET_CODE (tmp) == SYMBOL_REF || GET_CODE (tmp) == LABEL_REF)
> +    return true;
> +
> +  /* (const (plus: symbol_ref const_int))  */
> +  if (GET_CODE (addr) == CONST)
> +    tmp = XEXP (addr, 0);
> +
> +  if (GET_CODE (tmp) == PLUS)
> +    {
> +      xop0 = XEXP (tmp, 0);
> +      xop1 = XEXP (tmp, 1);
> +
> +      if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
> +	  return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> +    }
> +
> +  return false;
> +}
>  
>  /* Returns true if a valid comparison operation and makes
>     the operands in a form that is valid.  */
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 288bbb9..eefb7fa 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -5774,7 +5774,7 @@
>    [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
>  	(lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
>  		   (match_operand:SI 2 "general_operand"      "i")))]
> -  "arm_arch_thumb2"
> +  "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
>    "movt%?\t%0, #:upper16:%c2"
>    [(set_attr "predicable" "yes")
>     (set_attr "predicable_short_it" "no")
> diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
> index 42935a4..f9e11e0 100644
> --- a/gcc/config/arm/constraints.md
> +++ b/gcc/config/arm/constraints.md
> @@ -67,7 +67,8 @@
>  (define_constraint "j"
>   "A constant suitable for a MOVW instruction. (ARM/Thumb-2)"
>   (and (match_test "TARGET_32BIT && arm_arch_thumb2")
> -      (ior (match_code "high")
> +      (ior (and (match_code "high")
> +		(match_test "arm_valid_symbolic_address_p (XEXP (op, 0))"))
>  	   (and (match_code "const_int")
>                  (match_test "(ival & 0xffff0000) == 0")))))
>  
> 



More information about the Gcc-patches mailing list