Re: [PATCH v2 05/11] aarch64: Use UNSPEC_SBCS for subtract-with-borrow + output flags

2020-04-09 Thread Richard Henderson
On 4/9/20 2:52 PM, Segher Boessenkool wrote:
> Hi!
> 
> On Thu, Apr 02, 2020 at 11:53:47AM -0700, Richard Henderson wrote:
>> The rtl description of signed/unsigned overflow from subtract
>> was fine, as far as it goes -- we have CC_Cmode and CC_Vmode
>> that indicate that only those particular bits are valid.
>>
>> However, it's not clear how to extend that description to
>> handle signed comparison, where N == V (GE) N != V (LT) are
>> the only valid bits.
>>
>> Using an UNSPEC means that we can unify all 3 usages without
>> fear that combine will try to infer anything from the rtl.
>> It also means we need far fewer variants when various inputs
>> have constants propagated in, and the rtl folds.
>>
>> Accept -1 for the second input by using ADCS.
> 
> If you use an unspec anyway, why do you need a separate UNSPEC_SBCS?
> It is just the same as UNSPEC_ADCS, with one of the inputs inverted?
> 
> Is there any reason to pretend borrows are different from carries?

Good point.  If we go this way, I'll make sure and merge them.
But I've also just sent v4 that does away with the unspecs and
uses the forms that Earnshaw used for config/arm.


r~


[PATCH v4 11/12] aarch64: Accept 0 as first argument to compares

2020-04-09 Thread Richard Henderson via Gcc-patches
While cmp (extended register) and cmp (immediate) uses ,
cmp (shifted register) uses .  So we can perform cmp xzr, x0.

For ccmp, we only have  as an input.

* config/aarch64/aarch64.md (cmp): For operand 0, use
aarch64_reg_or_zero.  Shuffle reg/reg to last alternative
and accept Z.
(@ccmpcc): For operand 0, use aarch64_reg_or_zero and Z.
(@ccmpcc_rev): Likewise.
---
 gcc/config/aarch64/aarch64.md | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index fb1a39a3886..2b5a6eb510d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -502,7 +502,7 @@
   [(match_operand 0 "cc_register" "")
(const_int 0)])
  (compare:CC_ONLY
-   (match_operand:GPI 2 "register_operand" "r,r,r")
+   (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ,r,r")
(match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn"))
  (unspec:CC_ONLY
[(match_operand 5 "immediate_operand")]
@@ -542,7 +542,7 @@
[(match_operand 5 "immediate_operand")]
UNSPEC_NZCV)
  (compare:CC_ONLY
-   (match_operand:GPI 2 "register_operand" "r,r,r")
+   (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ,r,r")
(match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn"]
   ""
   "@
@@ -3902,14 +3902,14 @@
 
 (define_insn "cmp"
   [(set (reg:CC CC_REGNUM)
-   (compare:CC (match_operand:GPI 0 "register_operand" "rk,rk,rk")
-   (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
+   (compare:CC (match_operand:GPI 0 "aarch64_reg_or_zero" "rk,rk,rkZ")
+   (match_operand:GPI 1 "aarch64_plus_operand" "I,J,r")))]
   ""
   "@
-   cmp\\t%0, %1
cmp\\t%0, %1
-   cmn\\t%0, #%n1"
-  [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
+   cmn\\t%0, #%n1
+   cmp\\t%0, %1"
+  [(set_attr "type" "alus_imm,alus_imm,alus_sreg")]
 )
 
 (define_insn "fcmp"
-- 
2.20.1



[PATCH v4 12/12] aarch64: Implement TImode comparisons

2020-04-09 Thread Richard Henderson via Gcc-patches
* config/aarch64/aarch64-modes.def (CC_NV): New.
* config/aarch64/aarch64.c (aarch64_gen_compare_reg): Expand
all of the comparisons for TImode, not just NE.
(aarch64_select_cc_mode): Recognize cmp_carryin.
(aarch64_get_condition_code_1): Handle CC_NVmode.
* config/aarch64/aarch64.md (cbranchti4, cstoreti4): New.
(ccmp_iorne): New.
(cmp_carryin): New.
(*cmp_carryin): New.
(*cmp_carryin_z1): New.
(*cmp_carryin_z2): New.
(*cmp_carryin_m2, *ucmp_carryin_m2): New.
* config/aarch64/iterators.md (CC_EXTEND): New.
* config/aarch64/predicates.md (const_dword_umax): New.
---
 gcc/config/aarch64/aarch64.c | 164 ---
 gcc/config/aarch64/aarch64-modes.def |   1 +
 gcc/config/aarch64/aarch64.md| 113 ++
 gcc/config/aarch64/iterators.md  |   3 +
 gcc/config/aarch64/predicates.md |   9 ++
 5 files changed, 277 insertions(+), 13 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 837ee6a5e37..6c825b341a0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2731,32 +2731,143 @@ rtx
 aarch64_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
 {
   machine_mode cmp_mode = GET_MODE (x);
-  machine_mode cc_mode;
   rtx cc_reg;
 
   if (cmp_mode == TImode)
 {
-  gcc_assert (code == NE);
+  rtx x_lo, x_hi, y_lo, y_hi, tmp;
+  struct expand_operand ops[2];
 
-  cc_mode = CCmode;
-  cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM);
+  x_lo = operand_subword (x, 0, 0, TImode);
+  x_hi = operand_subword (x, 1, 0, TImode);
 
-  rtx x_lo = operand_subword (x, 0, 0, TImode);
-  rtx y_lo = operand_subword (y, 0, 0, TImode);
-  emit_set_insn (cc_reg, gen_rtx_COMPARE (cc_mode, x_lo, y_lo));
+  if (CONST_SCALAR_INT_P (y))
+   {
+ wide_int y_wide = rtx_mode_t (y, TImode);
 
-  rtx x_hi = operand_subword (x, 1, 0, TImode);
-  rtx y_hi = operand_subword (y, 1, 0, TImode);
-  emit_insn (gen_ccmpccdi (cc_reg, cc_reg, x_hi, y_hi,
-  gen_rtx_EQ (cc_mode, cc_reg, const0_rtx),
-  GEN_INT (AARCH64_EQ)));
+ switch (code)
+   {
+   case EQ:
+   case NE:
+ /* For equality, IOR the two halves together.  If this gets
+used for a branch, we expect this to fold to cbz/cbnz;
+otherwise it's no larger than the cmp+ccmp below.  Beware
+of the compare-and-swap post-reload split and use ccmp.  */
+ if (y_wide == 0 && can_create_pseudo_p ())
+   {
+ tmp = gen_reg_rtx (DImode);
+ emit_insn (gen_iordi3 (tmp, x_hi, x_lo));
+ emit_insn (gen_cmpdi (tmp, const0_rtx));
+ cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
+ goto done;
+   }
+ break;
+
+   case LE:
+   case GT:
+ /* Add 1 to Y to convert to LT/GE, which avoids the swap and
+keeps the constant operand.  */
+ if (wi::cmps(y_wide, wi::max_value (TImode, SIGNED)) < 0)
+   {
+ y = immed_wide_int_const (wi::add (y_wide, 1), TImode);
+ code = (code == LE ? LT : GE);
+   }
+ break;
+
+   case LEU:
+   case GTU:
+ /* Add 1 to Y to convert to LT/GE, which avoids the swap and
+keeps the constant operand.  */
+ if (wi::cmpu(y_wide, wi::max_value (TImode, UNSIGNED)) < 0)
+   {
+ y = immed_wide_int_const (wi::add (y_wide, 1), TImode);
+ code = (code == LEU ? LTU : GEU);
+   }
+ break;
+
+   default:
+ break;
+   }
+   }
+
+  y_lo = simplify_gen_subreg (DImode, y, TImode,
+ subreg_lowpart_offset (DImode, TImode));
+  y_hi = simplify_gen_subreg (DImode, y, TImode,
+ subreg_highpart_offset (DImode, TImode));
+
+  switch (code)
+   {
+   case LEU:
+   case GTU:
+   case LE:
+   case GT:
+ std::swap (x_lo, y_lo);
+ std::swap (x_hi, y_hi);
+ code = swap_condition (code);
+ break;
+
+   case LTU:
+   case GEU:
+   case LT:
+   case GE:
+ /* If the low word of y is 0, then this is simply a normal
+compare of the upper words.  */
+ if (y_lo == const0_rtx)
+   {
+ if (!aarch64_plus_operand (y_hi, DImode))
+   y_hi = force_reg (DImode, y_hi);
+ return aarch64_gen_compare_reg (code, x_hi, y_hi);
+   }
+ break;
+
+   default:
+ break;
+   }
+
+  /* Emit cmpdi, forcing operands into registers as required.  */
+  create_input_operand (&ops[0], x_lo

[PATCH v4 07/12] aarch64: Rename CC_ADCmode to CC_NOTCmode

2020-04-09 Thread Richard Henderson via Gcc-patches
We are about to use !C in more contexts than add-with-carry.
Choose a more generic name.

* config/aarch64/aarch64-modes.def (CC_NOTC): Rename CC_ADC.
* config/aarch64/aarch64.c (aarch64_select_cc_mode): Update.
(aarch64_get_condition_code_1): Likewise.
* config/aarch64/aarch64.md (addvti4): Likewise.
(add3_carryinC): Likewise.
(*add3_carryinC_zero): Likewise.
(*add3_carryinC): Likewise.
---
 gcc/config/aarch64/aarch64.c |  4 ++--
 gcc/config/aarch64/aarch64-modes.def |  5 +++--
 gcc/config/aarch64/aarch64.md| 14 +++---
 gcc/config/aarch64/predicates.md |  4 ++--
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index cd4dc1ef6f9..c09b7bcb7f0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9530,7 +9530,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   && code_x == PLUS
   && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
   && const_dword_umaxp1 (y, mode_x))
-return CC_ADCmode;
+return CC_NOTCmode;
 
   /* A test for signed overflow.  */
   if ((mode_x == DImode || mode_x == TImode)
@@ -9663,7 +9663,7 @@ aarch64_get_condition_code_1 (machine_mode mode, enum 
rtx_code comp_code)
}
   break;
 
-case E_CC_ADCmode:
+case E_CC_NOTCmode:
   switch (comp_code)
{
case GEU: return AARCH64_CS;
diff --git a/gcc/config/aarch64/aarch64-modes.def 
b/gcc/config/aarch64/aarch64-modes.def
index af972e8f72b..181b7b30dcd 100644
--- a/gcc/config/aarch64/aarch64-modes.def
+++ b/gcc/config/aarch64/aarch64-modes.def
@@ -29,7 +29,7 @@
CCmode is used for 'normal' compare (subtraction) operations.  For
ADC, the representation becomes more complex still, since we cannot
use the normal idiom of comparing the result to one of the input
-   operands; instead we use CC_ADCmode to represent this case.  */
+   operands; instead we use CC_NOTCmode to represent this case.  */
 CC_MODE (CCFP);
 CC_MODE (CCFPE);
 CC_MODE (CC_SWP);
@@ -38,7 +38,8 @@ CC_MODE (CC_NZC);   /* Only N, Z and C bits of condition 
flags are valid.
 CC_MODE (CC_NZ);/* Only N and Z bits of condition flags are valid.  */
 CC_MODE (CC_Z); /* Only Z bit of condition flags is valid.  */
 CC_MODE (CC_C); /* C represents unsigned overflow of a simple addition.  */
-CC_MODE (CC_ADC);   /* Unsigned overflow from an ADC (add with carry).  */
+CC_MODE (CC_NOTC);  /* !C represents unsigned overflow of subtraction,
+   as well as our representation of add-with-carry.  */
 CC_MODE (CC_V); /* Only V bit of condition flags is valid.  */
 
 /* Half-precision floating point for __fp16.  */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d51f6146c43..7d4a63f9a2a 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2077,7 +2077,7 @@
   CODE_FOR_adddi3_compareC,
   CODE_FOR_adddi3_compareC,
   CODE_FOR_adddi3_carryinC);
-  aarch64_gen_unlikely_cbranch (GEU, CC_ADCmode, operands[3]);
+  aarch64_gen_unlikely_cbranch (GEU, CC_NOTCmode, operands[3]);
   DONE;
 })
 
@@ -2580,7 +2580,7 @@
 (define_expand "add3_carryinC"
   [(parallel
  [(set (match_dup 3)
-  (compare:CC_ADC
+  (compare:CC_NOTC
 (plus:
   (plus:
 (match_dup 4)
@@ -2595,7 +2595,7 @@
 (match_dup 2)))])]
""
 {
-  operands[3] = gen_rtx_REG (CC_ADCmode, CC_REGNUM);
+  operands[3] = gen_rtx_REG (CC_NOTCmode, CC_REGNUM);
   rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM);
   operands[4] = gen_rtx_LTU (mode, ccin, const0_rtx);
   operands[5] = gen_rtx_LTU (mode, ccin, const0_rtx);
@@ -2605,8 +2605,8 @@
 })
 
 (define_insn "*add3_carryinC_zero"
-  [(set (reg:CC_ADC CC_REGNUM)
-   (compare:CC_ADC
+  [(set (reg:CC_NOTC CC_REGNUM)
+   (compare:CC_NOTC
  (plus:
(match_operand: 2 "aarch64_carry_operation" "")
(zero_extend: (match_operand:GPI 1 "register_operand" "r")))
@@ -2620,8 +2620,8 @@
 )
 
 (define_insn "*add3_carryinC"
-  [(set (reg:CC_ADC CC_REGNUM)
-   (compare:CC_ADC
+  [(set (reg:CC_NOTC CC_REGNUM)
+   (compare:CC_NOTC
  (plus:
(plus:
  (match_operand: 3 "aarch64_carry_operation" "")
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 99c3bfbace4..e3572d2f60d 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -390,7 +390,7 @@
   machine_mode ccmode = GET_MODE (op0);
   if (ccmode == CC_Cmode)
 return GET_CODE (op) == LTU;
-  if (ccmode == CC_ADCmode || ccmode == CCmode)
+  if (ccmode == CC_NOTCmode || ccmode == CCmode)
 return GET_CODE (op) == GEU;
   return false;
 })
@@ -408,7 +408,7 @@
   machine_mode ccmode = GET_MODE (op0);
   if (ccmode == CC_Cmode)
 return GET_COD

[PATCH v4 10/12] aarch64: Adjust result of aarch64_gen_compare_reg

2020-04-09 Thread Richard Henderson via Gcc-patches
Return the entire comparison expression, not just the cc_reg.
This will allow the routine to adjust the comparison code as
needed for TImode comparisons.

Note that some users were passing e.g. EQ to aarch64_gen_compare_reg
and then using gen_rtx_NE.  Pass the proper code in the first place.

* config/aarch64/aarch64.c (aarch64_gen_compare_reg): Return
the final comparison for code & cc_reg.
(aarch64_gen_compare_reg_maybe_ze): Likewise.
(aarch64_expand_compare_and_swap): Update to match -- do not
build the final comparison here, but PUT_MODE as necessary.
(aarch64_split_compare_and_swap): Use prebuilt comparison.
* config/aarch64/aarch64-simd.md (aarch64_cmdi): Likewise.
(aarch64_cmdi): Likewise.
(aarch64_cmtstdi): Likewise.
* config/aarch64/aarch64-speculation.cc
(aarch64_speculation_establish_tracker): Likewise.
* config/aarch64/aarch64.md (cbranch4, cbranch4): Likewise.
(mod3, abs2): Likewise.
(cstore4, cstore4): Likewise.
(cmov6, cmov6): Likewise.
(movcc, movcc, movcc): Likewise.
(cc): Likewise.
(ffs2): Likewise.
(cstorecc4): Remove redundant "".
---
 gcc/config/aarch64/aarch64.c  | 26 +++---
 gcc/config/aarch64/aarch64-simd.md| 18 ++---
 gcc/config/aarch64/aarch64-speculation.cc |  5 +-
 gcc/config/aarch64/aarch64.md | 96 ++-
 4 files changed, 63 insertions(+), 82 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d80afc36889..837ee6a5e37 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2726,7 +2726,7 @@ emit_set_insn (rtx x, rtx y)
 }
 
 /* X and Y are two things to compare using CODE.  Emit the compare insn and
-   return the rtx for register 0 in the proper mode.  */
+   return the rtx for the CCmode comparison.  */
 rtx
 aarch64_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
 {
@@ -2757,7 +2757,7 @@ aarch64_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
   cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM);
   emit_set_insn (cc_reg, gen_rtx_COMPARE (cc_mode, x, y));
 }
-  return cc_reg;
+  return gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
 }
 
 /* Similarly, but maybe zero-extend Y if Y_MODE < SImode.  */
@@ -2783,7 +2783,7 @@ aarch64_gen_compare_reg_maybe_ze (RTX_CODE code, rtx x, 
rtx y,
  cc_mode = CC_SWPmode;
  cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM);
  emit_set_insn (cc_reg, t);
- return cc_reg;
+ return gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
}
 }
 
@@ -18980,7 +18980,8 @@ aarch64_expand_compare_and_swap (rtx operands[])
 
   emit_insn (gen_aarch64_compare_and_swap_lse (mode, rval, mem,
   newval, mod_s));
-  cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode);
+  x = aarch64_gen_compare_reg_maybe_ze (EQ, rval, oldval, mode);
+  PUT_MODE (x, SImode);
 }
   else if (TARGET_OUTLINE_ATOMICS)
 {
@@ -18991,7 +18992,8 @@ aarch64_expand_compare_and_swap (rtx operands[])
   rval = emit_library_call_value (func, NULL_RTX, LCT_NORMAL, r_mode,
  oldval, mode, newval, mode,
  XEXP (mem, 0), Pmode);
-  cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode);
+  x = aarch64_gen_compare_reg_maybe_ze (EQ, rval, oldval, mode);
+  PUT_MODE (x, SImode);
 }
   else
 {
@@ -19003,13 +19005,13 @@ aarch64_expand_compare_and_swap (rtx operands[])
   emit_insn (GEN_FCN (code) (rval, mem, oldval, newval,
 is_weak, mod_s, mod_f));
   cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
+  x = gen_rtx_EQ (SImode, cc_reg, const0_rtx);
 }
 
   if (r_mode != mode)
 rval = gen_lowpart (mode, rval);
   emit_move_insn (operands[1], rval);
 
-  x = gen_rtx_EQ (SImode, cc_reg, const0_rtx);
   emit_insn (gen_rtx_SET (bval, x));
 }
 
@@ -19084,10 +19086,8 @@ aarch64_split_compare_and_swap (rtx operands[])
   if (strong_zero_p)
 x = gen_rtx_NE (VOIDmode, rval, const0_rtx);
   else
-{
-  rtx cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode);
-  x = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
-}
+x = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode);
+
   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
   aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
@@ -19100,8 +19100,7 @@ aarch64_split_compare_and_swap (rtx operands[])
{
  /* Emit an explicit compare instruction, so that we can correctly
 track the condition codes.  */
- rtx cc_reg = aarch64_gen_compare_reg (NE, scratch, const0_rtx);
- x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
+ x = aarch64_gen_compare_reg (NE, scratch,

[PATCH v4 01/12] aarch64: Provide expander for sub3_compare1

2020-04-09 Thread Richard Henderson via Gcc-patches
In one place we open-code a special case of this pattern into the
more specific sub3_compare1_imm, and miss this special case
in other places.  Centralize that special case into an expander.

* config/aarch64/aarch64.md (*sub3_compare1): Rename
from sub3_compare1.
(sub3_compare1): New expander.
(usubv4): Use aarch64_plus_operand for operand2.
* config/aarch64/aarch64.c (aarch64_expand_subvti): Remove
call to gen_subdi3_compare1_imm.
---
 gcc/config/aarch64/aarch64.c  | 11 ++-
 gcc/config/aarch64/aarch64.md | 24 +---
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4af562a81ea..ce306a10de6 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -20797,16 +20797,9 @@ aarch64_expand_subvti (rtx op0, rtx low_dest, rtx 
low_in1,
 }
   else
 {
-  if (aarch64_plus_immediate (low_in2, DImode))
-   emit_insn (gen_subdi3_compare1_imm (low_dest, low_in1, low_in2,
-   GEN_INT (-INTVAL (low_in2;
-  else
-   {
- low_in2 = force_reg (DImode, low_in2);
- emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2));
-   }
-  high_in2 = force_reg (DImode, high_in2);
+  emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2));
 
+  high_in2 = force_reg (DImode, high_in2);
   if (unsigned_p)
emit_insn (gen_usubdi3_carryinC (high_dest, high_in1, high_in2));
   else
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index c7c4d1dd519..728c63bd8d6 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2966,13 +2966,12 @@
 (define_expand "usubv4"
   [(match_operand:GPI 0 "register_operand")
(match_operand:GPI 1 "aarch64_reg_or_zero")
-   (match_operand:GPI 2 "aarch64_reg_or_zero")
+   (match_operand:GPI 2 "aarch64_plus_operand")
(label_ref (match_operand 3 "" ""))]
   ""
 {
   emit_insn (gen_sub3_compare1 (operands[0], operands[1], operands[2]));
   aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
-
   DONE;
 })
 
@@ -3119,7 +3118,7 @@
   [(set_attr "type" "alus_imm")]
 )
 
-(define_insn "sub3_compare1"
+(define_insn "*sub3_compare1"
   [(set (reg:CC CC_REGNUM)
(compare:CC
  (match_operand:GPI 1 "aarch64_reg_or_zero" "rkZ")
@@ -3131,6 +3130,25 @@
   [(set_attr "type" "alus_sreg")]
 )
 
+(define_expand "sub3_compare1"
+  [(parallel
+[(set (reg:CC CC_REGNUM)
+ (compare:CC
+   (match_operand:GPI 1 "aarch64_reg_or_zero")
+   (match_operand:GPI 2 "aarch64_plus_operand")))
+ (set (match_operand:GPI 0 "register_operand")
+ (minus:GPI (match_dup 1) (match_dup 2)))])]
+  ""
+{
+  if (CONST_SCALAR_INT_P (operands[2]))
+{
+  emit_insn (gen_sub3_compare1_imm
+(operands[0], operands[1], operands[2],
+ GEN_INT (-INTVAL (operands[2];
+  DONE;
+}
+})
+
 (define_peephole2
   [(set (match_operand:GPI 0 "aarch64_general_reg")
(minus:GPI (match_operand:GPI 1 "aarch64_reg_or_zero")
-- 
2.20.1



[PATCH v4 09/12] aarch64: Use CC_NOTCmode for double-word subtract

2020-04-09 Thread Richard Henderson via Gcc-patches
We have been using CCmode, which is not correct for this case.
Mirror the same code from the arm target.

* config/aarch64/aarch64.c (aarch64_select_cc_mode):
Recognize usub*_carryinC patterns.
* config/aarch64/aarch64.md (usubvti4): Use CC_NOTC.
(usub3_carryinC): Likewise.
(*usub3_carryinC_z1): Likewise.
(*usub3_carryinC_z2): Likewise.
(*usub3_carryinC): Likewise.
---
 gcc/config/aarch64/aarch64.c  |  9 +
 gcc/config/aarch64/aarch64.md | 18 +-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index c09b7bcb7f0..d80afc36889 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9532,6 +9532,15 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   && const_dword_umaxp1 (y, mode_x))
 return CC_NOTCmode;
 
+  /* A test for unsigned overflow from a subtract with borrow.  */
+  if ((mode_x == DImode || mode_x == TImode)
+  && (code == GEU || code == LTU)
+  && code_x == ZERO_EXTEND
+  && ((GET_CODE (y) == PLUS
+  && aarch64_borrow_operation (XEXP (y, 0), mode_x))
+ || aarch64_borrow_operation (y, mode_x)))
+return CC_NOTCmode;
+
   /* A test for signed overflow.  */
   if ((mode_x == DImode || mode_x == TImode)
   && (code == NE || code == EQ)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 7d4a63f9a2a..a0a872c6d94 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2954,7 +2954,7 @@
   CODE_FOR_subdi3_compare1,
   CODE_FOR_subdi3_compare1,
   CODE_FOR_usubdi3_carryinC);
-  aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
+  aarch64_gen_unlikely_cbranch (LTU, CC_NOTCmode, operands[3]);
   DONE;
 })
 
@@ -3367,8 +3367,8 @@
 
 (define_expand "usub3_carryinC"
   [(parallel
- [(set (reg:CC CC_REGNUM)
-  (compare:CC
+ [(set (reg:CC_NOTC CC_REGNUM)
+  (compare:CC_NOTC
 (zero_extend:
   (match_operand:GPI 1 "aarch64_reg_or_zero"))
 (plus:
@@ -3383,8 +3383,8 @@
 )
 
 (define_insn "*usub3_carryinC_z1"
-  [(set (reg:CC CC_REGNUM)
-   (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+   (compare:CC_NOTC
  (const_int 0)
  (plus:
(zero_extend:
@@ -3400,8 +3400,8 @@
 )
 
 (define_insn "*usub3_carryinC_z2"
-  [(set (reg:CC CC_REGNUM)
-   (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+   (compare:CC_NOTC
  (zero_extend:
(match_operand:GPI 1 "register_operand" "r"))
  (match_operand: 2 "aarch64_borrow_operation" "")))
@@ -3415,8 +3415,8 @@
 )
 
 (define_insn "*usub3_carryinC"
-  [(set (reg:CC CC_REGNUM)
-   (compare:CC
+  [(set (reg:CC_NOTC CC_REGNUM)
+   (compare:CC_NOTC
  (zero_extend:
(match_operand:GPI 1 "register_operand" "r"))
  (plus:
-- 
2.20.1



[PATCH v4 06/12] aarch64: Introduce aarch64_expand_addsubti

2020-04-09 Thread Richard Henderson via Gcc-patches
Modify aarch64_expand_subvti into a form that handles all
addition and subtraction, modulo, signed or unsigned overflow.

Use expand_insn to put the operands into the proper form,
and do not force values into register if not required.

* config/aarch64/aarch64.c (aarch64_ti_split) New.
(aarch64_addti_scratch_regs): Remove.
(aarch64_subvti_scratch_regs): Remove.
(aarch64_expand_subvti): Remove.
(aarch64_expand_addsubti): New.
* config/aarch64/aarch64-protos.h: Update to match.
* config/aarch64/aarch64.md (addti3): Use aarch64_expand_addsubti.
(addvti4, uaddvti4): Likewise.
(subvti4, usubvti4): Likewise.
(subti3): Likewise; accept immediates for operand 2.
---
 gcc/config/aarch64/aarch64-protos.h |  10 +--
 gcc/config/aarch64/aarch64.c| 129 +---
 gcc/config/aarch64/aarch64.md   | 125 ++-
 3 files changed, 67 insertions(+), 197 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 9e43adb7db0..787d67d62e0 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -630,16 +630,8 @@ void aarch64_reset_previous_fndecl (void);
 bool aarch64_return_address_signing_enabled (void);
 bool aarch64_bti_enabled (void);
 void aarch64_save_restore_target_globals (tree);
-void aarch64_addti_scratch_regs (rtx, rtx, rtx *,
-rtx *, rtx *,
-rtx *, rtx *,
-rtx *);
-void aarch64_subvti_scratch_regs (rtx, rtx, rtx *,
- rtx *, rtx *,
- rtx *, rtx *, rtx *);
-void aarch64_expand_subvti (rtx, rtx, rtx,
-   rtx, rtx, rtx, rtx, bool);
 
+void aarch64_expand_addsubti (rtx, rtx, rtx, int, int, int);
 
 /* Initialize builtins for SIMD intrinsics.  */
 void init_aarch64_simd_builtins (void);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 36e9ebb468a..cd4dc1ef6f9 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -20706,110 +20706,61 @@ aarch64_gen_unlikely_cbranch (enum rtx_code code, 
machine_mode cc_mode,
   aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
 }
 
-/* Generate DImode scratch registers for 128-bit (TImode) addition.
+/* Generate DImode scratch registers for 128-bit (TImode) add/sub.
+   INPUT represents the TImode input operand
+   LO represents the low half (DImode) of the TImode operand
+   HI represents the high half (DImode) of the TImode operand.  */
 
-   OP1 represents the TImode destination operand 1
-   OP2 represents the TImode destination operand 2
-   LOW_DEST represents the low half (DImode) of TImode operand 0
-   LOW_IN1 represents the low half (DImode) of TImode operand 1
-   LOW_IN2 represents the low half (DImode) of TImode operand 2
-   HIGH_DEST represents the high half (DImode) of TImode operand 0
-   HIGH_IN1 represents the high half (DImode) of TImode operand 1
-   HIGH_IN2 represents the high half (DImode) of TImode operand 2.  */
-
-void
-aarch64_addti_scratch_regs (rtx op1, rtx op2, rtx *low_dest,
-   rtx *low_in1, rtx *low_in2,
-   rtx *high_dest, rtx *high_in1,
-   rtx *high_in2)
+static void
+aarch64_ti_split (rtx input, rtx *lo, rtx *hi)
 {
-  *low_dest = gen_reg_rtx (DImode);
-  *low_in1 = gen_lowpart (DImode, op1);
-  *low_in2 = simplify_gen_subreg (DImode, op2, TImode,
- subreg_lowpart_offset (DImode, TImode));
-  *high_dest = gen_reg_rtx (DImode);
-  *high_in1 = gen_highpart (DImode, op1);
-  *high_in2 = simplify_gen_subreg (DImode, op2, TImode,
-  subreg_highpart_offset (DImode, TImode));
+  *lo = simplify_gen_subreg (DImode, input, TImode,
+subreg_lowpart_offset (DImode, TImode));
+  *hi = simplify_gen_subreg (DImode, input, TImode,
+subreg_highpart_offset (DImode, TImode));
 }
 
-/* Generate DImode scratch registers for 128-bit (TImode) subtraction.
-
-   This function differs from 'arch64_addti_scratch_regs' in that
-   OP1 can be an immediate constant (zero). We must call
-   subreg_highpart_offset with DImode and TImode arguments, otherwise
-   VOIDmode will be used for the const_int which generates an internal
-   error from subreg_size_highpart_offset which does not expect a size of zero.
-
-   OP1 represents the TImode destination operand 1
-   OP2 represents the TImode destination operand 2
-   LOW_DEST represents the low half (DImode) of TImode operand 0
-   LOW_IN1 represents the low half (DImode) of TImode operand 1
-   LOW_IN2 represents the low half (DImode) of TImode operand 2
-   HIGH_DEST represents the high half (DImode) of TImode operand 0
-   HIGH_IN1 represents the high half (DImode) of TImode operand 1
-   HIG

[PATCH v4 08/12] arm: Merge CC_ADC and CC_B to CC_NOTC

2020-04-09 Thread Richard Henderson via Gcc-patches
These CC_MODEs are identical, merge them into a more generic name.

* config/arm/arm-modes.def (CC_NOTC): New.
(CC_ADC, CC_B): Remove.
* config/arm/arm.c (arm_select_cc_mode): Update to match.
(arm_gen_dicompare_reg): Likewise.
(maybe_get_arm_condition_code): Likewise.
* config/arm/arm.md (uaddvdi4): Likewise.
(addsi3_cin_cout_reg, addsi3_cin_cout_imm): Likewise.
(*addsi3_cin_cout_reg_insn): Likewise.
(*addsi3_cin_cout_imm_insn): Likewise.
(addsi3_cin_cout_0, *addsi3_cin_cout_0_insn): Likewise.
(usubvsi3_borrow, usubvsi3_borrow_imm): Likewise.
---
 gcc/config/arm/arm.c | 30 +++---
 gcc/config/arm/arm-modes.def | 12 
 gcc/config/arm/arm.md| 36 ++--
 gcc/config/arm/iterators.md  |  2 +-
 gcc/config/arm/predicates.md |  4 ++--
 5 files changed, 36 insertions(+), 48 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c38776fdad7..145345c2278 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -15669,7 +15669,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
   && CONST_INT_P (y)
   && UINTVAL (y) == 0x8
   && (op == GEU || op == LTU))
-return CC_ADCmode;
+return CC_NOTCmode;
 
   if (GET_MODE (x) == DImode
   && (op == GE || op == LT)
@@ -15685,7 +15685,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
   && ((GET_CODE (y) == PLUS
   && arm_borrow_operation (XEXP (y, 0), DImode))
  || arm_borrow_operation (y, DImode)))
-return CC_Bmode;
+return CC_NOTCmode;
 
   if (GET_MODE (x) == DImode
   && (op == EQ || op == NE)
@@ -15879,18 +15879,18 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, 
rtx scratch)
 
rtx_insn *insn;
if (y_hi == const0_rtx)
- insn = emit_insn (gen_cmpsi3_0_carryin_CC_Bout (scratch, x_hi,
- cmp1));
+ insn = emit_insn (gen_cmpsi3_0_carryin_CC_NOTCout
+   (scratch, x_hi, cmp1));
else if (CONST_INT_P (y_hi))
  {
/* Constant is viewed as unsigned when zero-extended.  */
y_hi = GEN_INT (UINTVAL (y_hi) & 0xULL);
-   insn = emit_insn (gen_cmpsi3_imm_carryin_CC_Bout (scratch, x_hi,
- y_hi, cmp1));
+   insn = emit_insn (gen_cmpsi3_imm_carryin_CC_NOTCout
+ (scratch, x_hi, y_hi, cmp1));
  }
else
- insn = emit_insn (gen_cmpsi3_carryin_CC_Bout (scratch, x_hi, y_hi,
-   cmp1));
+ insn = emit_insn (gen_cmpsi3_carryin_CC_NOTCout
+   (scratch, x_hi, y_hi, cmp1));
return SET_DEST (single_set (insn));
   }
 
@@ -15911,8 +15911,8 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx 
scratch)
 arm_gen_compare_reg (LTU, y_lo, x_lo, scratch),
 const0_rtx);
y_hi = GEN_INT (0x & UINTVAL (y_hi));
-   rtx_insn *insn = emit_insn (gen_rscsi3_CC_Bout_scratch (scratch, y_hi,
-   x_hi, cmp1));
+   rtx_insn *insn = emit_insn (gen_rscsi3_CC_NOTCout_scratch
+   (scratch, y_hi, x_hi, cmp1));
return SET_DEST (single_set (insn));
   }
 
@@ -24511,7 +24511,7 @@ maybe_get_arm_condition_code (rtx comparison)
default: return ARM_NV;
}
 
-case E_CC_Bmode:
+case E_CC_NOTCmode:
   switch (comp_code)
{
case GEU: return ARM_CS;
@@ -24527,14 +24527,6 @@ maybe_get_arm_condition_code (rtx comparison)
default: return ARM_NV;
}
 
-case E_CC_ADCmode:
-  switch (comp_code)
-   {
-   case GEU: return ARM_CS;
-   case LTU: return ARM_CC;
-   default: return ARM_NV;
-   }
-
 case E_CCmode:
 case E_CC_RSBmode:
   switch (comp_code)
diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def
index 6e48223b63d..2495054e066 100644
--- a/gcc/config/arm/arm-modes.def
+++ b/gcc/config/arm/arm-modes.def
@@ -33,18 +33,15 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == 
ARM_FP16_FORMAT_ALTERNATIVE)
CC_Zmode should be used if only the Z flag is set correctly
CC_Cmode should be used if only the C flag is set correctly, after an
  addition.
+   CC_NOTCmode is the inverse of the C flag, after subtraction (borrow),
+ or for ADC where we cannot use the trick of comparing the sum
+ against one of the other operands.
CC_Nmode should be used if only the N (sign) flag is set correctly
CC_NVmode should be used if only the N and V bits are set correctly,
  (used for signed comparisons when the carry is propagated in).
CC_RSBmode should be used where the comparison is set by an RSB

[PATCH v4 05/12] aarch64: Improvements to aarch64_select_cc_mode from arm

2020-04-09 Thread Richard Henderson via Gcc-patches
The arm target has some improvements over aarch64 for
double-word arithmetic and comparisons.

* config/aarch64/aarch64.c (aarch64_select_cc_mode): Check
for swapped operands to CC_Cmode; check for zero_extend to
CC_ADCmode; check for swapped operands to CC_Vmode.
---
 gcc/config/aarch64/aarch64.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f2c14818c79..36e9ebb468a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9521,21 +9521,25 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   if ((mode_x == DImode || mode_x == TImode)
   && (code == LTU || code == GEU)
   && code_x == PLUS
-  && rtx_equal_p (XEXP (x, 0), y))
+  && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
 return CC_Cmode;
 
   /* A test for unsigned overflow from an add with carry.  */
   if ((mode_x == DImode || mode_x == TImode)
   && (code == LTU || code == GEU)
   && code_x == PLUS
+  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
   && const_dword_umaxp1 (y, mode_x))
 return CC_ADCmode;
 
   /* A test for signed overflow.  */
   if ((mode_x == DImode || mode_x == TImode)
-  && code == NE
-  && code_x == PLUS
-  && GET_CODE (y) == SIGN_EXTEND)
+  && (code == NE || code == EQ)
+  && (code_x == PLUS || code_x == MINUS)
+  && (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
+  || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
+  && GET_CODE (y) == SIGN_EXTEND
+  && GET_CODE (XEXP (y, 0)) == GET_CODE (x))
 return CC_Vmode;
 
   /* For everything else, return CCmode.  */
-- 
2.20.1



[PATCH v4 03/12] aarch64: Add cset, csetm, cinc patterns for carry/borrow

2020-04-09 Thread Richard Henderson via Gcc-patches
Some implementations have a higher cost for the csel insn
(and its specializations) than they do for adc/sbc.

* config/aarch64/aarch64.md (*cstore_carry): New.
(*cstoresi_carry_uxtw): New.
(*cstore_borrow): New.
(*cstoresi_borrow_uxtw): New.
(*csinc2_carry): New.
---
 gcc/testsuite/gcc.target/aarch64/asm-flag-1.c |  3 +-
 gcc/config/aarch64/aarch64.md | 51 ++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c 
b/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
index 49901e59c38..b6c21fee306 100644
--- a/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
@@ -21,7 +21,8 @@ void f(char *out)
 
 /* { dg-final { scan-assembler "cset.*, ne" } } */
 /* { dg-final { scan-assembler "cset.*, eq" } } */
-/* { dg-final { scan-assembler "cset.*, cs" } } */
+/* { dg-final { scan-assembler-not "cset.*, cs" } } */
+/* { dg-final { scan-assembler "adc.*, .zr, .zr" } } */
 /* { dg-final { scan-assembler "cset.*, cc" } } */
 /* { dg-final { scan-assembler "cset.*, mi" } } */
 /* { dg-final { scan-assembler "cset.*, pl" } } */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e65f46f0f74..d266a1edd64 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4086,6 +4086,15 @@
   "
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than adc.
+(define_insn "*cstore_carry"
+  [(set (match_operand:ALLI 0 "register_operand" "=r")
+   (match_operand:ALLI 1 "aarch64_carry_operation"))]
+  ""
+  "adc\\t%0, zr, zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "aarch64_cstore"
   [(set (match_operand:ALLI 0 "register_operand" "=r")
(match_operator:ALLI 1 "aarch64_comparison_operator_mode"
@@ -4130,7 +4139,16 @@
   [(set_attr "type" "csel")]
 )
 
-;; zero_extend version of the above
+;; zero_extend versions of the above
+
+(define_insn "*cstoresi_carry_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (zero_extend:DI (match_operand:SI 1 "aarch64_carry_operation")))]
+  ""
+  "adc\\t%w0, wzr, wzr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*cstoresi_insn_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
@@ -4141,6 +4159,15 @@
   [(set_attr "type" "csel")]
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than sbc.
+(define_insn "*cstore_borrow"
+  [(set (match_operand:ALLI 0 "register_operand" "=r")
+   (neg:ALLI (match_operand:ALLI 1 "aarch64_borrow_operation")))]
+  ""
+  "sbc\\t%0, zr, zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "cstore_neg"
   [(set (match_operand:ALLI 0 "register_operand" "=r")
(neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator_mode"
@@ -4150,7 +4177,17 @@
   [(set_attr "type" "csel")]
 )
 
-;; zero_extend version of the above
+;; zero_extend versions of the above
+
+(define_insn "*cstoresi_borrow_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (zero_extend:DI
+ (neg:SI (match_operand:SI 1 "aarch64_borrow_operation"]
+  ""
+  "sbc\\t%w0, wzr, wzr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*cstoresi_neg_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
@@ -4353,6 +4390,16 @@
   [(set_attr "type" "crc")]
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than adc.
+(define_insn "*csinc2_carry"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+   (plus:GPI (match_operand 2 "aarch64_carry_operation")
+  (match_operand:GPI 1 "register_operand" "r")))]
+  ""
+  "adc\\t%0, %1, zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*csinc2_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
-- 
2.20.1



[PATCH v4 04/12] aarch64: Add const_dword_umaxp1

2020-04-09 Thread Richard Henderson via Gcc-patches
Rather than duplicating the rather verbose integral test,
pull it out to a predicate.

* config/aarch64/predicates.md (const_dword_umaxp1): New.
* config/aarch64/aarch64.c (aarch64_select_cc_mode): Use it.
* config/aarch64/aarch64.md (add*add3_carryinC): Likewise.
(*add3_carryinC_zero): Likewise.
(add3_carryinC): Use mode for constant, not TImode.
---
 gcc/config/aarch64/aarch64.c |  5 +
 gcc/config/aarch64/aarch64.md| 16 +++-
 gcc/config/aarch64/predicates.md |  9 +
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index ce306a10de6..f2c14818c79 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9528,10 +9528,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   if ((mode_x == DImode || mode_x == TImode)
   && (code == LTU || code == GEU)
   && code_x == PLUS
-  && CONST_SCALAR_INT_P (y)
-  && (rtx_mode_t (y, mode_x)
- == (wi::shwi (1, mode_x)
- << (GET_MODE_BITSIZE (mode_x).to_constant () / 2
+  && const_dword_umaxp1 (y, mode_x))
 return CC_ADCmode;
 
   /* A test for signed overflow.  */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d266a1edd64..6b21cc9c61b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2659,7 +2659,7 @@
   operands[5] = gen_rtx_LTU (mode, ccin, const0_rtx);
   operands[6] = immed_wide_int_const (wi::shwi (1, mode)
  << GET_MODE_BITSIZE (mode),
- TImode);
+ mode);
 })
 
 (define_insn "*add3_carryinC_zero"
@@ -2668,13 +2668,12 @@
  (plus:
(match_operand: 2 "aarch64_carry_operation" "")
(zero_extend: (match_operand:GPI 1 "register_operand" "r")))
- (match_operand 4 "const_scalar_int_operand" "")))
+ (match_operand: 4 "const_dword_umaxp1" "")))
(set (match_operand:GPI 0 "register_operand" "=r")
(plus:GPI (match_operand:GPI 3 "aarch64_carry_operation" "")
  (match_dup 1)))]
-  "rtx_mode_t (operands[4], mode)
-   == (wi::shwi (1, mode) << (unsigned) GET_MODE_BITSIZE (mode))"
-   "adcs\\t%0, %1, zr"
+  ""
+  "adcs\\t%0, %1, zr"
   [(set_attr "type" "adc_reg")]
 )
 
@@ -2686,15 +2685,14 @@
  (match_operand: 3 "aarch64_carry_operation" "")
  (zero_extend: (match_operand:GPI 1 "register_operand" "r")))
(zero_extend: (match_operand:GPI 2 "register_operand" "r")))
- (match_operand 5 "const_scalar_int_operand" "")))
+ (match_operand: 5 "const_dword_umaxp1" "")))
(set (match_operand:GPI 0 "register_operand" "=r")
(plus:GPI
  (plus:GPI (match_operand:GPI 4 "aarch64_carry_operation" "")
(match_dup 1))
  (match_dup 2)))]
-  "rtx_mode_t (operands[5], mode)
-   == (wi::shwi (1, mode) << (unsigned) GET_MODE_BITSIZE (mode))"
-   "adcs\\t%0, %1, %2"
+  ""
+  "adcs\\t%0, %1, %2"
   [(set_attr "type" "adc_reg")]
 )
 
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 215fcec5955..99c3bfbace4 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -46,6 +46,15 @@
   return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3);
 })
 
+;; True for 1 << (GET_MODE_BITSIZE (mode) / 2)
+;; I.e UINT_MAX + 1 for a given mode, in the double-word mode.
+(define_predicate "const_dword_umaxp1"
+  (match_code "const_int,const_wide_int")
+{
+  unsigned bits = GET_MODE_BITSIZE (mode).to_constant () / 2;
+  return rtx_mode_t (op, mode) == (wi::shwi (1, mode) << bits);
+})
+
 (define_predicate "subreg_lowpart_operator"
   (ior (match_code "truncate")
(and (match_code "subreg")
-- 
2.20.1



[PATCH v4 00/12] aarch64: Implement TImode comparisons

2020-04-09 Thread Richard Henderson via Gcc-patches
This is attacking case 3 of PR 94174.

In v4, I attempt to bring over as many patterns from config/arm
as are applicable.  It's not too far away from what I had from v2.

In the process of checking all of the combinations (below), I
discovered that we could probably have a better represenation
for ccmp.  One that the optimizers can actually do something with,
rather than the if_then_else+unspec combo that we have now.

A special case of that is in the last patch: ccmp_iorne.  I think
it should be possible to come up with some sort of logical combo
that would apply to all cases, but haven't put enough thought
into the problem.


r~


Richard Henderson (12):
  aarch64: Provide expander for sub3_compare1
  aarch64: Match add3_carryin expander and insn
  aarch64: Add cset, csetm, cinc patterns for carry/borrow
  aarch64: Add const_dword_umaxp1
  aarch64: Improvements to aarch64_select_cc_mode from arm
  aarch64: Introduce aarch64_expand_addsubti
  aarch64: Rename CC_ADCmode to CC_NOTCmode
  arm: Merge CC_ADC and CC_B to CC_NOTC
  aarch64: Use CC_NOTCmode for double-word subtract
  aarch64: Adjust result of aarch64_gen_compare_reg
  aarch64: Accept 0 as first argument to compares
  aarch64: Implement TImode comparisons

 gcc/config/aarch64/aarch64-protos.h   |  10 +-
 gcc/config/aarch64/aarch64.c  | 356 -
 gcc/config/arm/arm.c  |  30 +-
 gcc/testsuite/gcc.target/aarch64/asm-flag-1.c |   3 +-
 gcc/config/aarch64/aarch64-modes.def  |   6 +-
 gcc/config/aarch64/aarch64-simd.md|  18 +-
 gcc/config/aarch64/aarch64-speculation.cc |   5 +-
 gcc/config/aarch64/aarch64.md | 473 +++---
 gcc/config/aarch64/iterators.md   |   3 +
 gcc/config/aarch64/predicates.md  |  22 +-
 gcc/config/arm/arm-modes.def  |  12 +-
 gcc/config/arm/arm.md |  36 +-
 gcc/config/arm/iterators.md   |   2 +-
 gcc/config/arm/predicates.md  |   4 +-
 14 files changed, 580 insertions(+), 400 deletions(-)

---

typedef signed long long s64;
typedef unsigned long long u64;
typedef __uint128_t u128;
typedef __int128_t s128;

#define i128(hi,lo) (((u128)(hi) << 64) | (u64)(lo))

int eq(u128 a, u128 b)  { return a == b; }
int ne(u128 a, u128 b)  { return a != b; }
int ltu(u128 a, u128 b) { return a < b; }
int geu(u128 a, u128 b) { return a >= b; }
int leu(u128 a, u128 b) { return a <= b; }
int gtu(u128 a, u128 b) { return a > b; }
int lt(s128 a, s128 b) { return a < b; }
int ge(s128 a, s128 b) { return a >= b; }
int le(s128 a, s128 b) { return a <= b; }
int gt(s128 a, s128 b) { return a > b; }

int eqS(u128 a, u64 b)  { return a == b; }
int neS(u128 a, u64 b)  { return a != b; }
int ltuS(u128 a, u64 b) { return a < b; }
int geuS(u128 a, u64 b) { return a >= b; }
int leuS(u128 a, u64 b) { return a <= b; }
int gtuS(u128 a, u64 b) { return a > b; }
int ltS(s128 a, s64 b) { return a < b; }
int geS(s128 a, s64 b) { return a >= b; }
int leS(s128 a, s64 b) { return a <= b; }
int gtS(s128 a, s64 b) { return a > b; }

int eqSH(u128 a, u64 b)  { return a == (u128)b << 64; }
int neSH(u128 a, u64 b)  { return a != (u128)b << 64; }
int ltuSH(u128 a, u64 b) { return a < (u128)b << 64; }
int geuSH(u128 a, u64 b) { return a >= (u128)b << 64; }
int leuSH(u128 a, u64 b) { return a <= (u128)b << 64; }
int gtuSH(u128 a, u64 b) { return a > (u128)b << 64; }
int ltSH(s128 a, s64 b) { return a < (s128)b << 64; }
int geSH(s128 a, s64 b) { return a >= (s128)b << 64; }
int leSH(s128 a, s64 b) { return a <= (s128)b << 64; }
int gtSH(s128 a, s64 b) { return a > (s128)b << 64; }

int eqFFHS(u128 a, u64 b)  { return a == i128(-1,b); }
int neFFHS(u128 a, u64 b)  { return a != i128(-1,b); }
int ltuFFHS(u128 a, u64 b) { return a < i128(-1,b); }
int geuFFHS(u128 a, u64 b) { return a >= i128(-1,b); }
int leuFFHS(u128 a, u64 b) { return a <= i128(-1,b); }
int gtuFFHS(u128 a, u64 b) { return a > i128(-1,b); }
int ltFFHS(s128 a, s64 b) { return a < (s128)i128(-1,b); }
int geFFHS(s128 a, s64 b) { return a >= (s128)i128(-1,b); }
int leFFHS(s128 a, s64 b) { return a <= (s128)i128(-1,b); }
int gtFFHS(s128 a, s64 b) { return a > (s128)i128(-1,b); }

int eq0(u128 a) { return a == 0; }
int ne0(u128 a) { return a != 0; }
int ltu0(u128 a) { return a < 0; }
int geu0(u128 a) { return a >= 0; }
int leu0(u128 a) { return a <= 0; }
int gtu0(u128 a) { return a > 0; }
int lt0(s128 a) { return a < 0; }
int ge0(s128 a) { return a >= 0; }
int le0(s128 a) { return a <= 0; }
int gt0(s128 a) { return a > 0; }

int eq1(u128 a) { return a == 1; }
int ne1(u128 a) { return a != 1; }
int ltu1(u128 a) { return a < 1; }
int geu1(u128 a) { return a >= 1; }
int leu1(u128 a) { return a <= 1; }
int gtu1(u128 a) { return a > 1; }
int lt1(s128 a) { return a < 1; }
int ge1(s128 a) { return a >= 1; }
int le1(s128 a) { return a <= 1; }
int gt1(s128 a) { return a > 1; }

int eqm1(u128 a) { return a == -1; }
int nem1(u128 a) { r

[PATCH v4 02/12] aarch64: Match add3_carryin expander and insn

2020-04-09 Thread Richard Henderson via Gcc-patches
The expander and insn predicates do not match,
which can lead to insn recognition errors.

* config/aarch64/aarch64.md (add3_carryin):
Use register_operand instead of aarch64_reg_or_zero.
---
 gcc/config/aarch64/aarch64.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 728c63bd8d6..e65f46f0f74 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2600,8 +2600,8 @@
(plus:GPI
  (plus:GPI
(ltu:GPI (reg:CC_C CC_REGNUM) (const_int 0))
-   (match_operand:GPI 1 "aarch64_reg_or_zero"))
- (match_operand:GPI 2 "aarch64_reg_or_zero")))]
+   (match_operand:GPI 1 "register_operand"))
+ (match_operand:GPI 2 "register_operand")))]
""
""
 )
-- 
2.20.1



libgo patch committed: Update to final 1.14.2 release

2020-04-09 Thread Ian Lance Taylor via Gcc-patches
This patch updates libgo to the final 1.14.2 release.  Bootstrapped
and ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
d79a22eddc694970316992927c669dd801e07557
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index b3cc9ecb9d1..138425a19d2 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-b31fbf7d8f23508cfbd578c5c44b13eefd8f359e
+89fbf55a409d37ae898e5c4ea4250035f86bed1b
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/MERGE b/libgo/MERGE
index 4398cd7dc28..8cae45f6b8e 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-edea4a79e8d7dea2456b688f492c8af33d381dc2
+96745b980cfde139e8611772e2bc0c59a8e6cdf7
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go
index 971a756b37d..c2678c3dd3c 100644
--- a/libgo/go/cmd/go/alldocs.go
+++ b/libgo/go/cmd/go/alldocs.go
@@ -2506,13 +2506,21 @@
 // The "go get" command remains permitted to update go.mod even with 
-mod=readonly,
 // and the "go mod" commands do not take the -mod flag (or any other build 
flags).
 //
-// If invoked with -mod=vendor, the go command assumes that the vendor
-// directory holds the correct copies of dependencies and ignores
-// the dependency descriptions in go.mod.
+// If invoked with -mod=vendor, the go command loads packages from the main
+// module's vendor directory instead of downloading modules to and loading 
packages
+// from the module cache. The go command assumes the vendor directory holds
+// correct copies of dependencies, and it does not compute the set of required
+// module versions from go.mod files. However, the go command does check that
+// vendor/modules.txt (generated by 'go mod vendor') contains metadata 
consistent
+// with go.mod.
 //
 // If invoked with -mod=mod, the go command loads modules from the module cache
 // even if there is a vendor directory present.
 //
+// If the go command is not invoked with a -mod flag and the vendor directory
+// is present and the "go" version in go.mod is 1.14 or higher, the go command
+// will act as if it were invoked with -mod=vendor.
+//
 // Pseudo-versions
 //
 // The go.mod file and the go command more generally use semantic versions as
@@ -2710,22 +2718,28 @@
 //
 // Modules and vendoring
 //
-// When using modules, the go command completely ignores vendor directories.
-//
-// By default, the go command satisfies dependencies by downloading modules
-// from their sources and using those downloaded copies (after verification,
-// as described in the previous section). To allow interoperation with older
-// versions of Go, or to ensure that all files used for a build are stored
-// together in a single file tree, 'go mod vendor' creates a directory named
-// vendor in the root directory of the main module and stores there all the
-// packages from dependency modules that are needed to support builds and
-// tests of packages in the main module.
-//
-// To build using the main module's top-level vendor directory to satisfy
-// dependencies (disabling use of the usual network sources and local
-// caches), use 'go build -mod=vendor'. Note that only the main module's
-// top-level vendor directory is used; vendor directories in other locations
-// are still ignored.
+// When using modules, the go command typically satisfies dependencies by
+// downloading modules from their sources and using those downloaded copies
+// (after verification, as described in the previous section). Vendoring may
+// be used to allow interoperation with older versions of Go, or to ensure
+// that all files used for a build are stored together in a single file tree.
+//
+// The command 'go mod vendor' constructs a directory named vendor in the main
+// module's root directory that contains copies of all packages needed to 
support
+// builds and tests of packages in the main module. 'go mod vendor' also
+// creates the file vendor/modules.txt that contains metadata about vendored
+// packages and module versions. This file should be kept consistent with 
go.mod:
+// when vendoring is used, 'go mod vendor' should be run after go.mod is 
updated.
+//
+// If the vendor directory is present in the main module's root directory, it 
will
+// be used automatically if the "go" version in the main module's go.mod file 
is
+// 1.14 or higher. Build commands like 'go build' and 'go test' will load 
packages
+// from the vendor directory instead of accessing the network or the local 
module
+// cache. To explicitly enable vendoring, invoke the go command with the flag
+// -mod=vendor. To disable vendoring, use the flag -mod=mod.
+//
+// Unlike vendoring in GOPATH, the go command ignores vendor directories in
+// locations other than the main module's root directory.
 //
 //
 // Module authentication using go.sum
diff --g

Go patch committed: Look up composite literal keys in global namespace

2020-04-09 Thread Ian Lance Taylor via Gcc-patches
In the Go frontend, a composite literal key may not have a global
definition, so Gogo::define_global_names may not see it.  In order to
correctly handle the case in which a predeclared identifier is used as
a composite literal key, do an explicit check of the global namespace.
The test case is https://golang.org/cl/227783.  Bootstrapped and ran
Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
4c3e7ca2e90b9339a2aca677be568312b9d076d2
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index c5e8b29879e..b3cc9ecb9d1 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-4a31d064fd6996f64b620104e849292af8f25e12
+b31fbf7d8f23508cfbd578c5c44b13eefd8f359e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 42ad93b9830..deac87448f3 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -16032,9 +16032,17 @@ Composite_literal_key_expression::do_lower(Gogo* gogo, 
Named_object*,
   Named_object* no = gogo->lookup(this->name_, NULL);
   if (no == NULL)
 {
-  go_error_at(this->location(), "reference to undefined name %qs",
- Gogo::message_name(this->name_).c_str());
-  return Expression::make_error(this->location());
+  // Gogo::lookup doesn't look in the global namespace, and names
+  // used in composite literal keys aren't seen by
+  // Gogo::define_global_names, so we have to look in the global
+  // namespace ourselves.
+  no = gogo->lookup_global(Gogo::unpack_hidden_name(this->name_).c_str());
+  if (no == NULL)
+   {
+ go_error_at(this->location(), "reference to undefined name %qs",
+ Gogo::message_name(this->name_).c_str());
+ return Expression::make_error(this->location());
+   }
 }
   return Expression::make_unknown_reference(no, this->location());
 }


Re: [PATCH v2 05/11] aarch64: Use UNSPEC_SBCS for subtract-with-borrow + output flags

2020-04-09 Thread Segher Boessenkool
Hi!

On Thu, Apr 02, 2020 at 11:53:47AM -0700, Richard Henderson wrote:
> The rtl description of signed/unsigned overflow from subtract
> was fine, as far as it goes -- we have CC_Cmode and CC_Vmode
> that indicate that only those particular bits are valid.
> 
> However, it's not clear how to extend that description to
> handle signed comparison, where N == V (GE) N != V (LT) are
> the only valid bits.
> 
> Using an UNSPEC means that we can unify all 3 usages without
> fear that combine will try to infer anything from the rtl.
> It also means we need far fewer variants when various inputs
> have constants propagated in, and the rtl folds.
> 
> Accept -1 for the second input by using ADCS.

If you use an unspec anyway, why do you need a separate UNSPEC_SBCS?
It is just the same as UNSPEC_ADCS, with one of the inputs inverted?

Is there any reason to pretend borrows are different from carries?


Segher


[pushed] c++: constexpr static data member instantiation [PR94523]

2020-04-09 Thread Jason Merrill via Gcc-patches
Here due to my recent change to store_init_value we were expanding the
initializer of aw knowing that we were initializing aw.  When
cxx_eval_call_expression finished the constructor, it wanted to look up the
value of aw to set TREE_READONLY on it, but we haven't set DECL_INITIAL yet,
so decl_constant_value tried to instantiate the initializer again.  And
infinite recursion.  Stopped by optimizing the case of asking for the value
of ctx->object, which is ctx->value.  It also would have worked to look in
the values hash table, so let's move that up before decl_constant_value as
well.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-04-09  Jason Merrill  

PR c++/94523
* constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Look at
ctx->object and ctx->global->values first.
---
 gcc/cp/constexpr.c | 13 +
 gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C | 10 ++
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 96497ab85d7..5793430c88d 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5485,6 +5485,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
 CONST_DECL for aggregate constants.  */
   if (lval)
return t;
+  else if (t == ctx->object)
+   return ctx->ctor;
+  if (VAR_P (t))
+   if (tree *p = ctx->global->values.get (t))
+ if (*p != NULL_TREE)
+   {
+ r = *p;
+ break;
+   }
   if (COMPLETE_TYPE_P (TREE_TYPE (t))
  && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
{
@@ -5499,10 +5508,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
   if (TREE_CODE (r) == TARGET_EXPR
  && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
r = TARGET_EXPR_INITIAL (r);
-  if (VAR_P (r))
-   if (tree *p = ctx->global->values.get (r))
- if (*p != NULL_TREE)
-   r = *p;
   if (DECL_P (r))
{
  if (!ctx->quiet)
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C
new file mode 100644
index 000..f39ed216fae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C
@@ -0,0 +1,10 @@
+// PR c++/94523
+// { dg-do compile { target c++14 } }
+
+template  using b = a;
+struct d {
+  char ao;
+  template  constexpr d(ap) : ao{} {}
+};
+template  struct e { static constexpr auto aw = d(au...); };
+template  b ax(e<1>::aw);

base-commit: af19e4d0e23e5f61fc15e44a58bfa3b047854b1e
-- 
2.18.1



[committed] libstdc++: Implement LWG 3324 for [cmp.alg] function objects (LWG 3324)

2020-04-09 Thread Jonathan Wakely via Gcc-patches
LWG 3324 changed the [cmp.alg] types to use std::compare_three_way
instead of the <=> operator, but we were still using the old
specification. In order to make the existing tests pass the N::X type
needs to be equality comparable, so that three_way_comparable is
satisfied and compare_three_way can be used.

As part of this change I noticed that the compare_three_way call
operator was unconditionally noexcept, which is incorrect.

* libsupc++/compare (compare_three_way): Fix noexcept-specifier.
(strong_order, weak_order, partial_order): Replace uses of <=> with
compare_three_way function object (LWG 3324).
* testsuite/18_support/comparisons/algorithms/partial_order.cc: Add
equality operator so that X satisfies three_way_comparable.
* testsuite/18_support/comparisons/algorithms/strong_order.cc:
Likewise.
* testsuite/18_support/comparisons/algorithms/weak_order.cc: Likewise.

Tested powerpc64le-linux, committed to master.


commit 3fd1c229ad10fda68318882329568f400a38fb6d
Author: Jonathan Wakely 
Date:   Thu Apr 9 22:24:57 2020 +0100

libstdc++: Implement LWG 3324 for [cmp.alg] function objects (LWG 3324)

LWG 3324 changed the [cmp.alg] types to use std::compare_three_way
instead of the <=> operator, but we were still using the old
specification. In order to make the existing tests pass the N::X type
needs to be equality comparable, so that three_way_comparable is
satisfied and compare_three_way can be used.

As part of this change I noticed that the compare_three_way call
operator was unconditionally noexcept, which is incorrect.

* libsupc++/compare (compare_three_way): Fix noexcept-specifier.
(strong_order, weak_order, partial_order): Replace uses of <=> with
compare_three_way function object (LWG 3324).
* testsuite/18_support/comparisons/algorithms/partial_order.cc: Add
equality operator so that X satisfies three_way_comparable.
* testsuite/18_support/comparisons/algorithms/strong_order.cc:
Likewise.
* testsuite/18_support/comparisons/algorithms/weak_order.cc: 
Likewise.

diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index b88b691b9e1..37601d32648 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -419,7 +419,8 @@ namespace std
   = __detail::__weakly_eq_cmp_with<_Tp, _Tp>
   && __detail::__partially_ordered_with<_Tp, _Tp>
   && requires(const remove_reference_t<_Tp>& __a,
- const remove_reference_t<_Tp>& __b) {
+ const remove_reference_t<_Tp>& __b)
+  {
{ __a <=> __b } -> __detail::__compares_as<_Cat>;
   };
 
@@ -435,7 +436,8 @@ namespace std
   && __detail::__weakly_eq_cmp_with<_Tp, _Up>
   && __detail::__partially_ordered_with<_Tp, _Up>
   && requires(const remove_reference_t<_Tp>& __t,
- const remove_reference_t<_Up>& __u) {
+ const remove_reference_t<_Up>& __u)
+  {
{ __t <=> __u } -> __detail::__compares_as<_Cat>;
{ __u <=> __t } -> __detail::__compares_as<_Cat>;
   };
@@ -494,7 +496,8 @@ namespace std
 template
   requires three_way_comparable_with<_Tp, _Up>
   constexpr auto
-  operator()(_Tp&& __t, _Up&& __u) const noexcept
+  operator()(_Tp&& __t, _Up&& __u) const
+  noexcept(noexcept(std::declval<_Tp>() <=> std::declval<_Up>()))
   {
if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>)
  {
@@ -579,16 +582,16 @@ namespace std
};
 
 template
-  concept __op_cmp = requires(_Tp&& __t, _Up&& __u)
+  concept __cmp3way = requires(_Tp&& __t, _Up&& __u, compare_three_way __c)
{
- _Ord(static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u));
+ _Ord(__c(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)));
};
 
 template
   concept __strongly_ordered
= __adl_strong<_Tp, _Up>
  // FIXME: || floating_point>
- || __op_cmp;
+ || __cmp3way;
 
 class _Strong_order
 {
@@ -601,8 +604,9 @@ namespace std
  else if constexpr (__adl_strong<_Tp, _Up>)
return noexcept(strong_ordering(strong_order(std::declval<_Tp>(),
 std::declval<_Up>(;
- else if constexpr (__op_cmp)
-   return noexcept(std::declval<_Tp>() <=> std::declval<_Up>());
+ else if constexpr (__cmp3way)
+   return noexcept(compare_three_way()(std::declval<_Tp>(),
+   std::declval<_Up>()));
}
 
   friend class _Weak_order;
@@ -623,8 +627,9 @@ namespace std
  else */ if constexpr (__adl_strong<_Tp, _Up>)
return strong_ordering(strong_order(static_cast<_Tp&&>(__e),
static_cast<_Up&&>(__f)));
-   

introduce target tmpnam and require it in tests relying on it

2020-04-09 Thread Alexandre Oliva


Some target C libraries that aren't recognized as freestanding don't
have filesystem support, so calling tmpnam, fopen/open and
remove/unlink fails to link.

This patch introduces a tmpnam effective target to the testsuite, and
requires it in the tests that call tmpnam.

Tested on x86_64-linux-gnu, and with a cross to arm-eabi.
Ok to install?


for  gcc/testsuite/ChangeLog

* lib/target-supports.exp (check_effective_target_tmpnam): New.
* gcc.c-torture/execute/fprintf-2.c: Require it.
* gcc.c-torture/execute/printf-2.c: Likewise.
* gcc.c-torture/execute/user-printf.c: Likewise.
---
 gcc/testsuite/gcc.c-torture/execute/fprintf-2.c   |1 +
 gcc/testsuite/gcc.c-torture/execute/printf-2.c|1 +
 gcc/testsuite/gcc.c-torture/execute/user-printf.c |1 +
 gcc/testsuite/lib/target-supports.exp |   14 ++
 4 files changed, 17 insertions(+)

diff --git a/gcc/testsuite/gcc.c-torture/execute/fprintf-2.c 
b/gcc/testsuite/gcc.c-torture/execute/fprintf-2.c
index c723867..815109b 100644
--- a/gcc/testsuite/gcc.c-torture/execute/fprintf-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/fprintf-2.c
@@ -1,6 +1,7 @@
 /* Verify that calls to fprintf don't get eliminated even if their
result on success can be computed at compile time (they can fail).
The calls can still be transformed into those of other functions.
+   { dg-require-effective-target tmpnam }
{ dg-prune-output "warning: warning: \[^\n\r\]* possibly used unsafely" }
{ dg-skip-if "requires io" { avr-*-* } }
{ dg-skip-if "requires io" { freestanding } } */
diff --git a/gcc/testsuite/gcc.c-torture/execute/printf-2.c 
b/gcc/testsuite/gcc.c-torture/execute/printf-2.c
index 57f467e..02787ec1 100644
--- a/gcc/testsuite/gcc.c-torture/execute/printf-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/printf-2.c
@@ -2,6 +2,7 @@
result on success can be computed at compile time (they can fail).
The calls can still be transformed into those of other functions.
{ dg-require-effective-target unwrapped }
+   { dg-require-effective-target tmpnam }
{ dg-prune-output "warning: warning: \[^\n\r\]* possibly used unsafely" }
{ dg-skip-if "requires io" { avr-*-* } }
{ dg-skip-if "requires io" { freestanding } } */
diff --git a/gcc/testsuite/gcc.c-torture/execute/user-printf.c 
b/gcc/testsuite/gcc.c-torture/execute/user-printf.c
index 006d99e..5f40f98 100644
--- a/gcc/testsuite/gcc.c-torture/execute/user-printf.c
+++ b/gcc/testsuite/gcc.c-torture/execute/user-printf.c
@@ -2,6 +2,7 @@
don't get eliminated even if their result on success can be computed at
compile time (they can fail).
{ dg-require-effective-target unwrapped }
+   { dg-require-effective-target tmpnam }
{ dg-prune-output "warning: warning: \[^\n\r\]* possibly used unsafely" }
{ dg-skip-if "requires io" { avr-*-* } }
{ dg-skip-if "requires io" { freestanding } } */
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index e42d0ea..8bde03a 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -751,6 +751,20 @@ proc check_effective_target_freestanding { } {
 return 0
 }
 
+# Check to see that tmpnam() and other I/O functions normally used
+# with it are available.
+proc check_effective_target_tmpnam { } {
+return [check_no_compiler_messages tmpnam_available executable {
+#include 
+int main() {
+char *n = tmpnam (NULL);
+FILE *f = fopen (n, "w");
+fclose (f);
+remove (n);
+return 0;
+} } ""]
+}
+
 # Return 1 if target has packed layout of structure members by
 # default, 0 otherwise.  Note that this is slightly different than
 # whether the target has "natural alignment": both attributes may be

-- 
Alexandre Oliva, freedom fighterhe/himhttps://FSFLA.org/blogs/lxo/
Free Software Evangelist  Stallman was right, but he's left :(
GNU Toolchain Engineer   Live long and free, and prosper ethically


Re: [PATCH] c++: make __is_constructible work with paren-init of aggrs [PR94149]

2020-04-09 Thread Jonathan Wakely via Gcc-patches

On 09/04/20 17:00 -0400, Marek Polacek wrote:

In C++20 this is well-formed:

 using T = int[2];
 T t(1, 2);

which means that std::is_constructible_v should be true.
But constructible_expr immediately returned the error_mark_node when it
saw a list with more than one element.  To give accurate results in
C++20, we have to try initializing the aggregate from a parenthesized list of
values.

To not repeat the same mistake as in c++/93790, if there's only one
element, I'm trying {} only when () didn't succeed.  is_constructible5.C
verifies this.

Jon, in paren-init24.C std::is_nothrow_constructible_v doesn't work,
I'm getting
error: invalid 'static_cast' from type 'int' to type 'int [1]'
and
error: functional cast to array type 'int [2]'

Are these the issues you had in mind when we spoke earlier today?


Yes, exactly. I need to add a partial specialization for arrays, which
will just check if the element type is nothrow-constuctible from each
of the argument types.




[PATCH] c++: make __is_constructible work with paren-init of aggrs [PR94149]

2020-04-09 Thread Marek Polacek via Gcc-patches
In C++20 this is well-formed:

  using T = int[2];
  T t(1, 2);

which means that std::is_constructible_v should be true.
But constructible_expr immediately returned the error_mark_node when it
saw a list with more than one element.  To give accurate results in
C++20, we have to try initializing the aggregate from a parenthesized list of
values.

To not repeat the same mistake as in c++/93790, if there's only one
element, I'm trying {} only when () didn't succeed.  is_constructible5.C
verifies this.

Jon, in paren-init24.C std::is_nothrow_constructible_v doesn't work,
I'm getting
 error: invalid 'static_cast' from type 'int' to type 'int [1]'
and
 error: functional cast to array type 'int [2]'

Are these the issues you had in mind when we spoke earlier today?

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

PR c++/94149
* method.c (constructible_expr): In C++20, try using parenthesized
initialization of aggregates to determine the result of
__is_constructible.

* g++.dg/cpp2a/paren-init24.C: New test.
* g++.dg/cpp2a/paren-init25.C: New test.
* g++.dg/ext/is_constructible5.C: New test.
---
 gcc/cp/method.c  | 42 ++--
 gcc/testsuite/g++.dg/cpp2a/paren-init24.C| 26 
 gcc/testsuite/g++.dg/cpp2a/paren-init25.C| 25 
 gcc/testsuite/g++.dg/ext/is_constructible5.C | 16 
 4 files changed, 106 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init24.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init25.C
 create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible5.C

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 9a21bfc1f66..2fb0de288a2 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1799,12 +1799,48 @@ constructible_expr (tree to, tree from)
 {
   if (from == NULL_TREE)
return build_value_init (strip_array_types (to), tf_none);
-  else if (TREE_CHAIN (from))
-   return error_mark_node; // too many initializers
-  from = build_stub_object (TREE_VALUE (from));
+  const int len = list_length (from);
+  if (len > 1)
+   {
+ if (cxx_dialect < cxx2a)
+   /* Too many initializers.  */
+   return error_mark_node;
+
+ /* In C++20 this is well-formed:
+  using T = int[2];
+  T t(1, 2);
+which means that std::is_constructible_v
+should be true.  */
+ vec *v;
+ vec_alloc (v, len);
+ for (tree t = from; t; t = TREE_CHAIN (t))
+   {
+ tree stub = build_stub_object (TREE_VALUE (t));
+ constructor_elt elt = { NULL_TREE, stub };
+ v->quick_push (elt);
+   }
+ from = build_constructor (init_list_type_node, v);
+ CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (from) = true;
+   }
+  else
+   from = build_stub_object (TREE_VALUE (from));
   expr = perform_direct_initialization_if_possible (to, from,
/*cast*/false,
tf_none);
+  /* If t(e) didn't work, maybe t{e} will.  */
+  if (expr == NULL_TREE
+ && len == 1
+ && cxx_dialect >= cxx2a)
+   {
+ from = build_constructor_single (init_list_type_node, NULL_TREE,
+  from);
+ CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (from) = true;
+ expr = perform_direct_initialization_if_possible (to, from,
+   /*cast*/false,
+   tf_none);
+   }
 }
   return expr;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/paren-init24.C 
b/gcc/testsuite/g++.dg/cpp2a/paren-init24.C
new file mode 100644
index 000..a636a28ee6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/paren-init24.C
@@ -0,0 +1,26 @@
+// PR c++/94149 - make __is_constructible work with paren-init of aggrs.
+// { dg-do compile { target c++2a } }
+
+#include 
+
+int main()
+{
+  using T = int[1];
+  T t(1);
+
+  static_assert(__is_constructible(T, int));
+  static_assert(!__is_constructible(T, int, int));
+  static_assert(std::is_constructible_v);
+  //FIXME: libstdc++ problem?
+  //static_assert(std::is_nothrow_constructible_v);
+
+  using T2 = int[2];
+  T2 t2(1);
+  T2 t3(1, 2);
+
+  static_assert(__is_constructible(T2, int));
+  static_assert(__is_constructible(T2, int, int));
+  static_assert(std::is_constructible_v);
+  // FIXME libstdc++ problem?
+  //static_assert(std::is_nothrow_constructible_v);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/paren-init25.C 
b/gcc/testsuite/g++.dg/cpp2a/paren-init25.C
new file mode 100644
index 000..53855a9ef9e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/paren-init25.C
@@ -0,0 +1,25 @@

Re: [PATCH, Fortran] -- PR fortran/87923 -- fix ICE when resolving I/O tags and simplify io.c

2020-04-09 Thread Fritz Reese via Gcc-patches
Tobias,

Thanks very much for the review.

On Thu, Apr 9, 2020 at 5:21 AM Tobias Burnus  wrote:
>
> Hi,
>
> On 4/6/20 7:25 PM, Fritz Reese via Fortran wrote:
>
> > The attached patch fixes PR 87923 while also simplifying the code in
> > io.c.
>
> Thanks for the work, which looks great; it is a bit lengthy
> but mostly moving code or mechanical (%C → %L).
> It also has an impressive amount of new test cases!

I also wished the patch could be easier on the eyes, but alas
sometimes this is the price of progress. :-)

> * First line in git commit "Fix fortran/87923 -- ICE(s) when resolving I/O 
> tags."
>It helps with doing patch archeology if they are the same – or if the GIT 
> one
>is a substring of the email subject. (If it is about a PR, searching for 
> the PR
>usually works, but also not al emails have the PR number in the subject.)
>For this patch, you use:
>email: "[PATCH, Fortran] -- PR fortran/87923 -- fix ICE when resolving I/O 
> tags and simplify io.c"
>GIT: "Fix fortran/87923 -- ICE(s) when resolving I/O tags."

Yes, that is a good point. I will alter the commit summary to match
the email subject.

> * Please check whether the ChangeLog lines are too long; I didn't count
>but it looks as if they might be too long. For sure, they
>were too long for your mail program …

I copied the git commit message from the log, which git formats with
an extra level of indentation. I wrapped the raw ChangeLog entries and
commit message to 80 characters, but after the extra indentation my
mail client indeed wrapped the lines during post-processing. I suppose
I should wrap these each to 76 to account for git's indentation. That
certainly makes "git log" look better.

> * In the following comment, you have two empty tailing lines:
>
> +   Tag expressions are already resolved by resolve_tag, which includes
> +   verifying the type, that they are scalar, and verifying that BT_CHARACTER
> +   tags are of default kind.
> +
> +   */

Oops!


I will commit the patch with these fixes rebased on master after one
final build+test. Thanks again for taking a look.

Cheers,

---
Fritz Reese


Re: [PATCH] cselib, var-tracking: Improve debug info after the cselib sp tracking changes [PR94495]

2020-04-09 Thread Christophe Lyon via Gcc-patches
Hi Jakub,

On Thu, 9 Apr 2020 at 17:06, Richard Biener  wrote:
>
> On Thu, 9 Apr 2020, Alexandre Oliva wrote:
>
> > On Apr  9, 2020, Jakub Jelinek  wrote:
> >
> > > 2020-04-09  Jakub Jelinek  
> >
> > > PR debug/94495
> > > * cselib.h (cselib_record_sp_cfa_base_equiv,
> > > cselib_sp_derived_value_p): Declare.
> > > * cselib.c (cselib_record_sp_cfa_base_equiv,
> > > cselib_sp_derived_value_p): New functions.
> > > * var-tracking.c (add_stores): Don't record MO_VAL_SET for
> > > cselib_sp_derived_value_p values.
> > > (vt_initialize): Call cselib_record_sp_cfa_base_equiv at the
> > > start of extended basic blocks other than the first one
> > > for !frame_pointer_needed functions.
> >
> > Beautiful, thanks!
>
> Thus OK.
>

This patch makes GCC fail to build newlib when configured for
aarch64_be-none-elf:
0x10c488c vt_expand_var_loc_chain

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8355
0x10c488c vt_expand_loc_callback

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8551
0x8a0aa4 cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1881
0x8a2b5e cselib_expand_value_rtx_cb(rtx_def*, bitmap_head*, int,
rtx_def* (*)(rtx_def*, bitmap_head*, int, void*), void*)

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1727
0x10c412a vt_expand_loc_callback

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8487
0x8a09c1 cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1846
0x8a2b5e cselib_expand_value_rtx_cb(rtx_def*, bitmap_head*, int,
rtx_def* (*)(rtx_def*, bitmap_head*, int, void*), void*)

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1727
0x10c4426 vt_expand_var_loc_chain

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8389
0x10c4426 vt_expand_loc_callback

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8551
0x8a0aa4 cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1881
0x8a2b5e cselib_expand_value_rtx_cb(rtx_def*, bitmap_head*, int,
rtx_def* (*)(rtx_def*, bitmap_head*, int, void*), void*)

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1727
0x10c4426 vt_expand_var_loc_chain

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8389
0x10c4426 vt_expand_loc_callback

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8551
0x8a0aa4 cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1881
0x8a07fc cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1919
0x8a07fc cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1919
0x8a2b5e cselib_expand_value_rtx_cb(rtx_def*, bitmap_head*, int,
rtx_def* (*)(rtx_def*, bitmap_head*, int, void*), void*)

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1727
0x10c4426 vt_expand_var_loc_chain

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8389
0x10c4426 vt_expand_loc_callback

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/var-tracking.c:8551
0x8a0aa4 cselib_expand_value_rtx_1

/tmp/9192639_9.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cselib.c:1881
make[7]: *** [Makefile:824: lib_a-ldtoa.o] Error 1
make[7]: *** Waiting for unfinished jobs
make[7]: Leaving directory
'/tmp/9192639_9.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64_be-none-elf/newlib/aarch64_be-none-elf/ilp32/newlib/libc/stdlib'

Christophe


> Richard.
>
> --
> Richard Biener 
> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
> Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)


Re: [PATCH] reject scalar array initialization with nullptr [PR94510]

2020-04-09 Thread Martin Sebor via Gcc-patches

On 4/9/20 1:32 PM, Jason Merrill wrote:

On 4/9/20 3:24 PM, Martin Sebor wrote:

On 4/9/20 1:03 PM, Jason Merrill wrote:

On 4/8/20 1:23 PM, Martin Sebor wrote:

On 4/7/20 3:36 PM, Marek Polacek wrote:

On Tue, Apr 07, 2020 at 02:46:52PM -0600, Martin Sebor wrote:

On 4/7/20 1:50 PM, Marek Polacek wrote:
On Tue, Apr 07, 2020 at 12:50:48PM -0600, Martin Sebor via 
Gcc-patches wrote:

Among the numerous regressions introduced by the change committed
to GCC 9 to allow string literals as template arguments is a 
failure
to recognize the C++ nullptr and GCC's __null constants as 
pointers.
For one, I didn't realize that nullptr, being a null pointer 
constant,
doesn't have a pointer type, and two, I didn't think of __null 
(which

is a special integer constant that NULL sometimes expands to).

The attached patch adjusts the special handling of trailing zero
initializers in reshape_init_array_1 to recognize both kinds of
constants and avoid treating them as zeros of the array integer
element type.  This restores the expected diagnostics when either
constant is used in the initializer list.

Martin


PR c++/94510 - nullptr_t implicitly cast to zero twice in 
std::array


gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all 
kinds

of pointers.

gcc/testsuite/ChangeLog:

PR c++/94510
* g++.dg/init/array57.C: New test.
* g++.dg/init/array58.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..692c8ed73f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree 
max_index, reshape_iter *d,

   TREE_CONSTANT (new_init) = false;
 /* Pointers initialized to strings must be treated as 
non-zero

- even if the string is empty.  */
+ even if the string is empty.  Handle all kinds of pointers,
+ including std::nullptr and GCC's __nullptr, neither of which
+ has a pointer type.  */
 tree init_type = TREE_TYPE (elt_init);
-  if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+  bool init_is_ptr = (POINTER_TYPE_P (init_type)
+  || NULLPTR_TYPE_P (init_type)
+  || null_node_p (elt_init));
+  if (POINTER_TYPE_P (elt_type) != init_is_ptr
 || !type_initializer_zero_p (elt_type, elt_init))
   last_nonzero = index;


It looks like this still won't handle e.g. pointers to member 
functions,

e.g.

struct S { };
int arr[3] = { (void (S::*) ()) 0, 0, 0 };

would still be accepted.  You could use TYPE_PTR_OR_PTRMEM_P 
instead of

POINTER_TYPE_P to catch this case.


Good catch!  That doesn't fail because unlike null data member 
pointers

which are represented as -1, member function pointers are represented
as a zero.

I had looked for an API that would answer the question: "is this
expression a pointer?" without having to think of all the different
kinds of them but all I could find was null_node_p().  Is this a 
rare,

isolated case that having an API like that wouldn't be worth having
or should I add one like in the attached update?

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all 
kinds

of pointers.
* gcc/cp/cp-tree.h (null_pointer_constant_p): New function.


(Drop the gcc/cp/.)


+/* Returns true if EXPR is a null pointer constant of any type.  */
+
+inline bool
+null_pointer_constant_p (tree expr)
+{
+  STRIP_ANY_LOCATION_WRAPPER (expr);
+  if (expr == null_node)
+    return true;
+  tree type = TREE_TYPE (expr);
+  if (NULLPTR_TYPE_P (type))
+    return true;
+  if (POINTER_TYPE_P (type))
+    return integer_zerop (expr);
+  return null_member_pointer_value_p (expr);
+}
+


We already have a null_ptr_cst_p so it would be sort of confusing 
to have
this as well.  But are you really interested in whether it's a null 
pointer,

not just a pointer?


The goal of the code is to detect a mismatch in "pointerness" between
an initializer expression and the type of the initialized element, so
it needs to know if the expression is a pointer (non-nulls pointers
are detected in type_initializer_zero_p).  That means testing a number
of IMO unintuitive conditions:

   TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (expr))
   || NULLPTR_TYPE_P (TREE_TYPE (expr))
   || null_node_p (expr)

I don't know if this type of a query is common in the C++ FE but unless
this is an isolated use case then besides fixing the bug I thought it
would be nice to make it easier to get the test above right, or at 
least

come close to it.

Since null_pointer_constant_p already exists (but isn't suitable here
because it returns true for plain literal zeros)


Why is that unsuitable?  A literal zero is a perfectly good 
zero-initializer for a pointer.


Right, that's why it's not suitable here.  Because a literal zero
is also not a pointer.

The question the code asks is: "is the initializer expression
a poin

[committed] libstdc++: Add comparison operators to std::unique_ptr

2020-04-09 Thread Jonathan Wakely via Gcc-patches

Some more C++20 changes from P1614R2, "The Mothership has Landed".

This includes the proposed resolution for LWG 3426 to fix the three-way
comparison with nullptr_t.

The existing tests for unique_ptr comparisons don't actually check the
results, only that the expressions compile and are convertible to bool.
This also adds a test for the results of those comparisons for C++11 and
up.

* include/bits/unique_ptr.h (operator<=>): Define for C++20.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust dg-error line.
* testsuite/20_util/default_delete/void_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/comparison/compare.cc: New test.
* testsuite/20_util/unique_ptr/comparison/compare_c++20.cc: New test.

Tested powerpc64le-linux, committed to master.

commit 5b074864f8c593fd4bccee788a023a37b446b2ed
Author: Jonathan Wakely 
Date:   Thu Apr 9 21:10:32 2020 +0100

libstdc++: Add comparison operators to std::unique_ptr

Some more C++20 changes from P1614R2, "The Mothership has Landed".

This includes the proposed resolution for LWG 3426 to fix the three-way
comparison with nullptr_t.

The existing tests for unique_ptr comparisons don't actually check the
results, only that the expressions compile and are convertible to bool.
This also adds a test for the results of those comparisons for C++11 and
up.

* include/bits/unique_ptr.h (operator<=>): Define for C++20.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust dg-error line.
* testsuite/20_util/default_delete/void_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/comparison/compare.cc: New test.
* testsuite/20_util/unique_ptr/comparison/compare_c++20.cc: New test.

diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index d03266c1878..53c8def627d 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -37,6 +37,9 @@
 #include 
 #include 
 #include 
+#if __cplusplus > 201703L
+# include 
+#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -756,6 +759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
 { return !__x; }
 
+#ifndef __cpp_lib_three_way_comparison
   /// unique_ptr comparison with nullptr
   template
 _GLIBCXX_NODISCARD inline bool
@@ -781,6 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_NODISCARD inline bool
 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
 { return (bool)__x; }
+#endif // three way comparison
 
   /// Relational operator for unique_ptr objects, compares the owned pointers
   template=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
 { return !(nullptr < __x); }
+
+#ifdef __cpp_lib_three_way_comparison
+  template
+requires three_way_comparable_with::pointer,
+   typename unique_ptr<_Up, _Ep>::pointer>
+compare_three_way_result_t::pointer,
+			   typename unique_ptr<_Up, _Ep>::pointer>
+operator<=>(const unique_ptr<_Tp, _Dp>& __x,
+		const unique_ptr<_Up, _Ep>& __y)
+{ return compare_three_way()(__x.get(), __y.get()); }
+
+  template
+requires three_way_comparable::pointer>
+compare_three_way_result_t::pointer>
+operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
+{
+  using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
+  return compare_three_way()(__x.get(), pointer(nullptr));
+}
+#endif
   // @} relates unique_ptr
 
   /// @cond undocumented
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
index 57d7e62c310..6da5a52e28b 100644
--- a/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/default_delete/48631_neg.cc
@@ -26,4 +26,4 @@ struct D : B { };
 D d;
 std::default_delete db;
 typedef decltype(db(&d)) type; // { dg-error "no match" }
-// { dg-error "no type" "" { target *-*-* } 112 }
+// { dg-error "no type" "" { target *-*-* } 115 }
diff --git a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
index 0c5a09e1e9d..149b699d106 100644
--- a/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/default_delete/void_neg.cc
@@ -25,5 +25,5 @@ void test01()
 {
   std::default_delete d;
   d(nullptr);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 77 }
+  // { dg-error "incomplete" "" { target *-*-* } 80 }
 }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/comparison/compare.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/comparison/compare.cc
new file mode 100644
index 000..e293b27904e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/comparison/compare.cc
@@ -0,0 +1,88 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is pa

[COMMITTED] MSP430: Indiciate that the epilogue_helper insn does not fallthru

2020-04-09 Thread Jozef Lawrynowicz
The attached patch fixes an ICE in rtl_verify_fallthru, at cfgrtl.c:2970
gcc.c-torture/execute/20071210-1.c for -mcpu=msp430 at -O2
and above.

The epilogue_helper insn was treated as a regular insn which will
fallthru, so when a barrier is emitted after it, RTL verification failed
as rtl_verify_fallthru.

Successfully regtested for msp430-elf in the default, -mcpu=msp430 and -mlarge
configurations.

Committed as obvious.
>From 07432a807ede1c629f0f52aa5f8bf00012929e88 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz 
Date: Thu, 9 Apr 2020 20:52:20 +0100
Subject: [PATCH] MSP430: Indiciate that the epilogue_helper insn does not
 fallthru

This fixes an ICE in rtl_verify_fallthru, at cfgrtl.c:2970
gcc.c-torture/execute/20071210-1.c for -mcpu=msp430 at -O2
and above.

The epilogue_helper insn was treated as a regular insn which will
fallthru, so when a barrier is emitted after it, RTL verification failed
as rtl_verify_fallthru.

gcc/ChangeLog:

2020-04-09  Jozef Lawrynowicz  

	* config/msp430/msp430.c (msp430_expand_epilogue): Use emit_jump_insn
	when to emit the epilogue_helper insn.
	* config/msp430/msp430.md (epilogue_helper): Add a return insn to the
	RTL pattern.
---
 gcc/ChangeLog   | 7 +++
 gcc/config/msp430/msp430.c  | 2 +-
 gcc/config/msp430/msp430.md | 4 +++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5e2290ab1a..bce700e472e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-04-09  Jozef Lawrynowicz  
+
+	* config/msp430/msp430.c (msp430_expand_epilogue): Use emit_jump_insn
+	when to emit the epilogue_helper insn.
+	* config/msp430/msp430.md (epilogue_helper): Add a return insn to the
+	RTL pattern.
+
 2020-04-09  Jakub Jelinek  
 
 	PR debug/94495
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index cde14c83812..e0d2d732ade 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2587,7 +2587,7 @@ msp430_expand_epilogue (int is_eh)
 		 && helper_n > 1
 		 && !is_eh)
 	  {
-	emit_insn (gen_epilogue_helper (GEN_INT (helper_n)));
+	emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n)));
 	return;
 	  }
 	else
diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index 815d122d8a8..b6602fbca66 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -1130,7 +1130,9 @@ (define_expand "epilogue"
   )
 
 (define_insn "epilogue_helper"
-  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)]
+  [(set (pc)
+(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER))
+   (return)]
   ""
   "BR%Q0\t#__mspabi_func_epilog_%J0"
   )
-- 
2.17.1



Re: [PATCH] c++: Stray RESULT_DECLs in result of constexpr function call [PR94034]

2020-04-09 Thread Patrick Palka via Gcc-patches
On Thu, 9 Apr 2020, Jason Merrill wrote:

> On 4/8/20 7:49 PM, Patrick Palka wrote:
> > When evaluating the initializer of 'a' in the following example
> > 
> >struct A { A *p = this; };
> >constexpr A foo() { return {}; }
> >constexpr A a = foo();
> > 
> > the PLACEHOLDER_EXPR for 'this' in the aggregate initializer returned by foo
> > gets resolved to the RESULT_DECL of foo.  But due to guaranteed RVO, the
> > 'this'
> > should really be resolved to '&a'.
> 
> > It seems to me that the right approach would be to immediately resolve the
> > PLACEHOLDER_EXPR to the correct target object during evaluation of 'foo()',
> > so
> > that we could use 'this' to access objects adjacent to the current object in
> > the
> > ultimate storage location.  (I think #c2 of PR c++/94537 is an example of
> > such
> > usage of 'this', which currently doesn't work.  But as #c1 shows we don't
> > seem
> > to handle this case correctly in non-constexpr initialization either.)
> 
> As I commented in the PR, the standard doesn't require this to work because A
> is trivially copyable, and our ABI makes it impossible.  But there's still a
> constexpr bug when we add
> 
> A() = default; A(const A&);
> 
> clang doesn't require the constructors to make this work for constant
> initialization, but similarly can't make it work for non-constant
> initialization.

That makes a lot of sense, thanks for the detailed explanation.

> 
> > I haven't yet been able to make a solution using the above approach work --
> > making sure we use the ultimate object instead of the RESULT_DECL whenever
> > we
> > access ctx->global->values is proving to be tricky and subtle.
> 
> Do we need to go through ctx->global->values?  Would it work for the
> RESULT_DECL case in cxx_eval_constant_expression to go to straight to
> ctx->object or ctx->ctor instead?

I attempted that at some point, but IIRC we still end up not resolving
some RESULT_DECLs because not all of them get processed through
cxx_eval_constant_expression before we manipulate ctx->global->values
with them.  I'll try this approach more carefully and report back with
more specifics.



Re: [PATCH] reject scalar array initialization with nullptr [PR94510]

2020-04-09 Thread Jason Merrill via Gcc-patches

On 4/9/20 3:24 PM, Martin Sebor wrote:

On 4/9/20 1:03 PM, Jason Merrill wrote:

On 4/8/20 1:23 PM, Martin Sebor wrote:

On 4/7/20 3:36 PM, Marek Polacek wrote:

On Tue, Apr 07, 2020 at 02:46:52PM -0600, Martin Sebor wrote:

On 4/7/20 1:50 PM, Marek Polacek wrote:
On Tue, Apr 07, 2020 at 12:50:48PM -0600, Martin Sebor via 
Gcc-patches wrote:

Among the numerous regressions introduced by the change committed
to GCC 9 to allow string literals as template arguments is a failure
to recognize the C++ nullptr and GCC's __null constants as pointers.
For one, I didn't realize that nullptr, being a null pointer 
constant,
doesn't have a pointer type, and two, I didn't think of __null 
(which

is a special integer constant that NULL sometimes expands to).

The attached patch adjusts the special handling of trailing zero
initializers in reshape_init_array_1 to recognize both kinds of
constants and avoid treating them as zeros of the array integer
element type.  This restores the expected diagnostics when either
constant is used in the initializer list.

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all 
kinds

of pointers.

gcc/testsuite/ChangeLog:

PR c++/94510
* g++.dg/init/array57.C: New test.
* g++.dg/init/array58.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..692c8ed73f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree 
max_index, reshape_iter *d,

   TREE_CONSTANT (new_init) = false;
 /* Pointers initialized to strings must be treated as 
non-zero

- even if the string is empty.  */
+ even if the string is empty.  Handle all kinds of pointers,
+ including std::nullptr and GCC's __nullptr, neither of which
+ has a pointer type.  */
 tree init_type = TREE_TYPE (elt_init);
-  if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+  bool init_is_ptr = (POINTER_TYPE_P (init_type)
+  || NULLPTR_TYPE_P (init_type)
+  || null_node_p (elt_init));
+  if (POINTER_TYPE_P (elt_type) != init_is_ptr
 || !type_initializer_zero_p (elt_type, elt_init))
   last_nonzero = index;


It looks like this still won't handle e.g. pointers to member 
functions,

e.g.

struct S { };
int arr[3] = { (void (S::*) ()) 0, 0, 0 };

would still be accepted.  You could use TYPE_PTR_OR_PTRMEM_P 
instead of

POINTER_TYPE_P to catch this case.


Good catch!  That doesn't fail because unlike null data member 
pointers

which are represented as -1, member function pointers are represented
as a zero.

I had looked for an API that would answer the question: "is this
expression a pointer?" without having to think of all the different
kinds of them but all I could find was null_node_p().  Is this a rare,
isolated case that having an API like that wouldn't be worth having
or should I add one like in the attached update?

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all kinds
of pointers.
* gcc/cp/cp-tree.h (null_pointer_constant_p): New function.


(Drop the gcc/cp/.)


+/* Returns true if EXPR is a null pointer constant of any type.  */
+
+inline bool
+null_pointer_constant_p (tree expr)
+{
+  STRIP_ANY_LOCATION_WRAPPER (expr);
+  if (expr == null_node)
+    return true;
+  tree type = TREE_TYPE (expr);
+  if (NULLPTR_TYPE_P (type))
+    return true;
+  if (POINTER_TYPE_P (type))
+    return integer_zerop (expr);
+  return null_member_pointer_value_p (expr);
+}
+


We already have a null_ptr_cst_p so it would be sort of confusing to 
have
this as well.  But are you really interested in whether it's a null 
pointer,

not just a pointer?


The goal of the code is to detect a mismatch in "pointerness" between
an initializer expression and the type of the initialized element, so
it needs to know if the expression is a pointer (non-nulls pointers
are detected in type_initializer_zero_p).  That means testing a number
of IMO unintuitive conditions:

   TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (expr))
   || NULLPTR_TYPE_P (TREE_TYPE (expr))
   || null_node_p (expr)

I don't know if this type of a query is common in the C++ FE but unless
this is an isolated use case then besides fixing the bug I thought it
would be nice to make it easier to get the test above right, or at least
come close to it.

Since null_pointer_constant_p already exists (but isn't suitable here
because it returns true for plain literal zeros)


Why is that unsuitable?  A literal zero is a perfectly good 
zero-initializer for a pointer.


Right, that's why it's not suitable here.  Because a literal zero
is also not a pointer.

The question the code asks is: "is the initializer expression
a pointer (of any kind)?"


Why is that a question we wa

Re: [PATCH] c++: Stray RESULT_DECLs in result of constexpr function call [PR94034]

2020-04-09 Thread Jason Merrill via Gcc-patches

On 4/8/20 7:49 PM, Patrick Palka wrote:

When evaluating the initializer of 'a' in the following example

   struct A { A *p = this; };
   constexpr A foo() { return {}; }
   constexpr A a = foo();

the PLACEHOLDER_EXPR for 'this' in the aggregate initializer returned by foo
gets resolved to the RESULT_DECL of foo.  But due to guaranteed RVO, the 'this'
should really be resolved to '&a'.



It seems to me that the right approach would be to immediately resolve the
PLACEHOLDER_EXPR to the correct target object during evaluation of 'foo()', so
that we could use 'this' to access objects adjacent to the current object in the
ultimate storage location.  (I think #c2 of PR c++/94537 is an example of such
usage of 'this', which currently doesn't work.  But as #c1 shows we don't seem
to handle this case correctly in non-constexpr initialization either.)


As I commented in the PR, the standard doesn't require this to work 
because A is trivially copyable, and our ABI makes it impossible.  But 
there's still a constexpr bug when we add


A() = default; A(const A&);

clang doesn't require the constructors to make this work for constant 
initialization, but similarly can't make it work for non-constant 
initialization.



I haven't yet been able to make a solution using the above approach work --
making sure we use the ultimate object instead of the RESULT_DECL whenever we
access ctx->global->values is proving to be tricky and subtle.


Do we need to go through ctx->global->values?  Would it work for the 
RESULT_DECL case in cxx_eval_constant_expression to go to straight to 
ctx->object or ctx->ctor instead?


Jason



Re: [PATCH] reject scalar array initialization with nullptr [PR94510]

2020-04-09 Thread Martin Sebor via Gcc-patches

On 4/9/20 1:03 PM, Jason Merrill wrote:

On 4/8/20 1:23 PM, Martin Sebor wrote:

On 4/7/20 3:36 PM, Marek Polacek wrote:

On Tue, Apr 07, 2020 at 02:46:52PM -0600, Martin Sebor wrote:

On 4/7/20 1:50 PM, Marek Polacek wrote:
On Tue, Apr 07, 2020 at 12:50:48PM -0600, Martin Sebor via 
Gcc-patches wrote:

Among the numerous regressions introduced by the change committed
to GCC 9 to allow string literals as template arguments is a failure
to recognize the C++ nullptr and GCC's __null constants as pointers.
For one, I didn't realize that nullptr, being a null pointer 
constant,

doesn't have a pointer type, and two, I didn't think of __null (which
is a special integer constant that NULL sometimes expands to).

The attached patch adjusts the special handling of trailing zero
initializers in reshape_init_array_1 to recognize both kinds of
constants and avoid treating them as zeros of the array integer
element type.  This restores the expected diagnostics when either
constant is used in the initializer list.

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all 
kinds

of pointers.

gcc/testsuite/ChangeLog:

PR c++/94510
* g++.dg/init/array57.C: New test.
* g++.dg/init/array58.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..692c8ed73f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree 
max_index, reshape_iter *d,

   TREE_CONSTANT (new_init) = false;
 /* Pointers initialized to strings must be treated as 
non-zero

- even if the string is empty.  */
+ even if the string is empty.  Handle all kinds of pointers,
+ including std::nullptr and GCC's __nullptr, neither of which
+ has a pointer type.  */
 tree init_type = TREE_TYPE (elt_init);
-  if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+  bool init_is_ptr = (POINTER_TYPE_P (init_type)
+  || NULLPTR_TYPE_P (init_type)
+  || null_node_p (elt_init));
+  if (POINTER_TYPE_P (elt_type) != init_is_ptr
 || !type_initializer_zero_p (elt_type, elt_init))
   last_nonzero = index;


It looks like this still won't handle e.g. pointers to member 
functions,

e.g.

struct S { };
int arr[3] = { (void (S::*) ()) 0, 0, 0 };

would still be accepted.  You could use TYPE_PTR_OR_PTRMEM_P 
instead of

POINTER_TYPE_P to catch this case.


Good catch!  That doesn't fail because unlike null data member pointers
which are represented as -1, member function pointers are represented
as a zero.

I had looked for an API that would answer the question: "is this
expression a pointer?" without having to think of all the different
kinds of them but all I could find was null_node_p().  Is this a rare,
isolated case that having an API like that wouldn't be worth having
or should I add one like in the attached update?

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all kinds
of pointers.
* gcc/cp/cp-tree.h (null_pointer_constant_p): New function.


(Drop the gcc/cp/.)


+/* Returns true if EXPR is a null pointer constant of any type.  */
+
+inline bool
+null_pointer_constant_p (tree expr)
+{
+  STRIP_ANY_LOCATION_WRAPPER (expr);
+  if (expr == null_node)
+    return true;
+  tree type = TREE_TYPE (expr);
+  if (NULLPTR_TYPE_P (type))
+    return true;
+  if (POINTER_TYPE_P (type))
+    return integer_zerop (expr);
+  return null_member_pointer_value_p (expr);
+}
+


We already have a null_ptr_cst_p so it would be sort of confusing to 
have
this as well.  But are you really interested in whether it's a null 
pointer,

not just a pointer?


The goal of the code is to detect a mismatch in "pointerness" between
an initializer expression and the type of the initialized element, so
it needs to know if the expression is a pointer (non-nulls pointers
are detected in type_initializer_zero_p).  That means testing a number
of IMO unintuitive conditions:

   TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (expr))
   || NULLPTR_TYPE_P (TREE_TYPE (expr))
   || null_node_p (expr)

I don't know if this type of a query is common in the C++ FE but unless
this is an isolated use case then besides fixing the bug I thought it
would be nice to make it easier to get the test above right, or at least
come close to it.

Since null_pointer_constant_p already exists (but isn't suitable here
because it returns true for plain literal zeros)


Why is that unsuitable?  A literal zero is a perfectly good 
zero-initializer for a pointer.


Right, that's why it's not suitable here.  Because a literal zero
is also not a pointer.

The question the code asks is: "is the initializer expression
a pointer (of any kind)?" and I thought that might be common enough
to justify adding a helper func

Re: [PATCH] reject scalar array initialization with nullptr [PR94510]

2020-04-09 Thread Jason Merrill via Gcc-patches

On 4/8/20 1:23 PM, Martin Sebor wrote:

On 4/7/20 3:36 PM, Marek Polacek wrote:

On Tue, Apr 07, 2020 at 02:46:52PM -0600, Martin Sebor wrote:

On 4/7/20 1:50 PM, Marek Polacek wrote:
On Tue, Apr 07, 2020 at 12:50:48PM -0600, Martin Sebor via 
Gcc-patches wrote:

Among the numerous regressions introduced by the change committed
to GCC 9 to allow string literals as template arguments is a failure
to recognize the C++ nullptr and GCC's __null constants as pointers.
For one, I didn't realize that nullptr, being a null pointer constant,
doesn't have a pointer type, and two, I didn't think of __null (which
is a special integer constant that NULL sometimes expands to).

The attached patch adjusts the special handling of trailing zero
initializers in reshape_init_array_1 to recognize both kinds of
constants and avoid treating them as zeros of the array integer
element type.  This restores the expected diagnostics when either
constant is used in the initializer list.

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all kinds
of pointers.

gcc/testsuite/ChangeLog:

PR c++/94510
* g++.dg/init/array57.C: New test.
* g++.dg/init/array58.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..692c8ed73f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree 
max_index, reshape_iter *d,

   TREE_CONSTANT (new_init) = false;
 /* Pointers initialized to strings must be treated as 
non-zero

- even if the string is empty.  */
+ even if the string is empty.  Handle all kinds of pointers,
+ including std::nullptr and GCC's __nullptr, neither of which
+ has a pointer type.  */
 tree init_type = TREE_TYPE (elt_init);
-  if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+  bool init_is_ptr = (POINTER_TYPE_P (init_type)
+  || NULLPTR_TYPE_P (init_type)
+  || null_node_p (elt_init));
+  if (POINTER_TYPE_P (elt_type) != init_is_ptr
 || !type_initializer_zero_p (elt_type, elt_init))
   last_nonzero = index;


It looks like this still won't handle e.g. pointers to member 
functions,

e.g.

struct S { };
int arr[3] = { (void (S::*) ()) 0, 0, 0 };

would still be accepted.  You could use TYPE_PTR_OR_PTRMEM_P instead of
POINTER_TYPE_P to catch this case.


Good catch!  That doesn't fail because unlike null data member pointers
which are represented as -1, member function pointers are represented
as a zero.

I had looked for an API that would answer the question: "is this
expression a pointer?" without having to think of all the different
kinds of them but all I could find was null_node_p().  Is this a rare,
isolated case that having an API like that wouldn't be worth having
or should I add one like in the attached update?

Martin



PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array

gcc/cp/ChangeLog:

PR c++/94510
* decl.c (reshape_init_array_1): Exclude mismatches with all kinds
of pointers.
* gcc/cp/cp-tree.h (null_pointer_constant_p): New function.


(Drop the gcc/cp/.)


+/* Returns true if EXPR is a null pointer constant of any type.  */
+
+inline bool
+null_pointer_constant_p (tree expr)
+{
+  STRIP_ANY_LOCATION_WRAPPER (expr);
+  if (expr == null_node)
+    return true;
+  tree type = TREE_TYPE (expr);
+  if (NULLPTR_TYPE_P (type))
+    return true;
+  if (POINTER_TYPE_P (type))
+    return integer_zerop (expr);
+  return null_member_pointer_value_p (expr);
+}
+


We already have a null_ptr_cst_p so it would be sort of confusing to have
this as well.  But are you really interested in whether it's a null 
pointer,

not just a pointer?


The goal of the code is to detect a mismatch in "pointerness" between
an initializer expression and the type of the initialized element, so
it needs to know if the expression is a pointer (non-nulls pointers
are detected in type_initializer_zero_p).  That means testing a number
of IMO unintuitive conditions:

   TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (expr))
   || NULLPTR_TYPE_P (TREE_TYPE (expr))
   || null_node_p (expr)

I don't know if this type of a query is common in the C++ FE but unless
this is an isolated use case then besides fixing the bug I thought it
would be nice to make it easier to get the test above right, or at least
come close to it.

Since null_pointer_constant_p already exists (but isn't suitable here
because it returns true for plain literal zeros)


Why is that unsuitable?  A literal zero is a perfectly good 
zero-initializer for a pointer.


Jason



[PATCH] ipa: Make call redirection detect already adjusted calls (PR 93621)

2020-04-09 Thread Martin Jambor
Hi,

PR 93621 testcase makes redirect_call_stmt_to_callee wrongly assume
that a call statement needs redirecting but then rightly fails an
assert ensuring the call statement parameters have not already been
adjusted because they were already created adjusted as part of thunk
expansion.

The test fails because the decl in the call call statement is
different than the decl of the callee, because the latter was created
in save_inline_function_body.  This patch adds a way to link these two
and detect the situation in redirect_call_stmt_to_callee.

I tend to think the deallocation bit is important for JIT, althoug in
the course of normal compilation it happens only just before the
compiler shuts down.

This patch passes bootstrap and LTO bootstrap and testing on
x86_64-linux, LTO profiledbootstrap is underway.  Is it OK the way it is
or do we for example want to move the new summary to ipa-utils so that
we don't have to include ipa-inline in two new files?  Should the
deallocation be someplace else?  Any other comments, preferences,
constructive criticism? :-)

Thanks,

Martin


2020-04-09  Martin Jambor  

PR ipa/93621
* ipa-inline.h (ipa_saved_clone_sources): Declare.
* ipa-inline-transform.c (ipa_saved_clone_sources): New variable.
(save_inline_function_body): Link the new body holder with the
previous one.
* cgraph.c: Include ipa-inline.h.
(cgraph_edge::redirect_call_stmt_to_callee): Try to find the decl from
the statement in ipa_saved_clone_sources.
* cgraphunit.c: Include ipa-inline.h.
(expand_all_functions): Free ipa_saved_clone_sources.
---
 gcc/ChangeLog  | 13 +
 gcc/cgraph.c   | 11 +++
 gcc/cgraphunit.c   |  4 +++-
 gcc/ipa-inline-transform.c | 19 +++
 gcc/ipa-inline.h   |  1 +
 gcc/testsuite/ChangeLog|  5 +
 gcc/testsuite/g++.dg/ipa/pr93621.C | 29 +
 7 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ipa/pr93621.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e10fb251c16..d68f5a68f3e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2020-04-09  Martin Jambor  
+
+   PR ipa/93621
+   * ipa-inline.h (ipa_saved_clone_sources): Declare.
+   * ipa-inline-transform.c (ipa_saved_clone_sources): New variable.
+   (save_inline_function_body): Link the new body holder with the
+   previous one.
+   * cgraph.c: Include ipa-inline.h.
+   (cgraph_edge::redirect_call_stmt_to_callee): Try to find the decl from
+   the statement in ipa_saved_clone_sources.
+   * cgraphunit.c: Include ipa-inline.h.
+   (expand_all_functions): Free ipa_saved_clone_sources.
+
 2020-04-05 Zachary Spytz  
 
* extend.texi: Add free to list of ISO C90 functions that
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 6b780f80eb3..b4b00b3b1c1 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "selftest.h"
 #include "tree-into-ssa.h"
+#include "ipa-inline.h"
 
 /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  
*/
 #include "tree-pass.h"
@@ -1470,6 +1471,16 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge 
*e)
   || decl == e->callee->decl)
 return e->call_stmt;
 
+  if (decl && ipa_saved_clone_sources)
+{
+  cgraph_node **p = ipa_saved_clone_sources->get (e->callee);
+  if (p && decl == (*p)->decl)
+   {
+ gimple_call_set_fndecl (e->call_stmt, e->callee->decl);
+ return e->call_stmt;
+   }
+}
+
   if (flag_checking && decl)
 {
   cgraph_node *node = cgraph_node::get (decl);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0e255f25b7d..a1ace95879a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -205,6 +205,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-section-names.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "ipa-inline.h"
 
 /* Queue of cgraph nodes scheduled to be added into cgraph.  This is a
secondary queue used during optimization to accommodate passes that
@@ -2481,7 +2482,8 @@ expand_all_functions (void)
 
   symtab->process_new_functions ();
   free_gimplify_stack ();
-
+  delete ipa_saved_clone_sources;
+  ipa_saved_clone_sources = NULL;
   free (order);
 }
 
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index eed992d314d..cd64a643506 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -531,6 +531,11 @@ inline_call (struct cgraph_edge *e, bool update_original,
   return new_edges_found;
 }
 
+/* For each node that was made the holder of function body by
+   save_inline_function_body, this summary contains pointer to the previous
+   holder of the body.  */
+
+function_summary  *ipa_saved_clone_sources;
 
 /* C

[PATCH] ipa-sra: Fix treatment of internal functions (PR 94434)

2020-04-09 Thread Martin Jambor
Hi,

On Tue, Apr 07 2020, bule wrote:
> Hi, 
>
> The patch is tested and works fine. It is more appropriate to handle
> the context by considering it as a section of assemble code.
>
> A minor question is that I think svst functions are for store
>operations. Why pass ISRA_CTX_LOAD to scan_expr_access rather than
>ISRA_CTX_STORE?
>

That's a good point, I did not immediately realize that these were
writes.  IPA-SRA really distinguishes between reads and writes only when
it comes to parameters passed by reference but I agree that we should
not lie to the bit of the compiler (if we can avoid it :-).

Therefore I'd like to fix this issue with the patch below.  I'd
encourage anyone with experience with adding SVE testcases to add one
specifically for this.

Thanks,

Martin


ipa-sra: Fix treatment of internal functions (PR 94434)

IPA-SRA can segfault when processing a coll to an internal function
because such calls do not have corresponding call graphs and should be
treated like memory accesses anyway, which what the patch below does.

The patch makes an attempt to differentiate between reads and writes,
although for things passed by value it does not make any difference.  It
treats all arguments of functions denoted with internal_store_fn_p as
written to, even though in practice only some are, but for IPA-SRA
purposes, actions needed to be taken when processing a read are also
always performed when analyzing a write, so the code is just slightly
pessimistic.  But not as pessimistic as bailing out on any internal call
immediately.

I have LTO bootstrapped and tested the patch on x86_64-linux and
normally bootstrapped and tested it on aarch64-linux, although one
which is not SVE capable.  I would appreciate testing on such machine
too - as well as a small testcase that would follow all relevant
conventions in gcc.target/aarch64/sve.

OK for trunk?


2020-04-09  Martin Jambor  

PR ipa/94434
* ipa-sra.c: Include internal-fn.h.
(enum isra_scan_context): Update comment.
(scan_function): Treat calls to internal_functions like loads or stores.
---
 gcc/ChangeLog |  7 +++
 gcc/ipa-sra.c | 26 --
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e10fb251c16..a838634b707 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-04-09  Martin Jambor  
+
+   PR ipa/94434
+   * ipa-sra.c: Include internal-fn.h.
+   (enum isra_scan_context): Update comment.
+   (scan_function): Treat calls to internal_functions like loads or stores.
+
 2020-04-05 Zachary Spytz  
 
* extend.texi: Add free to list of ISO C90 functions that
diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index f0ebaec708d..7c922e40a4e 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -83,7 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "cfganal.h"
 #include "tree-streamer.h"
-
+#include "internal-fn.h"
 
 /* Bits used to track size of an aggregate in bytes interprocedurally.  */
 #define ISRA_ARG_SIZE_LIMIT_BITS 16
@@ -1281,7 +1281,9 @@ allocate_access (gensum_param_desc *desc,
 }
 
 /* In what context scan_expr_access has been called, whether it deals with a
-   load, a function argument, or a store.  */
+   load, a function argument, or a store.  Please note that in rare
+   circumstances when it is not clear if the access is a load or store,
+   ISRA_CTX_STORE is used too.  */
 
 enum isra_scan_context {ISRA_CTX_LOAD, ISRA_CTX_ARG, ISRA_CTX_STORE};
 
@@ -1870,15 +1872,27 @@ scan_function (cgraph_node *node, struct function *fun)
case GIMPLE_CALL:
  {
unsigned argument_count = gimple_call_num_args (stmt);
-   scan_call_info call_info;
-   call_info.cs = node->get_edge (stmt);
-   call_info.argument_count = argument_count;
+   isra_scan_context ctx = ISRA_CTX_ARG;
+   scan_call_info call_info, *call_info_p = &call_info;
+   if (gimple_call_internal_p (stmt))
+ {
+   call_info_p = NULL;
+   ctx = ISRA_CTX_LOAD;
+   internal_fn ifn = gimple_call_internal_fn (stmt);
+   if (internal_store_fn_p (ifn))
+ ctx = ISRA_CTX_STORE;
+ }
+   else
+ {
+   call_info.cs = node->get_edge (stmt);
+   call_info.argument_count = argument_count;
+ }
 
for (unsigned i = 0; i < argument_count; i++)
  {
call_info.arg_idx = i;
scan_expr_access (gimple_call_arg (stmt, i), stmt,
- ISRA_CTX_ARG, bb, &call_info);
+ ctx, bb, call_info_p);
  }
 
tree lhs = gimple_call_lhs (stmt);
-- 
2.26.0



Re: [Patch] HSA: omp-grid.c – access proper clause code (was: Re: [Patch] omp-grid.c – add cast to silence different enumeration types warning)

2020-04-09 Thread Martin Jambor
Hi,

On Mon, Apr 06 2020, Jakub Jelinek wrote:
> On Fri, Apr 03, 2020 at 12:43:42PM +0200, Tobias Burnus wrote:
>> HSA: omp-grid.c – access proper clause code
>> 
>>  * omp-grid.c (grid_eliminate_combined_simd_part): Use
>>  OMP_CLAUSE_CODE to access the omp clause code.
>> 
>> diff --git a/gcc/omp-grid.c b/gcc/omp-grid.c
>> index b98e45de6a0..ba635fd3ea2 100644
>> --- a/gcc/omp-grid.c
>> +++ b/gcc/omp-grid.c
>> @@ -1065,7 +1065,7 @@ grid_eliminate_combined_simd_part (gomp_for *parloop)
>>while (*pc)
>>  {
>>tree c = *pc;
>> -  switch (TREE_CODE (c))
>> +  switch (OMP_CLAUSE_CODE (c))
>>  {
>>  case OMP_CLAUSE_LINEAR:
>>{
>
> It looks good to me, but I have no way to actually test it, nor understand
> why it worked (or isn't covered by testsuite) in the HSAIL offloading case.
> Martin?
>

Yes, most likely the gridification of any tests which should have
covered this bailed out earlier.  The patch looks obvious to me.

Thanks for taking care of it.

Martin



Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Jason Merrill via Gcc-patches

On 4/9/20 1:05 AM, Martin Liška wrote:

Hi.

We've got one another sneaky test-case (thank you Marc ;) ):

$ cat pr94314-array.C
#include 
#include 

int count = 0;

__attribute__((malloc, noinline)) void* operator new[](unsigned long sz) {
   ++count;
   return ::operator new(sz);
}

void operator delete[](void* ptr) noexcept {
   --count;
   ::operator delete(ptr);
}

void operator delete[](void* ptr, std::size_t sz) noexcept {
   --count;
   ::operator delete(ptr, sz);
}

int main() {
   delete[] new int[1];
   if (count != 0)
     __builtin_abort ();
}

I bet we need to include the Honza's fix for inline stacks.
Or it the test-case invalid?


I suppose that these inlining issues are a good reason why the standard 
talks about new-expressions and delete-expressions rather than calls.


Jason



[committed, wwwdocs] aarch64: Document SVE changes

2020-04-09 Thread Richard Sandiford
As per $SUBJECT

This seemed to flow more naturally if we organised things as:

- improvements to existing features
- new options
- new extensions
- new CPUs

The patch also fixes up some missing tags flagged by xmllint.

Pushed.

---
 htdocs/gcc-10/changes.html | 100 +++--
 1 file changed, 85 insertions(+), 15 deletions(-)

diff --git a/htdocs/gcc-10/changes.html b/htdocs/gcc-10/changes.html
index 1c8d7a9f..61c767f4 100644
--- a/htdocs/gcc-10/changes.html
+++ b/htdocs/gcc-10/changes.html
@@ -237,6 +237,7 @@ a work-in-progress.
with the new attribute access.
   
 
+  
 
 
 C
@@ -336,6 +337,7 @@ a work-in-progress.
causing an syntactic ambiguity.
   
 
+  
   
 G++ can now detect modifying constant objects in constexpr evaluation
 (which is undefined behavior).
@@ -452,6 +454,7 @@ a work-in-progress.
 For formatted input/output, if the explicit widths after the data-edit
 descriptors I, F and G have been
 omitted, default widths are used.
+  
   
 A blank format item at the end of a format specification, i.e. nothing
 following the final comma, is allowed.  Use the option
@@ -478,6 +481,7 @@ a work-in-progress.
 CHARACTER expressions. Use the option -fdec.
   
 
+  
   
 Character type names in errors and warnings now include len
 in addition to kind; * is used for assumed
@@ -516,38 +520,104 @@ a work-in-progress.
 
 AArch64
 
-   The -mbranch-protection=pac-ret option now accepts the
+  There have been several improvements related to the Scalable
+  Vector Extension (SVE):
+
+  The SVE ACLE types and intrinsics are now supported.  They can
+  be accessed using the header file arm_sve.h.
+  
+  It is now possible to create fixed-length SVE types using
+  the arm_sve_vector_bits attribute.  For example:
+#if __ARM_FEATURE_SVE_BITS==512
+typedef svint32_t vec512 __attribute__((arm_sve_vector_bits(512)));
+typedef svbool_t pred512 __attribute__((arm_sve_vector_bits(512)));
+#endif
+  
+  -mlow-precision-div, -mlow-precision-sqrt
+  and -mlow-precision-recip-sqrt now work for SVE.
+  
+  -msve-vector-bits=128 now generates
+  vector-length-specific code for little-endian targets.  It continues
+  to generate vector-length-agnostic code for big-endian targets,
+  just as previous releases did for all targets.
+  
+  The vectorizer is now able to use extending loads and truncating
+  stores, including gather loads and scatter stores.
+  
+  The vectorizer now compares the cost of vectorizing with SVE
+  and vectorizing with Advanced SIMD and tries to pick the best one.
+  Previously it would always use SVE if possible.
+  
+  If a vector loop uses Advanced SIMD rather than SVE, the vectorizer
+  now considers using SVE to vectorize the left-over elements (the
+  “scalar tail” or “epilog”).
+  
+  Besides these specific points, there have been many general
+  improvements to the way that the vectorizer uses SVE.
+  
+
+  
+  The -mbranch-protection=pac-ret option now accepts the
   optional argument +b-key extension to perform return address
   signing with the B-key instead of the A-key.
   
+  The option -moutline-atomics has been added to aid
+  deployment of the Large System Extensions (LSE) on GNU/Linux systems built
+  with a baseline architecture targeting Armv8-A.  When the option is
+  specified code is emitted to detect the presence of LSE instructions at
+  runtime and use them for standard atomic operations.
+  For more information please refer to the documentation.
+  
   The Transactional Memory Extension is now supported through ACLE
   intrinsics.  It can be enabled through the +tme option
   extension (for example, -march=armv8.5-a+tme).
   
-  Initial autovectorization support for SVE2 has been added and can be
-  enabled through the   +sve2 option extension (for example,
-  -march=armv8.5-a+sve2).  Additional extensions can be enabled
-  through +sve2-sm4, +sve2=aes,
-  +sve2-sha3, +sve2-bitperm.
-  
-   A number of features from the Armv8.5-a are now supported through ACLE
+  A number of features from Armv8.5-A are now supported through ACLE
   intrinsics.  These include:
 
The random number instructions that can be enabled
through the (already present in GCC 9.1) +rng option
extension.
Floating-point intrinsics to round to integer instructions from
-   Armv8.5-a when targeting -march=armv8.5-a or later.
+   Armv8.5-A when targeting -march=armv8.5-a or later.
Memory Tagging Extension intrinsics enabled through the
+memtag option extension.
 
   
-   The option -moutline-atomics has been added to aid
-  deployment of the Large System Extensions (LSE) on GNU/Linux systems built
-  with a baseline architecture targeting Armv8-A.  When the option is
-  specified code is emitt

Re: [PATCH], PowerPC, Backport PR 93932 (variable vec_extract) to GCC 9

2020-04-09 Thread Segher Boessenkool
Hi!

On Thu, Apr 09, 2020 at 10:11:48AM -0500, will schmidt wrote:
> This patch matches almost identically with what went into
> Mainline.  Exception to identical are two parts;
> 1 - A constraint change "v"/"wk" that exists in 9 versus
> mainline, (ok)
> 2 - The testcase changes, which are referenced in the
> provided description.  (and pass now, which is ++ok). :-)

Ah great, thanks, that saves me doing that comparison myself :-)

> > 2020-04-09  Michael Meissner  
> > 
> > Back port from trunk
> > 2020-02-26  Michael Meissner  
> > 
> > PR target/93932
> > * config/rs6000/vsx.md (vsx_extract__var, VSX_D
> > iterator):
> > Split the insn into two parts.  This insn only does variable
> > extract from a register.
> > (vsx_extract__var_load, VSX_D iterator): New insn, do
> > variable extract from memory.
> > (vsx_extract_v4sf_var): Split the insn into two parts.  This
> > insn
> > only does variable extract from a register.
> > (vsx_extract_v4sf_var_load): New insn, do variable extract from
> > memory.
> > (vsx_extract__var, VSX_EXTRACT_I iterator): Split the
> > insn
> > into two parts.  This insn only does variable extract from a
> > register.
> > (vsx_extract__var_load, VSX_EXTRACT_I iterator): New
> > insn,
> > do variable extract from memory.

Mike: the patch is okay for 9.  Thank you!


Segher


[committed] aarch64: Add a separate "SVE sizeless type" attribute

2020-04-09 Thread Richard Sandiford
It's more convenient for a later patch if sizelessness is represented
separately from "SVEness".  "SVEness" is an ABI property that carries
forward into gimple and beyond, and continues to matter during LTO.
Sizelessness is just a frontend restriction and can be ignored after
that.

Tested on aarch64-linux-gnu, aarch64-elf and aarch64_be-elf, with the
last two including -mabi=ilp32.  Pushed.

Richard


2020-04-09  Richard Sandiford  

gcc/
* config/aarch64/aarch64.c (aarch64_attribute_table): Add
"SVE sizeless type".
* config/aarch64/aarch64-sve-builtins.cc (make_type_sizeless)
(sizeless_type_p): New functions.
(register_builtin_types): Apply make_type_sizeless to the type.
(register_tuple_type): Likewise.
(verify_type_context): Use sizeless_type_p instead of builin_type_p.
---
 gcc/config/aarch64/aarch64-sve-builtins.cc | 21 -
 gcc/config/aarch64/aarch64.c   |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc 
b/gcc/config/aarch64/aarch64-sve-builtins.cc
index 2c5543b6e6a..bcd60e9f838 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -585,6 +585,23 @@ lookup_sve_type_attribute (const_tree type)
   return lookup_attribute ("SVE type", TYPE_ATTRIBUTES (type));
 }
 
+/* Force TYPE to be a sizeless type.  */
+static void
+make_type_sizeless (tree type)
+{
+  TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("SVE sizeless type"),
+ NULL_TREE, TYPE_ATTRIBUTES (type));
+}
+
+/* Return true if TYPE is a sizeless type.  */
+static bool
+sizeless_type_p (const_tree type)
+{
+  if (type == error_mark_node)
+return NULL_TREE;
+  return lookup_attribute ("SVE sizeless type", TYPE_ATTRIBUTES (type));
+}
+
 /* If TYPE is a valid SVE element type, return the corresponding type
suffix, otherwise return NUM_TYPE_SUFFIXES.  */
 static type_suffix_index
@@ -3293,6 +3310,7 @@ register_builtin_types ()
   TYPE_INDIVISIBLE_P (vectype) = 1;
   add_sve_type_attribute (vectype, num_zr, num_pr,
  vector_types[i].mangled_name);
+  make_type_sizeless (vectype);
   abi_vector_types[i] = vectype;
   lang_hooks.types.register_builtin_type (vectype,
  vector_types[i].abi_name);
@@ -3361,6 +3379,7 @@ register_tuple_type (unsigned int num_vectors, 
vector_type_index type)
   DECL_FIELD_CONTEXT (field) = tuple_type;
   TYPE_FIELDS (tuple_type) = field;
   add_sve_type_attribute (tuple_type, num_vectors, 0, NULL);
+  make_type_sizeless (tuple_type);
   layout_type (tuple_type);
   gcc_assert (VECTOR_MODE_P (TYPE_MODE (tuple_type))
  && TYPE_MODE_RAW (tuple_type) == TYPE_MODE (tuple_type)
@@ -3578,7 +3597,7 @@ bool
 verify_type_context (location_t loc, type_context_kind context,
 const_tree type, bool silent_p)
 {
-  if (!builtin_type_p (type))
+  if (!sizeless_type_p (type))
 return true;
 
   switch (context)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 25eccc755b3..0a467176fd9 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1247,6 +1247,7 @@ static const struct attribute_spec 
aarch64_attribute_table[] =
   { "aarch64_vector_pcs", 0, 0, false, true,  true,  true,
  handle_aarch64_vector_pcs_attribute, NULL },
   { "SVE type",  3, 3, false, true,  false, true,  NULL, NULL 
},
+  { "SVE sizeless type",  0, 0, false, true,  false, true,  NULL, NULL },
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
 };
 
-- 
2.17.1



[committed] libphobos: Remove --enable-druntime-gc configure option.

2020-04-09 Thread Iain Buclaw via Gcc-patches
Hi,

This is yet another old option that would have been somewhat useful back
before the D front-end implementation was able to support compiling
without the Druntime library.

Now however, -fno-druntime makes the gcstub package redundant, so the
option has been removed, along with the package itself.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain

---
libphobos/ChangeLog:

* configure: Regenerate.
* libdruntime/Makefile.am (ALL_DRUNTIME_INSTALL_DSOURCES): Remove
DRUNTIME_DSOURCES_GC and DRUNTIME_DSOURCES_GCSTUB.
(DRUNTIME_DSOURCES): Add gc/*.d sources.
(DRUNTIME_DSOURCES_GC): Remove.
(DRUNTIME_DSOURCES_GCSTUB): Remove.
* libdruntime/Makefile.in: Regenerate.
* libdruntime/gcstub/gc.d: Remove.
* m4/druntime.m4 (DRUNTIME_GC): Remove.
---
 libphobos/configure   |  31 +--
 libphobos/libdruntime/Makefile.am |  17 +-
 libphobos/libdruntime/Makefile.in | 182 +++---
 libphobos/libdruntime/gcstub/gc.d | 388 --
 libphobos/m4/druntime.m4  |  16 --
 5 files changed, 87 insertions(+), 547 deletions(-)
 delete mode 100644 libphobos/libdruntime/gcstub/gc.d

diff --git a/libphobos/configure b/libphobos/configure
index af597b2525b..a6f5aec2bfd 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -701,8 +701,6 @@ DRUNTIME_CPU_ARM_FALSE
 DRUNTIME_CPU_ARM_TRUE
 DRUNTIME_CPU_AARCH64_FALSE
 DRUNTIME_CPU_AARCH64_TRUE
-DRUNTIME_GC_ENABLE_FALSE
-DRUNTIME_GC_ENABLE_TRUE
 libphobos_srcdir
 libphobos_builddir
 get_gcc_base_ver
@@ -835,7 +833,6 @@ with_gnu_ld
 enable_libtool_lock
 with_gcc_major_version_only
 enable_werror
-enable_druntime_gc
 with_libatomic
 with_libbacktrace
 with_target_system_zlib
@@ -1485,7 +1482,6 @@ Optional Features:
   optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-werror turns on -Werror [default=no]
-  --enable-druntime-gcenable D runtime garbage collector (default: yes)
   --enable-version-specific-runtime-libs
   Specify that runtime libraries should be installed
   in a compiler-specific directory
@@ -11649,7 +11645,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11652 "configure"
+#line 11648 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11755,7 +11751,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11758 "configure"
+#line 11754 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13981,24 +13977,7 @@ fi
   WERROR_FLAG="-Werror"
   fi
 
-
-# Check whether --enable-druntime-gc was given.
-if test "${enable_druntime_gc+set}" = set; then :
-  enableval=$enable_druntime_gc; enable_druntime_gc=no
-else
-  enable_druntime_gc=yes
-fi
-
-
-   if test "$enable_druntime_gc" = "yes"; then
-  DRUNTIME_GC_ENABLE_TRUE=
-  DRUNTIME_GC_ENABLE_FALSE='#'
-else
-  DRUNTIME_GC_ENABLE_TRUE='#'
-  DRUNTIME_GC_ENABLE_FALSE=
-fi
-
-
+DRUNTIME_GC
 
   druntime_target_cpu_parsed=""
   case "$target_cpu" in
@@ -15510,10 +15489,6 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z 
"${MAINTAINER_MODE_FALSE}"; then
   as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${DRUNTIME_GC_ENABLE_TRUE}" && test -z 
"${DRUNTIME_GC_ENABLE_FALSE}"; then
-  as_fn_error $? "conditional \"DRUNTIME_GC_ENABLE\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${DRUNTIME_CPU_AARCH64_TRUE}" && test -z 
"${DRUNTIME_CPU_AARCH64_FALSE}"; then
   as_fn_error $? "conditional \"DRUNTIME_CPU_AARCH64\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libphobos/libdruntime/Makefile.am 
b/libphobos/libdruntime/Makefile.am
index c7b03a5967d..c1c446d14fd 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -28,7 +28,6 @@ AM_DFLAGS= \
 
 # Install all D and DI files
 ALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \
-   $(DRUNTIME_DSOURCES_GC) $(DRUNTIME_DSOURCES_GCSTUB) \
$(DRUNTIME_DSOURCES_BIONIC) $(DRUNTIME_DSOURCES_DARWIN) \
$(DRUNTIME_DSOURCES_DRAGONFLYBSD) $(DRUNTIME_DSOURCES_FREEBSD) \
$(DRUNTIME_DSOURCES_LINUX) $(DRUNTIME_DSOURCES_NETBSD) \
@@ -40,12 +39,6 @@ ALL_DRUNTIME_INSTALL_DSOURCES = $(DRUNTIME_DSOURCES) \
 # Setup source files depending on configure
 DRUNTIME_SOURCES_CONFIGURED =
 
-# GC sources
-if DRUNTIME_GC_ENABLE
-DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_GC)
-else
-DRUNTIME_SOURCES_CONFIGURED += $(DRUNTIME_DSOURCES_GCSTUB)
-endif
 # OS specific sources
 if DRUNTIME_OS_POSIX
 DRUNTI

Re: [PATCH], PowerPC, Backport PR 93932 (variable vec_extract) to GCC 9

2020-04-09 Thread will schmidt via Gcc-patches
On Thu, 2020-04-09 at 05:16 -0400, Michael Meissner via Gcc-patches
wrote:
> Backport PR target/93932 (variable vec_extract) to GCC 9
> 
> This patch backports the fix for PR target/93932 from the current
> master branch
> to GCC 9.  The patch for the master branch had to be adjusted due to
> using
> different constraints (GCC 10 uses the enabled attribute to eliminate
> alternatives, while GCC 9 uses special constraints).  I have tested
> this on a
> little endian power8 system running Linux.  The bootstrap and make
> check had no
> regressions.
> 
> This patch does fix the following test cases on power8 code:
>   gcc.target/powerpc/fold-vec-extract-double.p8.c
>   gcc.target/powerpc/fold-vec-extract-longlong.p8.c
>   gcc.target/powerpc/fold-vec-extract-longlong.p9.c
> 
> Can I check this patch into the gcc 9 branch?

LGTM.

This patch matches almost identically with what went into
Mainline.  Exception to identical are two parts;
1 - A constraint change "v"/"wk" that exists in 9 versus
mainline, (ok)
2 - The testcase changes, which are referenced in the
provided description.  (and pass now, which is ++ok). :-)

Thanks
-Will


> 
> 
> 2020-04-09  Michael Meissner  
> 
>   Back port from trunk
>   2020-02-26  Michael Meissner  
> 
>   PR target/93932
>   * config/rs6000/vsx.md (vsx_extract__var, VSX_D
> iterator):
>   Split the insn into two parts.  This insn only does variable
>   extract from a register.
>   (vsx_extract__var_load, VSX_D iterator): New insn, do
>   variable extract from memory.
>   (vsx_extract_v4sf_var): Split the insn into two parts.  This
> insn
>   only does variable extract from a register.
>   (vsx_extract_v4sf_var_load): New insn, do variable extract from
>   memory.
>   (vsx_extract__var, VSX_EXTRACT_I iterator): Split the
> insn
>   into two parts.  This insn only does variable extract from a
>   register.
>   (vsx_extract__var_load, VSX_EXTRACT_I iterator): New
> insn,
>   do variable extract from memory.
> 
> --- /tmp/t3Q8FG_vsx.md2020-04-09 02:18:54.436474001 -0500
> +++ gcc/config/rs6000/vsx.md  2020-04-09 02:03:31.998405325 -0500
> @@ -3292,14 +3292,14 @@ (define_insn "vsx_vslo_"
>"vslo %0,%1,%2"
>[(set_attr "type" "vecperm")])
> 
> -;; Variable V2DI/V2DF extract
> +;; Variable V2DI/V2DF extract from a register
>  (define_insn_and_split "vsx_extract__var"
> -  [(set (match_operand: 0 "gpc_reg_operand" "=v,,r")
> - (unspec: [(match_operand:VSX_D 1 "input_operand"
> "v,m,m")
> -  (match_operand:DI 2 "gpc_reg_operand"
> "r,r,r")]
> +  [(set (match_operand: 0 "gpc_reg_operand" "=v")
> + (unspec: [(match_operand:VSX_D 1 "gpc_reg_operand"
> "v")
> +  (match_operand:DI 2 "gpc_reg_operand"
> "r")]
>   UNSPEC_VSX_EXTRACT))
> -   (clobber (match_scratch:DI 3 "=r,&b,&b"))
> -   (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
> +   (clobber (match_scratch:DI 3 "=r"))
> +   (clobber (match_scratch:V2DI 4 "=&v"))]
>"VECTOR_MEM_VSX_P (mode) && TARGET_DIRECT_MOVE_64BIT"
>"#"
>"&& reload_completed"
> @@ -3310,6 +3310,23 @@ (define_insn_and_split "vsx_extract_DONE;
>  })
> 
> +;; Variable V2DI/V2DF extract from memory
> +(define_insn_and_split "*vsx_extract__var_load"
> +  [(set (match_operand: 0 "gpc_reg_operand" "=wa,r")
> + (unspec: [(match_operand:VSX_D 1 "memory_operand"
> "Q,Q")
> +  (match_operand:DI 2 "gpc_reg_operand"
> "r,r")]
> + UNSPEC_VSX_EXTRACT))
> +   (clobber (match_scratch:DI 3 "=&b,&b"))]
> +  "VECTOR_MEM_VSX_P (mode) && TARGET_DIRECT_MOVE_64BIT"
> +  "#"
> +  "&& reload_completed"
> +  [(set (match_dup 0) (match_dup 4))]
> +{
> +  operands[4] = rs6000_adjust_vec_address (operands[0], operands[1],
> operands[2],
> +operands[3],
> mode);
> +}
> +  [(set_attr "type" "fpload,load")])
> +
>  ;; Extract a SF element from V4SF
>  (define_insn_and_split "vsx_extract_v4sf"
>[(set (match_operand:SF 0 "vsx_register_operand" "=ww")
> @@ -3361,14 +3378,14 @@ (define_insn_and_split "*vsx_extract_v4s
>[(set_attr "type" "fpload,fpload,fpload,load")
> (set_attr "length" "8")])
> 
> -;; Variable V4SF extract
> +;; Variable V4SF extract from a register
>  (define_insn_and_split "vsx_extract_v4sf_var"
> -  [(set (match_operand:SF 0 "gpc_reg_operand" "=ww,ww,?r")
> - (unspec:SF [(match_operand:V4SF 1 "input_operand" "v,m,m")
> - (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
> +  [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
> + (unspec:SF [(match_operand:V4SF 1 "gpc_reg_operand" "v")
> + (match_operand:DI 2 "gpc_reg_operand" "r")]
>  UNSPEC_VSX_EXTRACT))
> -   (clobber (match_scratch:DI 3 "=r,&b,&b"))
> -   (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
> +   (clobber (match_scratch:DI 3 "=r"))
> +   (clobber (match_scratch:V2DI 4 "=&v"))]
>"VE

Re: [PATCH] cselib, var-tracking: Improve debug info after the cselib sp tracking changes [PR94495]

2020-04-09 Thread Richard Biener
On Thu, 9 Apr 2020, Alexandre Oliva wrote:

> On Apr  9, 2020, Jakub Jelinek  wrote:
> 
> > 2020-04-09  Jakub Jelinek  
> 
> > PR debug/94495
> > * cselib.h (cselib_record_sp_cfa_base_equiv,
> > cselib_sp_derived_value_p): Declare.
> > * cselib.c (cselib_record_sp_cfa_base_equiv,
> > cselib_sp_derived_value_p): New functions.
> > * var-tracking.c (add_stores): Don't record MO_VAL_SET for
> > cselib_sp_derived_value_p values.
> > (vt_initialize): Call cselib_record_sp_cfa_base_equiv at the
> > start of extended basic blocks other than the first one
> > for !frame_pointer_needed functions.
> 
> Beautiful, thanks!

Thus OK.

Richard.

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)


Re: [PATCH] cselib, var-tracking: Improve debug info after the cselib sp tracking changes [PR94495]

2020-04-09 Thread Alexandre Oliva
On Apr  9, 2020, Jakub Jelinek  wrote:

> 2020-04-09  Jakub Jelinek  

>   PR debug/94495
>   * cselib.h (cselib_record_sp_cfa_base_equiv,
>   cselib_sp_derived_value_p): Declare.
>   * cselib.c (cselib_record_sp_cfa_base_equiv,
>   cselib_sp_derived_value_p): New functions.
>   * var-tracking.c (add_stores): Don't record MO_VAL_SET for
>   cselib_sp_derived_value_p values.
>   (vt_initialize): Call cselib_record_sp_cfa_base_equiv at the
>   start of extended basic blocks other than the first one
>   for !frame_pointer_needed functions.

Beautiful, thanks!

-- 
Alexandre Oliva, freedom fighterhe/himhttps://FSFLA.org/blogs/lxo/
Free Software Evangelist  Stallman was right, but he's left :(
GNU Toolchain Engineer   Live long and free, and prosper ethically


RE: [Arm] Allow the use of arm_cde.h for C++

2020-04-09 Thread Kyrylo Tkachov



> -Original Message-
> From: Matthew Malcomson 
> Sent: 09 April 2020 15:31
> To: gcc-patches@gcc.gnu.org
> Cc: nd ; Ramana Radhakrishnan
> ; Kyrylo Tkachov
> ; Richard Earnshaw
> ; ni...@redhat.com
> Subject: [Arm] Allow the use of arm_cde.h for C++
> 
> arm_cde.h includes the arm_mve_types.h header, which declares some C++
> overloaded functions.
> 
> There is a superfluous `extern "C"` statement in arm_cde.h, which
> encompasses these functions.  This means that if compiling for C++, the
> overloaded functions are declared, but are declared without name
> mangling.  Hence all the function names are the same and we have many
> conflicting declarations.
> 
> Testing Done:
>   Regression tested for arm-none-eabi.

Ok.
Thanks,
Kyrill

> 
> gcc/ChangeLog:
> 
> 2020-04-09  Matthew Malcomson  
> 
>   * config/arm/arm_cde.h: Remove `extern "C"` when compiling for
>   C++.
> 
> gcc/testsuite/ChangeLog:
> 
> 2020-04-09  Matthew Malcomson  
> 
>   * g++.target/arm/cde_mve.C: New test.
> 
> 
> 
> ### Attachment also inlined for ease of reply
> ###
> 
> 
> diff --git a/gcc/config/arm/arm_cde.h b/gcc/config/arm/arm_cde.h
> index
> d8ddda6bd648d8b94e97f7b6403b7708cebc9eb3..0ba3ee02d057dd280c9b34
> 00ef70b46ed472aec3 100644
> --- a/gcc/config/arm/arm_cde.h
> +++ b/gcc/config/arm/arm_cde.h
> @@ -27,10 +27,6 @@
>  #ifndef _GCC_ARM_CDE_H
>  #define _GCC_ARM_CDE_H 1
> 
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
>  #include 
> 
>  #if defined (__ARM_FEATURE_CDE)
> @@ -177,8 +173,4 @@ extern "C" {
> 
>  #endif
> 
> -#ifdef __cplusplus
> -}
> -#endif
> -
>  #endif
> diff --git a/gcc/testsuite/g++.target/arm/cde_mve.C
> b/gcc/testsuite/g++.target/arm/cde_mve.C
> new file mode 100644
> index
> ..897cbd2b8119471385c1c51
> 158b1aa4851acbaf1
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/arm/cde_mve.C
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target arm_v8_1m_main_cde_mve_fp_ok } */
> +/* { dg-add-options arm_v8_1m_main_cde_mve_fp } */
> +
> +/* Ensure this compiles.  */
> +#include "arm_cde.h"
> +int foo ()
> +{
> +  return 1;
> +}



Re: [PING][PATCH][wwwdocs] GCC 10: Document RISC-V target's requirement for binutils 2.30

2020-04-09 Thread Jeff Law via Gcc-patches
On Thu, 2020-04-09 at 15:36 +0100, Maciej W. Rozycki wrote:
> On Thu, 9 Apr 2020, Jeff Law wrote:
> 
> > > > Match GCC commit bfe78b08471f ("RISC-V: Using fmv.x.w/fmv.w.x rather 
> > > > than fmv.x.s/fmv.s.x") and commit 879bc686a0aa ("doc: RISC-V: Update 
> > > > binutils requirement to 2.30").
> > > 
> > >  Ping for:
> > > 
> > > 
> > OK.  Do we need any configure magic to detect what assembler version is 
> > being
> > used and warn/error if it's too old?
> 
>  I discussed this with Jim (cc-ed) who thinks there is no need for that; 
> cf. ;.
Great thanks. 

JEff



Re: [PING][PATCH][wwwdocs] GCC 10: Document RISC-V target's requirement for binutils 2.30

2020-04-09 Thread Maciej W. Rozycki via Gcc-patches
On Thu, 9 Apr 2020, Jeff Law wrote:

> > > Match GCC commit bfe78b08471f ("RISC-V: Using fmv.x.w/fmv.w.x rather 
> > > than fmv.x.s/fmv.s.x") and commit 879bc686a0aa ("doc: RISC-V: Update 
> > > binutils requirement to 2.30").
> > 
> >  Ping for:
> > 
> > 
> OK.  Do we need any configure magic to detect what assembler version is being
> used and warn/error if it's too old?

 I discussed this with Jim (cc-ed) who thinks there is no need for that; 
cf. .

 Patch now applied, thanks for your review.

  Maciej


[Arm] Allow the use of arm_cde.h for C++

2020-04-09 Thread Matthew Malcomson
arm_cde.h includes the arm_mve_types.h header, which declares some C++
overloaded functions.

There is a superfluous `extern "C"` statement in arm_cde.h, which
encompasses these functions.  This means that if compiling for C++, the
overloaded functions are declared, but are declared without name
mangling.  Hence all the function names are the same and we have many
conflicting declarations.

Testing Done:
  Regression tested for arm-none-eabi.

gcc/ChangeLog:

2020-04-09  Matthew Malcomson  

* config/arm/arm_cde.h: Remove `extern "C"` when compiling for
C++.

gcc/testsuite/ChangeLog:

2020-04-09  Matthew Malcomson  

* g++.target/arm/cde_mve.C: New test.



### Attachment also inlined for ease of reply###


diff --git a/gcc/config/arm/arm_cde.h b/gcc/config/arm/arm_cde.h
index 
d8ddda6bd648d8b94e97f7b6403b7708cebc9eb3..0ba3ee02d057dd280c9b3400ef70b46ed472aec3
 100644
--- a/gcc/config/arm/arm_cde.h
+++ b/gcc/config/arm/arm_cde.h
@@ -27,10 +27,6 @@
 #ifndef _GCC_ARM_CDE_H
 #define _GCC_ARM_CDE_H 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include 
 
 #if defined (__ARM_FEATURE_CDE)
@@ -177,8 +173,4 @@ extern "C" {
 
 #endif
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif
diff --git a/gcc/testsuite/g++.target/arm/cde_mve.C 
b/gcc/testsuite/g++.target/arm/cde_mve.C
new file mode 100644
index 
..897cbd2b8119471385c1c51158b1aa4851acbaf1
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/cde_mve.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_1m_main_cde_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_main_cde_mve_fp } */
+
+/* Ensure this compiles.  */
+#include "arm_cde.h"
+int foo ()
+{
+  return 1;
+}

diff --git a/gcc/config/arm/arm_cde.h b/gcc/config/arm/arm_cde.h
index 
d8ddda6bd648d8b94e97f7b6403b7708cebc9eb3..0ba3ee02d057dd280c9b3400ef70b46ed472aec3
 100644
--- a/gcc/config/arm/arm_cde.h
+++ b/gcc/config/arm/arm_cde.h
@@ -27,10 +27,6 @@
 #ifndef _GCC_ARM_CDE_H
 #define _GCC_ARM_CDE_H 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include 
 
 #if defined (__ARM_FEATURE_CDE)
@@ -177,8 +173,4 @@ extern "C" {
 
 #endif
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif
diff --git a/gcc/testsuite/g++.target/arm/cde_mve.C 
b/gcc/testsuite/g++.target/arm/cde_mve.C
new file mode 100644
index 
..897cbd2b8119471385c1c51158b1aa4851acbaf1
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/cde_mve.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_1m_main_cde_mve_fp_ok } */
+/* { dg-add-options arm_v8_1m_main_cde_mve_fp } */
+
+/* Ensure this compiles.  */
+#include "arm_cde.h"
+int foo ()
+{
+  return 1;
+}



[PATCH] cselib, var-tracking: Improve debug info after the cselib sp tracking changes [PR94495]

2020-04-09 Thread Jakub Jelinek via Gcc-patches
Hi!

On the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94495#c5
testcase GCC emits worse debug info after the PR92264 cselib.c
changes.
The difference at -O2 -g -dA in the assembly is (when ignoring debug info):
# DEBUG g => [argp]
# DEBUG k => [argp+0x20]
# DEBUG j => [argp+0x18]
# DEBUG a => di
# DEBUG b => si
# DEBUG c => dx
# DEBUG d => cx
# DEBUG h => [argp+0x8]
# DEBUG e => r8
# DEBUG i => [argp+0x10]
# DEBUG f => r9
...
 .LVL4:
+   # DEBUG h => [sp+0x10]
+   # DEBUG i => [sp+0x18]
+   # DEBUG j => [sp+0x20]
+   # DEBUG k => [sp+0x28]
# DEBUG c => entry_value
 # SUCC: EXIT [always]  count:1073741824 (estimated locally)
ret
 .LVL5:
+   # DEBUG k => [argp+0x20]
# DEBUG a => bx
# DEBUG b => si
# DEBUG c => dx
# DEBUG d => cx
# DEBUG e => r8
# DEBUG f => r9
+   # DEBUG h => [argp+0x8]
+   # DEBUG i => [argp+0x10]
+   # DEBUG j => [argp+0x18]
This means that before the changes, h, i, j, k could be all expressed
in DW_AT_location directly with DW_OP_fbreg , but now we need
to use a location list, where in the first part of the function and last
part of the function (everything except the ret instruction) we use that
DW_OP_fbreg , but for the single ret instruction we instead
say those values live in something pointed by stack pointer + offset.
It is true, but only because stack pointer + offset is equal to DW_OP_fbreg
 at that point.

The var-tracking pass has for !frame_pointer_needed functions code to
canonicalize stack pointer uses in the insns before it hands it over
to cselib to cfa_base_rtx + offset depending on the stack depth at each
point.  The problem is that on the last epilogue pop insn (the one right
before ret) the canonicalization is sp = argp - 8 and add_stores records
a MO_VAL_SET operation for that argp - 8 value (which is the
SP_DERIVED_VALUE_P VALUE the cselib changes canonicalize sp based accesses
on) and thus var-tracking from that point onwards tracks that that VALUE
(2:2) now lives in sp.  At the end of function it of course needs to forget
it again (or it would need on any changes to sp).  But when processing
that uop, we note that the VALUE has changed and anything based on it
changed too, so emit changes for everything.  Before that var-tracking
itself doesn't track it in any register, so uses cselib and cselib knows
through the permanent equivs how to compute it using argp (i.e. what
will be DW_OP_fbreg).

The following fix has two parts.  One is it detects if cselib can compute
a certain VALUE using the cfa_base_rtx and for such VALUEs doesn't add
the MO_VAL_SET operation, as it is better to express them using cfa_base_rtx
rather than temporarily through something else.  And the other is make sure
we reuse in !frame_pointer_needed the single SP_DERIVED_VALUE_P VALUE in
other extended basic blocks too (and other VALUEs) too.  This can be done
because we have computed the stack depths at the start of each basic block
in vt_stack_adjustments and while cselib_reset_table is called at the end
of each extended bb, which throws away all hard registers (but the magic
cfa_base_rtx) and so can hint cselib.c at the start of the ebb what VALUE
the sp hard reg has.  That means fewer VALUEs during var-tracking and more
importantly that they will all have the cfa_base_rtx + offset equivalency.

I have performed 4 bootstraps+regtests (x86_64-linux and i686-linux,
each with this patch (that is the new cselib + var-tracking variant) and
once with that patch reverted as well as all other cselib.c changes from
this month; once that bootstrapped, I've reapplied the cselib.c changes and
this patch and rebuilt cc1plus, so that the content is comparable, but built
with the pre-Apr 2 cselib.c+var-tracking.c (that is the old cselib one)).

Below are readelf -WS cc1plus | grep debug_ filtered to only have debug
sections whose size actually changed, followed by dwlocstat results on
cc1plus.  This shows that there was about 3% shrink in those .debug*
sections for 32-bit and 1% shrink for 64-bit, with minor variable coverage
changes one or the other way that are IMHO insignificant.

32-bit old cselib
  [33] .debug_info   PROGBITS 29139c0 710e5fa 00  0   0 
 1
  [34] .debug_abbrev PROGBITS 9a21fba 21ad6d 00  0   0  
1
  [35] .debug_line   PROGBITS 9c3cd27 1a05e56 00  0   0 
 1
  [36] .debug_strPROGBITS b642b7d 7cad09 01  MS  0   0  
1
  [37] .debug_locPROGBITS be0d886 5792627 00  0   0 
 1
  [38] .debug_ranges PROGBITS 1159fead e57218 00  0   0 
 1
sum 263075589B
32-bit new cselib + var-tracking
  [33] .debug_info   PROGBITS 29129c0 71065d1 00  0   0 
 1
  [34] .debug_abbrev PROGBITS 9a18f91 21af28 00  0   0  
1
  [35] .debug_line   

[PATCH] aarch64, libgcc: Fix unwinding from pac-ret to normal frames [PR94514]

2020-04-09 Thread Szabolcs Nagy
With -mbranch-protection=pac-ret the debug info toggles the
signedness state of the return address so the unwinder knows when
the return address needs pointer authentication.

The unwind context flags were not updated according to the dwarf
frame info.

This causes unwinding across frames that were built without pac-ret
to incorrectly authenticate the return address wich corrupts the
return address on a system where PAuth is enabled.

Note: This even affects systems where all code use pac-ret because
unwinding across a signal frame the return address is not signed.

gcc/testsuite/ChangeLog:

2020-04-XX  Szabolcs Nagy  

PR target/94514
* g++.target/aarch64/pr94514.C: New test.
* gcc.target/aarch64/pr94514.c: New test.

libgcc/ChangeLog:

2020-04-XX  Szabolcs Nagy  

PR target/94514
* config/aarch64/aarch64-unwind.h (aarch64_frob_update_context):
Update context->flags accroding to the frame state.
---
 gcc/testsuite/g++.target/aarch64/pr94514.C | 26 
 gcc/testsuite/gcc.target/aarch64/pr94514.c | 76 ++
 libgcc/config/aarch64/aarch64-unwind.h |  2 +
 3 files changed, 104 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/aarch64/pr94514.C
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr94514.c

diff --git a/gcc/testsuite/g++.target/aarch64/pr94514.C 
b/gcc/testsuite/g++.target/aarch64/pr94514.C
new file mode 100644
index 000..2a8c949ba30
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr94514.C
@@ -0,0 +1,26 @@
+/* PR target/94514. Unwind across mixed pac-ret and non-pac-ret frames.  */
+/* { dg-do run } */
+
+__attribute__((noinline, target("branch-protection=pac-ret")))
+static void do_throw (void)
+{
+  throw 42;
+  __builtin_abort ();
+}
+
+__attribute__((noinline, target("branch-protection=none")))
+static void no_pac_ret (void)
+{
+  do_throw ();
+  __builtin_abort ();
+}
+
+int main ()
+{
+  try {
+no_pac_ret ();
+  } catch (...) {
+return 0;
+  }
+  __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr94514.c 
b/gcc/testsuite/gcc.target/aarch64/pr94514.c
new file mode 100644
index 000..bbbf5a6b0b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr94514.c
@@ -0,0 +1,76 @@
+/* PR target/94514. Unwind across mixed pac-ret and non-pac-ret frames.  */
+/* { dg-do run } */
+/* { dg-options "-fexceptions -O2" } */
+
+#include 
+#include 
+#include 
+
+#define die() \
+  do { \
+printf ("%s:%d: reached unexpectedly.\n", __FILE__, __LINE__); \
+fflush (stdout); \
+abort (); \
+  } while (0)
+
+static struct _Unwind_Exception exc;
+
+static _Unwind_Reason_Code
+force_unwind_stop (int version, _Unwind_Action actions,
+   _Unwind_Exception_Class exc_class,
+   struct _Unwind_Exception *exc_obj,
+   struct _Unwind_Context *context,
+   void *stop_parameter)
+{
+  printf ("%s: CFA: %p PC: %p actions: %d\n",
+ __func__,
+ (void *)_Unwind_GetCFA (context),
+ (void *)_Unwind_GetIP (context),
+ (int)actions);
+  if (actions & _UA_END_OF_STACK)
+die ();
+  return _URC_NO_REASON;
+}
+
+static void force_unwind (void)
+{
+#ifndef __USING_SJLJ_EXCEPTIONS__
+  _Unwind_ForcedUnwind (&exc, force_unwind_stop, 0);
+#else
+  _Unwind_SjLj_ForcedUnwind (&exc, force_unwind_stop, 0);
+#endif
+}
+
+__attribute__((noinline, target("branch-protection=pac-ret")))
+static void f2_pac_ret (void)
+{
+  force_unwind ();
+  die ();
+}
+
+__attribute__((noinline, target("branch-protection=none")))
+static void f1_no_pac_ret (void)
+{
+  f2_pac_ret ();
+  die ();
+}
+
+__attribute__((noinline, target("branch-protection=pac-ret")))
+static void f0_pac_ret (void)
+{
+  f1_no_pac_ret ();
+  die ();
+}
+
+static void cleanup_handler (void *p)
+{
+  printf ("%s: Success.\n", __func__);
+  exit (0);
+}
+
+int main ()
+{
+  char dummy __attribute__((cleanup (cleanup_handler)));
+  f0_pac_ret ();
+  die ();
+}
diff --git a/libgcc/config/aarch64/aarch64-unwind.h 
b/libgcc/config/aarch64/aarch64-unwind.h
index 4c8790bae67..ed84a96db41 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -104,6 +104,8 @@ aarch64_frob_update_context (struct _Unwind_Context 
*context,
   if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1)
 /* The flag is used for re-authenticating EH handler's address.  */
 context->flags |= RA_SIGNED_BIT;
+  else
+context->flags &= ~RA_SIGNED_BIT;
 
   return;
 }
-- 
2.17.1



[PATCH] aarch64: Fix .cfi_window_save with pac-ret [PR94515]

2020-04-09 Thread Szabolcs Nagy
On aarch64 -mbranch-protection=pac-ret reuses the dwarf
opcode for window_save to mean "toggle the return address
mangle state", but in the dwarf2cfi internal logic the
state was not properly recorded so the remember/restore
logic was broken.

This can cause the unwinder not to authenticate return
addresses that were signed (or vice versa) which means
a runtime crash on a pauth enabled system.

Currently only aarch64 pac-ret uses REG_CFA_TOGGLE_RA_MANGLE.

gcc/ChangeLog:

2020-04-XX  Szabolcs Nagy  

PR target/94515
* dwarf2cfi.c (dwarf2out_frame_debug): Record RA
mangle state in cur_row->window_save.

gcc/testsuite/ChangeLog:

2020-04-XX  Szabolcs Nagy  

PR target/94515
* g++.target/aarch64/pr94515.C: New test.
---
 gcc/dwarf2cfi.c|  3 ++
 gcc/testsuite/g++.target/aarch64/pr94515.C | 43 ++
 2 files changed, 46 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/aarch64/pr94515.C

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 229fbfacc30..22989a6c2fb 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -2145,6 +2145,9 @@ dwarf2out_frame_debug (rtx_insn *insn)
   case REG_CFA_TOGGLE_RA_MANGLE:
/* This uses the same DWARF opcode as the next operation.  */
dwarf2out_frame_debug_cfa_window_save (true);
+   /* Keep track of RA mangle state by toggling the window_save bit.
+  This is needed so .cfi_window_save is emitted correctly.  */
+   cur_row->window_save = !cur_row->window_save;
handled_one = true;
break;
 
diff --git a/gcc/testsuite/g++.target/aarch64/pr94515.C 
b/gcc/testsuite/g++.target/aarch64/pr94515.C
new file mode 100644
index 000..7707c773a72
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/pr94515.C
@@ -0,0 +1,43 @@
+/* PR target/94515. Check .cfi_window_save with multiple return paths.  */
+/* { dg-do run } */
+/* { dg-additional-options "-O2 -mbranch-protection=pac-ret --save-temps" } */
+
+volatile int zero = 0;
+
+__attribute__((noinline, target("branch-protection=none")))
+void unwind (void)
+{
+  if (zero == 0)
+throw 42;
+}
+
+__attribute__((noinline, noipa, target("branch-protection=pac-ret")))
+int test (int z)
+{
+  if (z) {
+asm volatile ("":::"x20","x21");
+unwind ();
+return 1;
+  } else {
+unwind ();
+return 2;
+  }
+}
+
+__attribute__((target("branch-protection=none")))
+int main ()
+{
+  try {
+test (zero);
+__builtin_abort ();
+  } catch (...) {
+return 0;
+  }
+  __builtin_abort ();
+}
+
+/* This check only works if there are two return paths in test and
+   cfi_window_save is used for both instead of cfi_remember_state
+   plus cfi_restore_state.  This is currently the case with -O2.  */
+
+/* { dg-final { scan-assembler-times {\t\.cfi_window_save\n} 4 } } */
-- 
2.17.1



Re: [committed] libphobos: Add --enable-libphobos-checking configure option (PR94305)

2020-04-09 Thread Iain Buclaw via Gcc-patches
On 09/04/2020 12:02, Matthias Klose wrote:
> On 4/9/20 12:47 AM, Iain Buclaw via Gcc-patches wrote:
>> Hi,
>>
>> As GDCFLAGS is overriden by the top-level make file with '-O2 -g',
>> libphobos ends up always being built with all contracts, invariants, and
>> asserts compiled in.  This adds a new configurable that defaults to omit
>> compiling any run-time checks into the library using '-frelease'.
>>
>> Other choices either set the flags '-fno-release', enabling all run-time
>> checks, or '-fassert', which only compiles in asserts.
>>
>> The omission of compiling in contracts results in a smaller library
>> size, with faster build times.
> 
> please could you document these in gcc/doc/install.texi, maybe together with
> other undocumented options?
> 
> Thanks, Matthias
> 

The thought did cross my mind, I wanted to remove all archaic/nonsense 
configure options first.

Iain.


Re: [PING][PATCH][wwwdocs] GCC 10: Document RISC-V target's requirement for binutils 2.30

2020-04-09 Thread Jeff Law via Gcc-patches
On Thu, 2020-04-09 at 14:42 +0100, Maciej W. Rozycki via Gcc-patches wrote:
> On Thu, 2 Apr 2020, Maciej W. Rozycki wrote:
> 
> > Match GCC commit bfe78b08471f ("RISC-V: Using fmv.x.w/fmv.w.x rather 
> > than fmv.x.s/fmv.s.x") and commit 879bc686a0aa ("doc: RISC-V: Update 
> > binutils requirement to 2.30").
> 
>  Ping for:
> 
> 
OK.  Do we need any configure magic to detect what assembler version is being
used and warn/error if it's too old?

jeff



Re: [PATCH] aarch64: Add TX3 machine model

2020-04-09 Thread Anton Youdkevitch

Andrew,

On 09.4.2020 00:50 , Andrew Pinski wrote:

On Wed, Apr 8, 2020 at 11:06 AM Anton Youdkevitch
 wrote:

Here is the patch introducing thunderxt311 maching model
for the scheduler.  A name for the new chip was added to the
list of the names to be recognized as a valid parameter for mcpu
and mtune flags. The TX2 cost model was reused for TX3.

It might make sense to use thunderx3 instead of thunderx3t11 now.
The main reason why I had used thunderx2t99 was because there was
going to be 2 Thunderx2 with two different costs but the second one
turned into OcteonTX2 instead.

We will revisited this. Thanks for the suggestion!

--
  Anton


[PING][PATCH][wwwdocs] GCC 10: Document RISC-V target's requirement for binutils 2.30

2020-04-09 Thread Maciej W. Rozycki via Gcc-patches
On Thu, 2 Apr 2020, Maciej W. Rozycki wrote:

> Match GCC commit bfe78b08471f ("RISC-V: Using fmv.x.w/fmv.w.x rather 
> than fmv.x.s/fmv.s.x") and commit 879bc686a0aa ("doc: RISC-V: Update 
> binutils requirement to 2.30").

 Ping for:



  Maciej


Make it possible to have different instrumented and feedback builds without copying gcda files around [pr93401]

2020-04-09 Thread Jan Hubicka
Hi,
in GCC 8 we changed -fprofile-generate= to use mangled absolute paths in
the  directory. This was necessary to avoid clashes of files when gcc is
executed from different directories to build different sources of same
filename.

However this made it difficult to build projects on setups where instrumented
build is done in one directory, feedback build in different and possibly
training happens in yet another directory structure.  This happens i.e. for
Firefox builds for month or two.

This patch adds -fprofile-prefix-path that can be used to inform gcc where the
root of build directory is and strip it form the gcda filenames.
This is similar to exisitng debug-prefix-map but without the map feature since
it seems useless for profile data.

We spent quite some time with Maritn Liska discussing options and found no
better solution.  I was looking how this work on LLVM and they produce single
profdata file which is then transformed into kind of simple database by
llvmprofdata tool.  This database keys functions by filename and symbol name.
If you arrane two files with same name define static variable with same symbol
name this gets messedup and result in wrong info. So I think this is not very
good solution and preffer the extra option.

Bootstrapped/regtested x86_64-linux. I plan to commit it later today if there
are no complains.

I suppose our manual could have some central section on profile feedback
explaining the whole setup at one place.

Honza

* common.opt (profile-prefix-path): New option.
* coverae.c: Include diagnostics.h.
(coverage_init): Strip profile prefix path.
* doc/invoke.texi (-fprofile-prefix-path): Document.
diff --git a/gcc/common.opt b/gcc/common.opt
index bb2ea4c905d..5662d46630a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2196,6 +2196,10 @@ Enum(profile_update) String(atomic) 
Value(PROFILE_UPDATE_ATOMIC)
 EnumValue
 Enum(profile_update) String(prefer-atomic) Value(PROFILE_UPDATE_PREFER_ATOMIC)
 
+fprofile-prefix-path=
+Common Joined RejectNegative Var(profile_prefix_path)
+remove prefix from absolute path before manging name for -fprofile-generate= 
and -fprofile-use=.
+
 fprofile-generate
 Common
 Enable common options for generating profile info for profile feedback 
directed optimizations.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 30ae84df90f..d09a5749fbd 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "auto-profile.h"
 #include "profile.h"
+#include "diagnostic.h"
 
 #include "gcov-io.c"
 
@@ -1221,6 +1222,19 @@ coverage_init (const char *filename)
  const char *separator = "/";
 #endif
  filename = concat (getpwd (), separator, filename, NULL);
+ if (profile_prefix_path)
+   {
+ if (!strncmp (filename, profile_prefix_path,
+   strlen (profile_prefix_path)))
+   {
+ filename += strlen (profile_prefix_path);
+ while (*filename == *separator)
+   filename++;
+   }
+ else
+   warning (0, "filename %s does not start with profile prefix %s",
+filename, profile_prefix_path);
+   }
  filename = mangle_path (filename);
  len = strlen (filename);
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index be7b5bb7d71..afd8a6dbc03 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -549,8 +549,9 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-p  -pg  -fprofile-arcs  --coverage  -ftest-coverage @gol
 -fprofile-abs-path @gol
 -fprofile-dir=@var{path}  -fprofile-generate  -fprofile-generate=@var{path} 
@gol
--fprofile-note=@var{path}  -fprofile-update=@var{method} @gol
--fprofile-filter-files=@var{regex}  -fprofile-exclude-files=@var{regex} 
-fprofile-reproducibility @gol
+-fprofile-note=@var{path} -fprofile-prefix-path=@var{path} @gol
+-fprofile-update=@var{method} -fprofile-filter-files=@var{regex} @gol
+-fprofile-exclude-files=@var{regex} -fprofile-reproducibility @gol
 -fsanitize=@var{style}  -fsanitize-recover  -fsanitize-recover=@var{style} @gol
 -fasan-shadow-offset=@var{number}  -fsanitize-sections=@var{s1},@var{s2},... 
@gol
 -fsanitize-undefined-trap-on-error  -fbounds-check @gol
@@ -13398,6 +13399,20 @@ If @var{path} is specified, GCC saves @file{.gcno} 
file into @var{path}
 location.  If you combine the option with multiple source files,
 the @file{.gcno} file will be overwritten.
 
+@item -fprofile-prefix-path=@var{path}
+
+This option can be used in combination with
+@option{profile-generate=}@var{profile_dir} and
+@option{profile-use=}@var{profile_dir} to inform GCC where is the base
+directory of built source tree.  By default @var{profile_dir} will contain
+files with mangled absolute paths of all object files in the built project.
+This is not desirable when directory used to build the 

Avoid g++.dg/lto/alias-4_0.C test failure on ARM [PR91322]

2020-04-09 Thread Jan Hubicka
Hi,
this patch avoid failure of alias-4_0.C testcase. The testcase is
testing that ODR TBAA works but structure used conflicts with builtin
va_arg type on ARM which disables TBAA for it.

Better fix would be to make va_arg types with mangled names in
lto1 frontend but that require some extra work, so it is next stage1
material.

I thus comitted the following.
Honza

2020-04-09  Jan Hubicka  

PR tree-optimization/91322
* g++.dg/lto/alias-4_0.C: Avoid conflict with va_list on ARM and add
a template testing that.

diff --git a/gcc/testsuite/g++.dg/lto/alias-4_0.C 
b/gcc/testsuite/g++.dg/lto/alias-4_0.C
index 410c3140baf..3d386324753 100644
--- a/gcc/testsuite/g++.dg/lto/alias-4_0.C
+++ b/gcc/testsuite/g++.dg/lto/alias-4_0.C
@@ -1,11 +1,14 @@
 /* { dg-lto-do run } */
-/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
+/* { dg-lto-options { { -O3 -flto -fno-early-inlining -fdump-ipa-cgraph} } } */
 __attribute__ ((used))
 short *ptr_init, **ptr=&ptr_init;
 
 __attribute__ ((used))
 struct a {
   int *aptr;
+  /* On ARM va_list is an anonymous structure containing pointer. 
+ This disable ODR TBAA on it.  */
+  short b;
 } a, *aptr=&a;
 
 void
@@ -29,3 +32,6 @@ main()
   test ();
   return 0;
 }
+/* On ARM the testcase used to fial because struct a got in conflict with 
builtin
+   va_list type.  Check that this does not happen.  */
+/* { dg-final { scan-wpa-ipa-dump-not "ODR and non-ODR type conflict" "cgraph" 
 } } */


[PATCH] testsuite/93369 - use -shared to avoid issue with ODR violation

2020-04-09 Thread Richard Biener


The testcase contains an ODR violation and thus the observed
link failure is an accepted outcome (it originally was for
an ICE during WPA).  Thus the following adds -shared to the link.

Pushed.

2020-04-09  Richard Biener  

PR testsuite/93369
* g++.dg/lto/pr64076_0.C: Add -shared -fPIC.
* g++.dg/lto/pr64076_1.C: Add -fPIC.
---
 gcc/testsuite/g++.dg/lto/pr64076_0.C | 4 
 gcc/testsuite/g++.dg/lto/pr64076_1.C | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/lto/pr64076_0.C 
b/gcc/testsuite/g++.dg/lto/pr64076_0.C
index fb9b060e323..57d0fd6a1c3 100644
--- a/gcc/testsuite/g++.dg/lto/pr64076_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr64076_0.C
@@ -1,4 +1,8 @@
 // { dg-lto-do link }
+// { dg-lto-options { { -O0 -flto -shared -fPIC } } }
+// { dg-require-effective-target fpic }
+// { dg-require-effective-target shared }
+// { dg-extra-ld-options "-shared" }
 
 #define XXX
 #include "pr64076.H"
diff --git a/gcc/testsuite/g++.dg/lto/pr64076_1.C 
b/gcc/testsuite/g++.dg/lto/pr64076_1.C
index 4bd00817b1d..c9c58b798ec 100644
--- a/gcc/testsuite/g++.dg/lto/pr64076_1.C
+++ b/gcc/testsuite/g++.dg/lto/pr64076_1.C
@@ -1,4 +1,4 @@
-// { dg-options -fno-lto }
+// { dg-options "-fno-lto -fPIC" }
 
 #include "pr64076.H"
 
-- 
2.25.1


[wwwdocs] Move arm section under aarch64

2020-04-09 Thread Kyrylo Tkachov
Hi all,

We logically grouped the aarch64 and arm entries as they share some content but
then the alphabetic order came in and put amdgcn and arc between the two.
I'm taking the liberty of moving arm under aarch64 and adding a small 
clarification
that the recently added CDE intrinsics implement a beta version of the ACLE 
specification.

Pushing to wwwdocs.

Thanks,
Kyrill


wwwdocs-move-arm.patch
Description: wwwdocs-move-arm.patch


Re: [testsuite][arm] Fix cmse-15.c expected output

2020-04-09 Thread Richard Sandiford
Christophe Lyon  writes:
> On Wed, 8 Apr 2020 at 11:48, Richard Sandiford
>  wrote:
>>
>> Christophe Lyon via Gcc-patches  writes:
>> > Hi,
>> >
>> > While checking Martin's fix for PR ipa/94445, he made me realize that
>> > the cmse-15.c testcase still fails at -Os because ICF means that we
>> > generate
>> > nonsecure2:
>> > b   nonsecure0
>> >
>> > which is OK, but does not match the currently expected
>> > nonsecure2:
>> > ...
>> > bl  __gnu_cmse_nonsecure_call
>> >
>> > (see https://gcc.gnu.org/pipermail/gcc-patches/2020-April/543190.html)
>> >
>> > The test has already different expectations for v8-M and v8.1-M.
>> >
>> > I've decided to try to use check-function-bodies to account for the
>> > different possibilities:
>> > - v8-M vs v8.1-M via two different prefixes
>> > - code generation variants (-0?) via multiple regexps
>> >
>> > I've tested that the test now passes with 
>> > --target-board=-march=armv8-m.main
>> > and --target-board=-march=armv8.1-m.main.
>> >
>> > I feel this a bit too much of a burden for the purpose, maybe there's
>> > a better way of handling all these alternatives (in particular,
>> > there's a lot of duplication since the expected code for the secure*
>> > functions is the same for v8-M and v8.1-M).
>>
>> FWIW, an alternative is to give multiple versions with the same prefix
>> and use { target ... } to select between them.  E.g.:
>>
>> /*
>> ** foo:   { target a }
>> **  ...
>> */
>> /*
>> ** foo:   { target { ! a } }
>> **  ...
>> */
>>
>
> Ha indeed, that makes it simpler. Thanks for the example, I hadn't
> fully understand how to use that scheme: I tried to add a third
> alternative (different prefix) with no selector for cases where no
> distinction was needed, but I realized that all alternatives need
> their full matching description.
>
> However, {target { ! a } } does not work as is, so the attached patch
> uses a non-greedy regexp to avoid trying "! a }" instead of "target {
> ! a }"

Oops.  This part is definitely OK, thanks.

> If OK, maybe I should commit that as two separate patches?

I don't really feel qualified to review the substance of the arm part
of the patch, but given Andre's LGTM for that in the earlier version,
a rubber-stamp OK for that too.  I agree separate commits might be
better.

Thanks,
Richard


Re: [committed] libphobos: Add --enable-libphobos-checking configure option (PR94305)

2020-04-09 Thread Matthias Klose
On 4/9/20 12:47 AM, Iain Buclaw via Gcc-patches wrote:
> Hi,
> 
> As GDCFLAGS is overriden by the top-level make file with '-O2 -g',
> libphobos ends up always being built with all contracts, invariants, and
> asserts compiled in.  This adds a new configurable that defaults to omit
> compiling any run-time checks into the library using '-frelease'.
> 
> Other choices either set the flags '-fno-release', enabling all run-time
> checks, or '-fassert', which only compiles in asserts.
> 
> The omission of compiling in contracts results in a smaller library
> size, with faster build times.

please could you document these in gcc/doc/install.texi, maybe together with
other undocumented options?

Thanks, Matthias


Re: [PATCH v3] Fix alignment for local variable [PR90811]

2020-04-09 Thread Kito Cheng
Hi Richard:

> Please skip vars with DECL_USER_ALIGN.

I was consider to skip DECL_USER_ALIGN,
but Jakub think it shouldn't skip in other patch review[1] (related to
this patch),
because it's minimum alignment not restricted alignment[2]

[1] https://gcc.gnu.org/pipermail/gcc-patches/2020-March/542913.html
[2] 
https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#Common-Type-Attributes

>
> Note local-decls also contains the base variables that
> are written into SSA form so you are processing variables
> here that are not processed by the corresponding code
> during RTL expansion.  It's probably harmless to increase
> alignment of registers since that should be ignored.
> I'm not sure whether alignment has any effect on
> DECL_HARD_REGISTER vars.

I did more checks on expand_one_var, DECL_HARD_REGISTER won't adjust
alignment since use different path to expand, so it should skip here.

So yeah, it seems should skip here.

> Note local-decls also contains local statics.  I'm not sure
> LOCAL_DECL_ALIGNMENT is supposed to handle those,
> certainly the RTL expansion code does not.  So please
> exclude is_global_var (var) vars as well.

I checked static local will included in FOR_EACH_LOCAL_DECL, will skip
is_global_var next version

Thanks :)


Re: [PATCH, Fortran] -- PR fortran/87923 -- fix ICE when resolving I/O tags and simplify io.c

2020-04-09 Thread Tobias Burnus

Hi,

On 4/6/20 7:25 PM, Fritz Reese via Fortran wrote:


The attached patch fixes PR 87923 while also simplifying the code in
io.c.


Thanks for the work, which looks great; it is a bit lengthy
but mostly moving code or mechanical (%C → %L).
It also has an impressive amount of new test cases!

I only have three nits:

* Please check whether the ChangeLog lines are too long; I didn't count
  but it looks as if they might be too long. For sure, they
  were too long for your mail program …

* First line in git commit "Fix fortran/87923 -- ICE(s) when resolving I/O 
tags."
  It helps with doing patch archeology if they are the same – or if the GIT one
  is a substring of the email subject. (If it is about a PR, searching for the 
PR
  usually works, but also not al emails have the PR number in the subject.)
  For this patch, you use:
  email: "[PATCH, Fortran] -- PR fortran/87923 -- fix ICE when resolving I/O tags 
and simplify io.c"
  GIT: "Fix fortran/87923 -- ICE(s) when resolving I/O tags."

* In the following comment, you have two empty tailing lines:

+   Tag expressions are already resolved by resolve_tag, which includes
+   verifying the type, that they are scalar, and verifying that BT_CHARACTER
+   tags are of default kind.
+
+   */

Otherwise: LGTM.

Thanks,

Tobias



Over the years various special cases have been introduced which are
not necessary. The constraints for I/O statements are verified in
several different places, and in fact some constraints (like whether
an I/O tag is a scalar default-kind character) are checked as many as
three times. This patches simplifies the code by moving all checks not
necessary for matching out of the matching phase and into the
resolution phase. The resolve_tag function already checks several
constraints for I/O tags, including type and kind, which were
previously checked redundantly in other places. This patch also
improves error reporting by providing the correct locus for I/O
statement error messages, and by providing a more detailed error
message when a tag which requires an init-expr is not a valid
init-expr.

The patch also increases test coverage of I/O statements, especially
for I/O tags, by incorporating testcases provided in PRs from the past
which the removed code originally addressed: specifically, PRs 66724
and 66725. With the patch applied on the current master
(c72a1b6f8b2...) all regression tests with check-fortran pass,
including the new ones.

OK for master?


commit 5a403f4e8e77123994ca1ed05e8f10877423fe55
Author: Fritz Reese 
Date:   Mon Apr 6 12:13:48 2020 -0400

 Fix fortran/87923 -- ICE(s) when resolving I/O tags.

 2020-04-06  Fritz Reese  

 This patch also reorganizes I/O checking code. Checks which were done
 in the matching phase which do not affect the match result are moved to the
 resolution phase. Checks which were duplicated in both the
matching phase and
 resolution phase have been reduced to one check in the resolution phase.

 Another section of code which used a global async_io_dt flag to
check for and
 assign the asynchronous attribute to variables used in
asynchronous I/O has been
 simplified.

 Furthermore, this patch improves error reporting and expands test
coverage of
 I/O tags:

  - "TAG must be an initialization expression" reported by io.c
(check_io_constraints) is replaced with an error from expr.c
(gfc_reduce_init_expr) indicating _why_ the expression is not a valid
initialization expression.

  - Several distinct error messages regarding the check for scalar
+ character
+ default kind have been unified to one message reported by resolve_tag
or check_*_constraints.

 gcc/fortran/ChangeLog:

 PR fortran/87923
 * gfortran.h (gfc_resolve_open, gfc_resolve_close): Add
 locus parameter.
 (gfc_resolve_dt): Add code parameter.
 * io.c (async_io_dt, check_char_variable, is_char_type): Removed.
 (resolve_tag_format): Add locus to error message regarding
zero-sized
 array in FORMAT tag.
 (check_open_constraints, check_close_constraints): New
functions called
 at resolution time.
 (gfc_match_open, gfc_match_close, match_io): Move checks which 
don't
 affect the match result to new functions check_open_constraints,
 check_close_constraints, check_io_constraints.
 (gfc_resolve_open, gfc_resolve_close): Call new functions
 check_open_constraints, check_close_constraints after all
tags have been
 independently resolved.  Remove duplicate constraints
which are already
 verified by resolve_tag. Explicitly pass locus to all error 
reports.
 (compare_to_allowed_values): Add locus parameter and
provide explicit
 locus all error reports.
 (match_open_element, match_close_element, match_file_element,
 ma

[PATCH], PowerPC, Backport PR 93932 (variable vec_extract) to GCC 9

2020-04-09 Thread Michael Meissner via Gcc-patches
Backport PR target/93932 (variable vec_extract) to GCC 9

This patch backports the fix for PR target/93932 from the current master branch
to GCC 9.  The patch for the master branch had to be adjusted due to using
different constraints (GCC 10 uses the enabled attribute to eliminate
alternatives, while GCC 9 uses special constraints).  I have tested this on a
little endian power8 system running Linux.  The bootstrap and make check had no
regressions.

This patch does fix the following test cases on power8 code:
gcc.target/powerpc/fold-vec-extract-double.p8.c
gcc.target/powerpc/fold-vec-extract-longlong.p8.c
gcc.target/powerpc/fold-vec-extract-longlong.p9.c

Can I check this patch into the gcc 9 branch?


2020-04-09  Michael Meissner  

Back port from trunk
2020-02-26  Michael Meissner  

PR target/93932
* config/rs6000/vsx.md (vsx_extract__var, VSX_D iterator):
Split the insn into two parts.  This insn only does variable
extract from a register.
(vsx_extract__var_load, VSX_D iterator): New insn, do
variable extract from memory.
(vsx_extract_v4sf_var): Split the insn into two parts.  This insn
only does variable extract from a register.
(vsx_extract_v4sf_var_load): New insn, do variable extract from
memory.
(vsx_extract__var, VSX_EXTRACT_I iterator): Split the insn
into two parts.  This insn only does variable extract from a
register.
(vsx_extract__var_load, VSX_EXTRACT_I iterator): New insn,
do variable extract from memory.

--- /tmp/t3Q8FG_vsx.md  2020-04-09 02:18:54.436474001 -0500
+++ gcc/config/rs6000/vsx.md2020-04-09 02:03:31.998405325 -0500
@@ -3292,14 +3292,14 @@ (define_insn "vsx_vslo_"
   "vslo %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
-;; Variable V2DI/V2DF extract
+;; Variable V2DI/V2DF extract from a register
 (define_insn_and_split "vsx_extract__var"
-  [(set (match_operand: 0 "gpc_reg_operand" "=v,,r")
-   (unspec: [(match_operand:VSX_D 1 "input_operand" "v,m,m")
-(match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
+  [(set (match_operand: 0 "gpc_reg_operand" "=v")
+   (unspec: [(match_operand:VSX_D 1 "gpc_reg_operand" "v")
+(match_operand:DI 2 "gpc_reg_operand" "r")]
UNSPEC_VSX_EXTRACT))
-   (clobber (match_scratch:DI 3 "=r,&b,&b"))
-   (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
+   (clobber (match_scratch:DI 3 "=r"))
+   (clobber (match_scratch:V2DI 4 "=&v"))]
   "VECTOR_MEM_VSX_P (mode) && TARGET_DIRECT_MOVE_64BIT"
   "#"
   "&& reload_completed"
@@ -3310,6 +3310,23 @@ (define_insn_and_split "vsx_extract__var_load"
+  [(set (match_operand: 0 "gpc_reg_operand" "=wa,r")
+   (unspec: [(match_operand:VSX_D 1 "memory_operand" "Q,Q")
+(match_operand:DI 2 "gpc_reg_operand" "r,r")]
+   UNSPEC_VSX_EXTRACT))
+   (clobber (match_scratch:DI 3 "=&b,&b"))]
+  "VECTOR_MEM_VSX_P (mode) && TARGET_DIRECT_MOVE_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 4))]
+{
+  operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], 
operands[2],
+  operands[3], mode);
+}
+  [(set_attr "type" "fpload,load")])
+
 ;; Extract a SF element from V4SF
 (define_insn_and_split "vsx_extract_v4sf"
   [(set (match_operand:SF 0 "vsx_register_operand" "=ww")
@@ -3361,14 +3378,14 @@ (define_insn_and_split "*vsx_extract_v4s
   [(set_attr "type" "fpload,fpload,fpload,load")
(set_attr "length" "8")])
 
-;; Variable V4SF extract
+;; Variable V4SF extract from a register
 (define_insn_and_split "vsx_extract_v4sf_var"
-  [(set (match_operand:SF 0 "gpc_reg_operand" "=ww,ww,?r")
-   (unspec:SF [(match_operand:V4SF 1 "input_operand" "v,m,m")
-   (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
+   (unspec:SF [(match_operand:V4SF 1 "gpc_reg_operand" "v")
+   (match_operand:DI 2 "gpc_reg_operand" "r")]
   UNSPEC_VSX_EXTRACT))
-   (clobber (match_scratch:DI 3 "=r,&b,&b"))
-   (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
+   (clobber (match_scratch:DI 3 "=r"))
+   (clobber (match_scratch:V2DI 4 "=&v"))]
   "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT"
   "#"
   "&& reload_completed"
@@ -3379,6 +3396,23 @@ (define_insn_and_split "vsx_extract_v4sf
   DONE;
 })
 
+;; Variable V4SF extract from memory
+(define_insn_and_split "*vsx_extract_v4sf_var_load"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=wa,?r")
+   (unspec:SF [(match_operand:V4SF 1 "memory_operand" "Q,Q")
+   (match_operand:DI 2 "gpc_reg_operand" "r,r")]
+  UNSPEC_VSX_EXTRACT))
+   (clobber (match_scratch:DI 3 "=&b,&b"))]
+  "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup

[committed] PR target/94530 (was [PATCH] PR target/48240)

2020-04-09 Thread Andrea Corallo
Hi all,

Second version of the patch for PR94530 (pr num fixed) addressing 
comments.

Bootstrapped on aarch64-unknown-linux-gnu.

Committed.

Andrea

gcc/ChangeLog

2020-04-09  Andrea Corallo  

PR target/pr94530
* config/aarch64/falkor-tag-collision-avoidance.c
(valid_src_p): Fix missing rtx type check.

gcc/testsuite/ChangeLog

2020-04-09  Andrea Corallo  

* gcc.target/aarch64/pr94530.c: New test.

>From 6136519229b43ad7a9d0d304fd42280a6757493c Mon Sep 17 00:00:00 2001
From: Andrea Corallo 
Date: Wed, 8 Apr 2020 13:38:28 +0100
Subject: [PATCH] pr94530

---
 gcc/config/aarch64/falkor-tag-collision-avoidance.c | 3 +++
 gcc/testsuite/gcc.target/aarch64/pr94530.c  | 9 +
 2 files changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr94530.c

diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.c b/gcc/config/aarch64/falkor-tag-collision-avoidance.c
index 719df484ee61..f850153fae02 100644
--- a/gcc/config/aarch64/falkor-tag-collision-avoidance.c
+++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.c
@@ -538,6 +538,9 @@ valid_src_p (rtx src, rtx_insn *insn, struct loop *loop, bool *pre_post,
   if (!aarch64_classify_address (&addr, XEXP (x, 0), mode, true))
 return false;
 
+  if (!REG_P (addr.base))
+return false;
+
   unsigned regno = REGNO (addr.base);
   if (global_regs[regno] || fixed_regs[regno])
 return false;
diff --git a/gcc/testsuite/gcc.target/aarch64/pr94530.c b/gcc/testsuite/gcc.target/aarch64/pr94530.c
new file mode 100644
index ..1f98201c50a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr94530.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mcpu=falkor -mpc-relative-literal-loads -mcmodel=large" } */
+
+extern void bar(const char *);
+
+void foo(void) {
+  for (;;)
+bar("");
+}
-- 
2.17.1



Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Jonathan Wakely via Gcc-patches
On Thu, 9 Apr 2020 at 09:05, Marc Glisse wrote:
> Note that the matching is not 1-to-1. Array vs non-array and
> aligned vs non-aligned seem important, but sized and unsized delete can
> both match the same new, IIUC.

Right.

> Not sure about the nothrow versions...

This is valid, and mixes the nothrow new with non-nothrow delete:

delete new (std::nothrow) int;


Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Marc Glisse

On Thu, 9 Apr 2020, Richard Biener wrote:


On Thu, Apr 9, 2020 at 7:06 AM Martin Liška  wrote:


Hi.

We've got one another sneaky test-case (thank you Marc ;) ):

$ cat pr94314-array.C
#include 
#include 

int count = 0;

__attribute__((malloc, noinline)) void* operator new[](unsigned long sz) {
   ++count;
   return ::operator new(sz);
}

void operator delete[](void* ptr) noexcept {
   --count;
   ::operator delete(ptr);
}

void operator delete[](void* ptr, std::size_t sz) noexcept {
   --count;
   ::operator delete(ptr, sz);
}

int main() {
   delete[] new int[1];
   if (count != 0)
 __builtin_abort ();
}

I bet we need to include the Honza's fix for inline stacks.
Or it the test-case invalid?


I don't see how inline stacking helps here when you consider

void *foo(unsigned long sz) { return ::operator new(sz); }
void operator delete[](void* ptr) noexcept {
   --count;
   ::operator delete(ptr);
}

thus regular functions inlining where definitely the inline
stack depth does not need to match.

I guess the testcase asks for us to match the exact
operator form (in the testcase we match ::delete and ::new[]),
for example by instead of looking at the decl flags
simply match the assembler names (the mangled names)
of the operator?


A hard-coded list can make sense (although if we use asm names, I guess we 
have to take care of platforms that prefix all symbols with _ for 
instance). Note that the matching is not 1-to-1. Array vs non-array and 
aligned vs non-aligned seem important, but sized and unsized delete can 
both match the same new, IIUC. Not sure about the nothrow versions...


--
Marc Glisse


Re: [PATCH] PR target/48240

2020-04-09 Thread Andrea Corallo
Kyrylo Tkachov  writes:

> diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.c 
> b/gcc/config/aarch64/falkor-tag-collision-avoidance.c
> index 719df484ee61..4e07a43282f7 100644
> --- a/gcc/config/aarch64/falkor-tag-collision-avoidance.c
> +++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.c
> @@ -538,9 +538,12 @@ valid_src_p (rtx src, rtx_insn *insn, struct loop *loop, 
> bool *pre_post,
>if (!aarch64_classify_address (&addr, XEXP (x, 0), mode, true))
>  return false;
>  
> -  unsigned regno = REGNO (addr.base);
> -  if (global_regs[regno] || fixed_regs[regno])
> -return false;
> +  if (REG_P (addr.base))
> +{
> +  unsigned regno = REGNO (addr.base);
> +  if (global_regs[regno] || fixed_regs[regno])
> + return false;
> +}
>
> I think we want to just return false here if !REG_P (addr.base) rather than 
> fall through?

I think functionally would be equivalent cause after we guard on
addr.type, but probably nicer.

> +++ b/gcc/testsuite/gcc.target/aarch64/pr48240.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-v -Os -mcpu=falkor -mpc-relative-literal-loads 
> -mcmodel=large" } */
>
> We shouldn't need the "-v" here...

Ack

> Ok with those changes.
> Thanks,
> Kyrill

Thanks for reviewing updating the patch!

  Andrea


Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Jakub Jelinek via Gcc-patches
On Thu, Apr 09, 2020 at 08:59:59AM +0200, Martin Liška wrote:
> What do you mean by 'decl flags'. We can't compare ASM names as one is ctor
> and the second one is dtor. It's about argument types that much match, right?

You can't disginguish the [] vs. non-[] from arguments, plus there are some
changes in the arguments in all cases anyway (e.g. first argument of
operator delete always being the pointer, while first argument of operator
new being size_t, but some operator delete forms also having size_t after
it).
See http://eel.is/c++draft/new.delete 
[[nodiscard]] void* operator new(std::size_t size);
[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment);
[[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) 
noexcept;
[[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment, 
const std::nothrow_t&) noexcept;
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) 
noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, std::align_val_t alignment, const 
std::nothrow_t&) noexcept;
[[nodiscard]] void* operator new[](std::size_t size);
[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t 
alignment);
[[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) 
noexcept;
[[nodiscard]] void* operator new[](std::size_t size, std::align_val_t 
alignment, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) 
noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment, const 
std::nothrow_t&) noexcept;

I believe one can't allocate with operator new and free with operator delete[]
or allocate with operator new[] and free with operator delete, but am not
sure if there aren't other requirements?
E.g. "If the alignment parameter is not present, ptr was returned by an 
allocation function
without an alignment parameter.  If present, the alignment argument is equal to 
the
alignment argument passed to the allocation function that returned ptr."
suggests one can't mix the std::align_val_t vs. non-std::align_val_t cases,
dunno about the throwing vs. non-throwing or sizd ones.

Jakub



Re: [PATCH v3] Fix alignment for local variable [PR90811]

2020-04-09 Thread Richard Biener via Gcc-patches
On Wed, Apr 8, 2020 at 7:13 PM Kito Cheng  wrote:
>
> ping
>
> On Tue, Mar 31, 2020 at 4:33 PM Kito Cheng  wrote:
> >
> >  - The alignment for local variable was adjust during 
> > estimate_stack_frame_size,
> >however it seems wrong spot to adjust that, expand phase will adjust that
> >but it little too late to some gimple optimization, which rely on certain
> >target hooks need to check alignment, forwprop is an example for
> >that, result of simplify_builtin_call rely on the alignment on some
> >target like ARM or RISC-V.
> >
> >  - This patch fix gfortran.dg/pr45636.f90 for arm and riscv.
> >
> >  - Regression test on riscv32/riscv64 and x86_64-linux-gnu, no new fail
> >introduced.
> >
> > gcc/ChangeLog
> >
> > PR target/90811
> > * Makefile.in (OBJS): Add tree-adjust-alignment.o.
> > * tree-adjust-alignment.cc (pass_data_adjust_alignment): New.
> > (pass_adjust_alignment): New.
> > (-pass_adjust_alignment::execute): New.
> > (make_pass_adjust_alignment): New.
> > * tree-pass.h (make_pass_adjust_alignment): New.
> > * passes.def: Add pass_adjust_alignment.
> > ---
> >  gcc/Makefile.in  |  1 +
> >  gcc/passes.def   |  1 +
> >  gcc/tree-adjust-alignment.cc | 88 
> >  gcc/tree-pass.h  |  1 +
> >  4 files changed, 91 insertions(+)
> >  create mode 100644 gcc/tree-adjust-alignment.cc
> >
> > diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> > index fa9923bb270..9b73288f776 100644
> > --- a/gcc/Makefile.in
> > +++ b/gcc/Makefile.in
> > @@ -1545,6 +1545,7 @@ OBJS = \
> > ubsan.o \
> > sanopt.o \
> > sancov.o \
> > +   tree-adjust-alignment.o \
> > tree-call-cdce.o \
> > tree-cfg.o \
> > tree-cfgcleanup.o \
> > diff --git a/gcc/passes.def b/gcc/passes.def
> > index 2bf2cb78fc5..92cbe587a8a 100644
> > --- a/gcc/passes.def
> > +++ b/gcc/passes.def
> > @@ -183,6 +183,7 @@ along with GCC; see the file COPYING3.  If not see
> >NEXT_PASS (pass_oacc_device_lower);
> >NEXT_PASS (pass_omp_device_lower);
> >NEXT_PASS (pass_omp_target_link);
> > +  NEXT_PASS (pass_adjust_alignment);
> >NEXT_PASS (pass_all_optimizations);
> >PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations)
> >NEXT_PASS (pass_remove_cgraph_callee_edges);
> > diff --git a/gcc/tree-adjust-alignment.cc b/gcc/tree-adjust-alignment.cc
> > new file mode 100644
> > index 000..1269f93e56a
> > --- /dev/null
> > +++ b/gcc/tree-adjust-alignment.cc
> > @@ -0,0 +1,88 @@
> > +/* Adjust alignment for local variable.
> > +   Copyright (C) 2003-2020 Free Software Foundation, Inc.
> > +   Contributed by Dorit Naishlos 
> > +
> > +This file is part of GCC.
> > +
> > +GCC is free software; you can redistribute it and/or modify it under
> > +the terms of the GNU General Public License as published by the Free
> > +Software Foundation; either version 3, or (at your option) any later
> > +version.
> > +
> > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> > +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> > +for more details.
> > +
> > +You should have received a copy of the GNU General Public License
> > +along with GCC; see the file COPYING3.  If not see
> > +.  */
> > +
> > +#include "config.h"
> > +#include "system.h"
> > +#include "coretypes.h"
> > +#include "backend.h"
> > +#include "target.h"
> > +#include "tree.h"
> > +#include "gimple.h"
> > +#include "tree-pass.h"
> > +#include "cgraph.h"
> > +#include "fold-const.h"
> > +#include "gimple-iterator.h"
> > +#include "tree-cfg.h"
> > +#include "cfgloop.h"
> > +#include "tree-vectorizer.h"
> > +#include "tm_p.h"
> > +
> > +namespace {
> > +
> > +const pass_data pass_data_adjust_alignment =
> > +{
> > +  GIMPLE_PASS, /* type */
> > +  "adjust_alignment", /* name */
> > +  OPTGROUP_NONE, /* optinfo_flags */
> > +  TV_NONE, /* tv_id */
> > +  0, /* properties_required */
> > +  0, /* properties_provided */
> > +  0, /* properties_destroyed */
> > +  0, /* todo_flags_start */
> > +  0, /* todo_flags_finish */
> > +};
> > +
> > +class pass_adjust_alignment : public gimple_opt_pass
> > +{
> > +public:
> > +  pass_adjust_alignment (gcc::context *ctxt)
> > +: gimple_opt_pass (pass_data_adjust_alignment, ctxt)
> > +  {}
> > +
> > +  virtual unsigned int execute (function *);
> > +
> > +}; // class pass_adjust_alignment
> > +
> > +} // anon namespace
> > +
> > +/* Entry point to adjust_alignment pass.  */
> > +unsigned int
> > +pass_adjust_alignment::execute (function *fun) {
> > +  size_t i;
> > +  tree var;
> > +  struct cgraph_node *node;
> > +  unsigned int align;
> > +
> > +  FOR_EACH_LOCAL_DECL (fun, i, var)
> > +{

Please skip vars with DECL_USER_ALIGN.

Note local-decls also contains the base variables that
are written into S

Re: [PATCH] PR target/48240

2020-04-09 Thread Andrea Corallo
Richard Sandiford  writes:

> Andrea Corallo  writes:
>> Hi all,
>>
>> I'd like to submit this for PR48240.
>>
>> Bootstrapped on aarch64-unknown-linux-gnu.
>> Okay for trunk when finished with regression?
>
> OK, but the PR number looks like a typo.  Also:

Ooops, no idea how did I managed to generated this number.

>> Andrea
>>
>> gcc/ChangeLog
>>
>> 2020-??-??  Andrea Corallo  
>>
>>  PR target/48240
>>  * gcc/config/aarch64/falkor-tag-collision-avoidance.c
>>  (valid_src_p): Fix missing rtx type check.
>
> no gcc/ prefix here.
>
> Thanks,
> Richard


Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Richard Biener via Gcc-patches
On Thu, Apr 9, 2020 at 9:00 AM Martin Liška  wrote:
>
> On 4/9/20 8:45 AM, Richard Biener wrote:
> > On Thu, Apr 9, 2020 at 7:06 AM Martin Liška  wrote:
> >>
> >> Hi.
> >>
> >> We've got one another sneaky test-case (thank you Marc ;) ):
> >>
> >> $ cat pr94314-array.C
> >> #include 
> >> #include 
> >>
> >> int count = 0;
> >>
> >> __attribute__((malloc, noinline)) void* operator new[](unsigned long sz) {
> >> ++count;
> >> return ::operator new(sz);
> >> }
> >>
> >> void operator delete[](void* ptr) noexcept {
> >> --count;
> >> ::operator delete(ptr);
> >> }
> >>
> >> void operator delete[](void* ptr, std::size_t sz) noexcept {
> >> --count;
> >> ::operator delete(ptr, sz);
> >> }
> >>
> >> int main() {
> >> delete[] new int[1];
> >> if (count != 0)
> >>   __builtin_abort ();
> >> }
> >>
> >> I bet we need to include the Honza's fix for inline stacks.
> >> Or it the test-case invalid?
> >
> > I don't see how inline stacking helps here when you consider
> >
> > void *foo(unsigned long sz) { return ::operator new(sz); }
> > void operator delete[](void* ptr) noexcept {
> >  --count;
> >  ::operator delete(ptr);
> > }
> >
> > thus regular functions inlining where definitely the inline
> > stack depth does not need to match.
>
> I was considering quite strict rules:
> - inline stack can contain only up to 1 replaceable operator new (or delete)
> - no non-replaceable operators are allowed
> - number of repl. operator much match.
>
> >
> > I guess the testcase asks for us to match the exact
> > operator form (in the testcase we match ::delete and ::new[]),
> > for example by instead of looking at the decl flags
> > simply match the assembler names (the mangled names)
> > of the operator?
>
> What do you mean by 'decl flags'. We can't compare ASM names as one is ctor
> and the second one is dtor. It's about argument types that much match, right?

Sure, we have to make a translation from delete to new ODR name and compare
those.  I thought of simply having an array of predefined pairs like

{ { "_Znam", "_ZdaPvm" }, ... }

if programmatically translating the ODR name of the delete to the corresponding
new one is too difficult.

Richard.

> Thanks,
> Martin
>
> >
> > Richard.
> >
> >> Thanks,
> >> Martin
>


Re: [PATCH] Allow new/delete operator deletion only for replaceable.

2020-04-09 Thread Martin Liška

On 4/9/20 8:45 AM, Richard Biener wrote:

On Thu, Apr 9, 2020 at 7:06 AM Martin Liška  wrote:


Hi.

We've got one another sneaky test-case (thank you Marc ;) ):

$ cat pr94314-array.C
#include 
#include 

int count = 0;

__attribute__((malloc, noinline)) void* operator new[](unsigned long sz) {
++count;
return ::operator new(sz);
}

void operator delete[](void* ptr) noexcept {
--count;
::operator delete(ptr);
}

void operator delete[](void* ptr, std::size_t sz) noexcept {
--count;
::operator delete(ptr, sz);
}

int main() {
delete[] new int[1];
if (count != 0)
  __builtin_abort ();
}

I bet we need to include the Honza's fix for inline stacks.
Or it the test-case invalid?


I don't see how inline stacking helps here when you consider

void *foo(unsigned long sz) { return ::operator new(sz); }
void operator delete[](void* ptr) noexcept {
 --count;
 ::operator delete(ptr);
}

thus regular functions inlining where definitely the inline
stack depth does not need to match.


I was considering quite strict rules:
- inline stack can contain only up to 1 replaceable operator new (or delete)
- no non-replaceable operators are allowed
- number of repl. operator much match.



I guess the testcase asks for us to match the exact
operator form (in the testcase we match ::delete and ::new[]),
for example by instead of looking at the decl flags
simply match the assembler names (the mangled names)
of the operator?


What do you mean by 'decl flags'. We can't compare ASM names as one is ctor
and the second one is dtor. It's about argument types that much match, right?

Thanks,
Martin



Richard.


Thanks,
Martin


>From 16c77b6b65e31be657f91dcf0308f1638a784d7a Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Thu, 9 Apr 2020 07:36:56 +0200
Subject: [PATCH] Compare inline stacks for new/delete repl. operators.

gcc/ChangeLog:

2020-04-09  Martin Liska  

	PR c++/94314
	* tree-ssa-dce.c (compare_new_delete_inline_contexts):
	(propagate_necessity):
	* cgraphclones.c (set_new_clone_decl_and_node_flags):
	Drop DECL_IS_REPLACEABLE_OPERATOR to false.

gcc/testsuite/ChangeLog:

2020-04-09  Martin Liska  

	PR c++/94314
	* g++.dg/pr94314-4.C: New test.
	* g++.dg/pr94314.C: Do not expect a dtor deletion.
---
 gcc/cgraphclones.c   |  2 +
 gcc/testsuite/g++.dg/pr94314-4.C | 33 ++
 gcc/testsuite/g++.dg/pr94314.C   |  2 +-
 gcc/tree-ssa-dce.c   | 76 +++-
 4 files changed, 102 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr94314-4.C

diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index c73b8f810f0..8f541a28b6e 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -165,6 +165,7 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
   DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
   DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
   DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
+  DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
 
   new_node->externally_visible = 0;
   new_node->local = 1;
@@ -1030,6 +1031,7 @@ cgraph_node::create_version_clone_with_body
   DECL_STATIC_DESTRUCTOR (new_decl) = 0;
   DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
   DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
+  DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
 
   /* Create the new version's call-graph node.
  and update the edges of the new node. */
diff --git a/gcc/testsuite/g++.dg/pr94314-4.C b/gcc/testsuite/g++.dg/pr94314-4.C
new file mode 100644
index 000..afa2a443dc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr94314-4.C
@@ -0,0 +1,33 @@
+/* PR c++/94314.  */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-cddce-details -std=c++14" } */
+/* { dg-additional-options "-fdelete-null-pointer-checks" } */
+
+#include 
+
+int count = 0;
+
+__attribute__((malloc, noinline)) void* operator new[](__SIZE_TYPE__ sz) {
+  ++count;
+  return ::operator new(sz);
+}
+
+void operator delete[](void* ptr) noexcept {
+  --count;
+  ::operator delete(ptr);
+}
+
+void operator delete[](void* ptr, __SIZE_TYPE__ sz) noexcept {
+  --count;
+  ::operator delete(ptr, sz);
+}
+
+int main() {
+  delete[] new int[1];
+  if (count != 0)
+__builtin_abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Deleting : operator delete" "cddce1"} } */
diff --git a/gcc/testsuite/g++.dg/pr94314.C b/gcc/testsuite/g++.dg/pr94314.C
index 86e651d10ba..da293a7dd9b 100644
--- a/gcc/testsuite/g++.dg/pr94314.C
+++ b/gcc/testsuite/g++.dg/pr94314.C
@@ -81,5 +81,5 @@ int main(){
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 1 "cddce1"} } */
+/* { dg-final { scan-tree-dump-not "Deleting : operator delete" "cddce1"} } */
 /* { dg-final { scan-tree-dump-not "Deleting : B::operator delete" "cddce1"} } */
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index fd5f24c746c..e1085d6b049 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -646,6 +646,53 @@ degenerate_phi_p (gimple *p