[PATCH] gimplify: Fix ICE in recalculate_side_effects [PR113228]

2024-01-06 Thread Jakub Jelinek
Hi!

The following testcase ICEs during regimplificatgion since the addition of
(convert (eqne zero_one_valued_p@0 INTEGER_CST@1))
simplification.  That simplification is novel in the sense that in
gimplify_expr it can turn an expression (comparison in particular) into
a SSA_NAME.  Normally when gimplify_expr sees originally a SSA_NAME, it does
case SSA_NAME:
  /* Allow callbacks into the gimplifier during optimization.  */
  ret = GS_ALL_DONE;
  break;
and doesn't try to recalculate side effects because of that, but in this
case gimplify_expr normally enters the:
default:
  switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
{
case tcc_comparison:
then does
  *expr_p = gimple_boolify (*expr_p);
and then
  *expr_p = fold_convert_loc (input_location,
  org_type, *expr_p);
with this new match.pd simplification turns that tcc_comparison class
into SSA_NAME.  Unlike the outer SSA_NAME handling though, this falls
through into
  recalculate_side_effects (*expr_p);

dont_recalculate:
  break;
but unfortunately recalculate_side_effects doesn't handle SSA_NAME and ICEs
on it.
SSA_NAMEs don't ever have TREE_SIDE_EFFECTS set on those, so the following
patch fixes it by handling it similarly to the tcc_constant case.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-01-06  Jakub Jelinek  

PR tree-optimization/113228
* gimplify.cc (recalculate_side_effects): Do nothing for SSA_NAMEs.

* gcc.c-torture/compile/pr113228.c: New test.

--- gcc/gimplify.cc.jj  2024-01-03 11:51:40.744603324 +0100
+++ gcc/gimplify.cc 2024-01-05 13:32:34.351336320 +0100
@@ -3344,6 +3344,9 @@ recalculate_side_effects (tree t)
   return;
 
 default:
+  if (code == SSA_NAME)
+   /* No side-effects.  */
+   return;
   gcc_unreachable ();
}
 }
--- gcc/testsuite/gcc.c-torture/compile/pr113228.c.jj   2024-01-05 
13:27:42.876330301 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr113228.c  2024-01-05 
13:27:22.503609458 +0100
@@ -0,0 +1,17 @@
+/* PR tree-optimization/113228 */
+
+int a, b, c, d, i;
+
+void
+foo (void)
+{
+  int k[3] = {};
+  int *l = &a;
+  for (d = 0; c; c--)
+for (i = 0; i <= 9; i++)
+  {
+   for (b = 1; b <= 4; b++)
+ k[0] = k[0] == 0;
+   *l |= k[d];
+  }
+}

Jakub



Re: [PATCH] LoongArch: Optimize zero_extendqisi2 and zero_extendqidi2 patterns

2024-01-06 Thread chenglulu

Hi,jiahao:

 The instruction latencies of the two instructions I tested here are 
the same on 3a5000 and 3a6000.


This issue needs to be confirmed again.

在 2024/1/5 下午3:37, Jiahao Xu 写道:

For zero_extendqisi2 and zero_extendqidi2, use andi instead of bstrpick.w,
because andi is 6 times faster than bstrpick.w.

gcc/ChangeLog:

* config/loongarch/loongarch.md:
(zero_extend2): Rename to ..
(zero_extendhi2): .. this, use hi.
(zero_extendqihi2): Rename to ..
(zero_extendqi2): .. this, and extend to HWD.
(*zero_extend_trunc): Rename to ..
(*zero_extend_trunchi): .. this, use hi.
(*zero_extendhi_truncqi): Rename to ..
(*zero_extend_truncqi): .. this, and extend to HWD.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/zeroextend-qi.c: New test.

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index d1f5b94f5d6..843dee77a60 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -397,6 +397,9 @@
  ;; Likewise the 64-bit truncate-and-shift patterns.
  (define_mode_iterator SUBDI [QI HI SI])
  
+;; Scalar fixed point modes but excludes QI.

+(define_mode_iterator HWD [HI SI (DI "TARGET_64BIT")])
+
  ;; Iterator for scalar fixed point modes.
  (define_mode_iterator QHWD [QI HI SI (DI "TARGET_64BIT")])
  
@@ -1659,48 +1662,48 @@

[(set_attr "move_type" "arith,load,load,load")
 (set_attr "mode" "DI")])
  
-(define_insn "zero_extend2"

+(define_insn "zero_extendhi2"
[(set (match_operand:GPR 0 "register_operand" "=r,r,r")
(zero_extend:GPR
-(match_operand:SHORT 1 "nonimmediate_operand" "r,m,k")))]
+(match_operand:HI 1 "nonimmediate_operand" "r,m,k")))]
""
"@
-   bstrpick.w\t%0,%1,,0
-   ld.u\t%0,%1
-   ldx.u\t%0,%1"
+   bstrpick.w\t%0,%1,15,0
+   ld.hu\t%0,%1
+   ldx.hu\t%0,%1"
[(set_attr "move_type" "pick_ins,load,load")
 (set_attr "mode" "")])
  
-(define_insn "zero_extendqihi2"

-  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
-   (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,k,m")))]
+(define_insn "zero_extendqi2"
+  [(set (match_operand:HWD 0 "register_operand" "=r,r,r")
+   (zero_extend:HWD (match_operand:QI 1 "nonimmediate_operand" "r,k,m")))]
""
"@
 andi\t%0,%1,0xff
 ldx.bu\t%0,%1
 ld.bu\t%0,%1"
[(set_attr "move_type" "andi,load,load")
-   (set_attr "mode" "HI")])
+   (set_attr "mode" "")])
  
  ;; Combiner patterns to optimize truncate/zero_extend combinations.
  
-(define_insn "*zero_extend_trunc"

+(define_insn "*zero_extend_trunchi"
[(set (match_operand:GPR 0 "register_operand" "=r")
(zero_extend:GPR
-   (truncate:SHORT (match_operand:DI 1 "register_operand" "r"]
+   (truncate:HI (match_operand:DI 1 "register_operand" "r"]
"TARGET_64BIT"
-  "bstrpick.w\t%0,%1,,0"
+  "bstrpick.w\t%0,%1,15,0"
[(set_attr "move_type" "pick_ins")
 (set_attr "mode" "")])
  
-(define_insn "*zero_extendhi_truncqi"

-  [(set (match_operand:HI 0 "register_operand" "=r")
-   (zero_extend:HI
+(define_insn "*zero_extend_truncqi"
+  [(set (match_operand:HWD 0 "register_operand" "=r")
+   (zero_extend:HWD
(truncate:QI (match_operand:DI 1 "register_operand" "r"]
"TARGET_64BIT"
"andi\t%0,%1,0xff"
[(set_attr "alu_type" "and")
-   (set_attr "mode" "HI")])
+   (set_attr "mode" "")])
  
  ;;
  ;;  
diff --git a/gcc/testsuite/gcc.target/loongarch/zeroextend-qi.c 
b/gcc/testsuite/gcc.target/loongarch/zeroextend-qi.c
new file mode 100644
index 000..1da8cdad2ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/zeroextend-qi.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "andi" } } */
+
+#include 
+
+uint8_t
+foo (uint64_t a, uint8_t b)
+{
+  return a + b;
+}




[PATCH 2/3] LoongArch: Redundant sign extension elimination optimization.

2024-01-06 Thread Lulu Cheng
From: liwei 

We found that the current combine optimization pass in gcc cannot handle
the following redundant sign extension situations:

(insn 77 76 78 5 (set (reg:SI 143)
(plus:SI (subreg/s/u:SI (reg/v:DI 104 [ len ]) 0)
(const_int 1 [0x1]))) {addsi3}
(expr_list:REG_DEAD (reg/v:DI 104 [ len ])
(nil)))
(insn 78 77 82 5 (set (reg/v:DI 104 [ len ])
(sign_extend:DI (reg:SI 143))) {extendsidi2}
(nil))

Because reg:SI 143 is not died or set in insn 78, no replacement merge will
be performed for the insn sequence. We adjusted the add template to eliminate
redundant sign extensions during the expand pass.

gcc/ChangeLog:

* config/loongarch/loongarch.md (add3): Removed.
(*addsi3): New.
(addsi3): New.
(adddi3): New.
(*addsi3_extended): Removed.
(addsi3_extended): New.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/sign-extend.c: Moved to...
* gcc.target/loongarch/sign-extend-1.c: ...here.
* gcc.target/loongarch/sign-extend-2.c: New test.
---
 gcc/config/loongarch/loongarch.md | 93 ---
 .../{sign-extend.c => sign-extend-1.c}|  0
 .../gcc.target/loongarch/sign-extend-2.c  | 59 
 3 files changed, 137 insertions(+), 15 deletions(-)
 rename gcc/testsuite/gcc.target/loongarch/{sign-extend.c => sign-extend-1.c} 
(100%)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/sign-extend-2.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 436b9a93235..17ec401f535 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -657,15 +657,15 @@ (define_insn "add3"
   [(set_attr "type" "fadd")
(set_attr "mode" "")])
 
-(define_insn_and_split "add3"
-  [(set (match_operand:GPR 0 "register_operand" "=r,r,r,r,r,r,r")
-   (plus:GPR (match_operand:GPR 1 "register_operand" "r,r,r,r,r,r,r")
- (match_operand:GPR 2 "plus__operand"
+(define_insn_and_split "*addsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
+   (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r,r,r")
+ (match_operand:SI 2 "plus_si_operand"
   "r,I,La,Lb,Lc,Ld,Le")))]
   ""
   "@
-   add.\t%0,%1,%2
-   addi.\t%0,%1,%2
+   add.w\t%0,%1,%2
+   addi.w\t%0,%1,%2
#
* operands[2] = GEN_INT (INTVAL (operands[2]) / 65536); \
  return \"addu16i.d\t%0,%1,%2\";
@@ -674,25 +674,88 @@ (define_insn_and_split "add3"
#"
   "CONST_INT_P (operands[2]) && !IMM12_INT (operands[2]) \
&& !ADDU16I_OPERAND (INTVAL (operands[2]))"
-  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
-   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
+  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
+   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
   {
-loongarch_split_plus_constant (&operands[2], mode);
+loongarch_split_plus_constant (&operands[2], SImode);
   }
   [(set_attr "alu_type" "add")
-   (set_attr "mode" "")
+   (set_attr "mode" "SI")
(set_attr "insn_count" "1,1,2,1,2,2,2")
(set (attr "enabled")
   (cond
-   [(match_test "mode != DImode && which_alternative == 4")
+   [(match_test "which_alternative == 4")
 (const_string "no")
-(match_test "mode != DImode && which_alternative == 5")
-(const_string "no")
-(match_test "mode != SImode && which_alternative == 6")
+(match_test "which_alternative == 5")
+(const_string "no")]
+   (const_string "yes")))])
+
+(define_expand "addsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
+   (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r")
+(match_operand:SI 2 "plus_si_operand"  "r,I,La,Le,Lb")))]
+  ""
+{
+  if (TARGET_64BIT)
+{
+  if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2])
+ && ADDU16I_OPERAND (INTVAL (operands[2])))
+   {
+ rtx t1 = gen_reg_rtx (DImode);
+ rtx t2 = gen_reg_rtx (DImode);
+ rtx t3 = gen_reg_rtx (DImode);
+ emit_insn (gen_extend_insn (t1, operands[1], DImode, SImode, 0));
+ t2 = operands[2];
+ emit_insn (gen_adddi3 (t3, t1, t2));
+ t3 = gen_lowpart (SImode, t3);
+ emit_move_insn (operands[0], t3);
+ DONE;
+   }
+  else
+   {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_addsi3_extended (t, operands[1], operands[2]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ DONE;
+   }
+}
+})
+
+(define_insn_and_split "adddi3"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
+   (plus:DI (match_operand:DI 1 "register_operand" "r,r,r,r,r,r,r")
+ (match_operand:DI 2 "plus_di_operand"
+   

[PATCH 1/3] LoongArch: Optimized some of the symbolic expansion instructions generated during bitwise operations.

2024-01-06 Thread Lulu Cheng
There are two mode iterators defined in the loongarch.md:
(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
  and
(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
Replace the mode in the bit arithmetic from GPR to X.

Since the bitwise operation instruction does not distinguish between 64-bit,
32-bit, etc., it is necessary to perform symbolic expansion if the bitwise
operation is less than 64 bits.
The original definition would have generated a lot of redundant symbolic
extension instructions. This problem is optimized with reference to the
implementation of RISCV.

Add this patch spec2017 500.perlbench performance improvement by 1.8%

gcc/ChangeLog:

* config/loongarch/loongarch.md (one_cmpl2): Replace GPR with X.
(*nor3): Likewise.
(nor3): Likewise.
(*negsi2_extended): New template.
(*si3_internal): Likewise.
(*one_cmplsi2_internal): Likewise.
(*norsi3_internal): Likewise.
(*nsi_internal): Likewise.
(bytepick_w__extend): Modify this template according to 
the
modified bit operation to make the optimization work.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/sign-extend-bitwise.c: New test.
---
 gcc/config/loongarch/loongarch.md | 93 ++-
 .../loongarch/sign-extend-bitwise.c   | 21 +
 2 files changed, 90 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/sign-extend-bitwise.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index d1f5b94f5d6..436b9a93235 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -736,7 +736,7 @@ (define_insn "sub3"
 
 (define_insn "sub3"
   [(set (match_operand:GPR 0 "register_operand" "=r")
-   (minus:GPR (match_operand:GPR 1 "register_operand" "rJ")
+   (minus:GPR (match_operand:GPR 1 "register_operand" "r")
   (match_operand:GPR 2 "register_operand" "r")))]
   ""
   "sub.\t%0,%z1,%2"
@@ -1412,13 +1412,13 @@ (define_insn "neg2"
   [(set_attr "alu_type""sub")
(set_attr "mode" "")])
 
-(define_insn "one_cmpl2"
-  [(set (match_operand:GPR 0 "register_operand" "=r")
-   (not:GPR (match_operand:GPR 1 "register_operand" "r")))]
-  ""
-  "nor\t%0,%.,%1"
-  [(set_attr "alu_type" "not")
-   (set_attr "mode" "")])
+(define_insn "*negsi2_extended"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (sign_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"]
+  "TARGET_64BIT"
+  "sub.w\t%0,%.,%1"
+  [(set_attr "alu_type" "sub")
+   (set_attr "mode" "SI")])
 
 (define_insn "neg2"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
@@ -1438,14 +1438,39 @@ (define_insn "neg2"
 ;;
 
 (define_insn "3"
-  [(set (match_operand:GPR 0 "register_operand" "=r,r")
-   (any_bitwise:GPR (match_operand:GPR 1 "register_operand" "%r,r")
-(match_operand:GPR 2 "uns_arith_operand" "r,K")))]
+  [(set (match_operand:X 0 "register_operand" "=r,r")
+   (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
+  (match_operand:X 2 "uns_arith_operand" "r,K")))]
   ""
   "%i2\t%0,%1,%2"
   [(set_attr "type" "logical")
(set_attr "mode" "")])
 
+(define_insn "*si3_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
+   (match_operand:SI 2 "uns_arith_operand"" r,K")))]
+  "TARGET_64BIT"
+  "%i2\t%0,%1,%2"
+  [(set_attr "type" "logical")
+   (set_attr "mode" "SI")])
+
+(define_insn "one_cmpl2"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (not:X (match_operand:X 1 "register_operand" "r")))]
+  ""
+  "nor\t%0,%.,%1"
+  [(set_attr "alu_type" "not")
+   (set_attr "mode" "")])
+
+(define_insn "*one_cmplsi2_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (not:SI (match_operand:SI 1 "register_operand" " r")))]
+  "TARGET_64BIT"
+  "nor\t%0,%.,%1"
+  [(set_attr "type" "logical")
+   (set_attr "mode" "SI")])
+
 (define_insn "and3_extended"
   [(set (match_operand:GPR 0 "register_operand" "=r")
(and:GPR (match_operand:GPR 1 "nonimmediate_operand" "r")
@@ -1561,25 +1586,43 @@ (define_insn "*iorhi3"
   [(set_attr "type" "logical")
(set_attr "mode" "HI")])
 
-(define_insn "*nor3"
-  [(set (match_operand:GPR 0 "register_operand" "=r")
-   (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "%r"))
-(not:GPR (match_operand:GPR 2 "register_operand" "r"]
+(define_insn "nor3"
+  [(set (match_operand:X 0 "register_operand" "=r")
+   (and:X (not:X (match_operand:X 1 "register_operand" "%r"))
+(not:X (match_operand:X 2 "register_operand" "r"]
   ""
   "nor\t%0,%1,%2"
   [(set_attr "type" "logical")
(set_attr "mode" "")])
 
+(define_insn "*norsi3_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (and:SI (not:S

[PATCH 3/3] LoongArch: Redundant sign extension elimination optimization 2.

2024-01-06 Thread Lulu Cheng
From: liwei 

Eliminate the redundant sign extension that exists after the conditional
move when the target register is SImode.

gcc/ChangeLog:

* config/loongarch/loongarch.cc (loongarch_expand_conditional_move):
Adjust.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/sign-extend-2.c: Adjust.
---
 gcc/config/loongarch/loongarch.cc  | 2 ++
 gcc/testsuite/gcc.target/loongarch/sign-extend-2.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index ec376a7228a..4b757b30b64 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -5371,6 +5371,8 @@ loongarch_expand_conditional_move (rtx *operands)
  rtx temp3 = gen_reg_rtx (mode);
  emit_insn (gen_rtx_SET (temp3, gen_rtx_IOR (mode, temp, temp2)));
  temp3 = gen_lowpart (GET_MODE (operands[0]), temp3);
+ SUBREG_PROMOTED_VAR_P (temp3) = 1;
+ SUBREG_PROMOTED_SET (temp3, SRP_SIGNED);
  loongarch_emit_move (operands[0], temp3);
}
   else
diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c 
b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
index a45dde4f73f..428535cb8e3 100644
--- a/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-mabi=lp64d -O2" } */
-/* { dg-final { scan-assembler-times "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" 1 
} } */
+/* { dg-final { scan-assembler-times "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" 0 
} } */
 
 #include 
 #define my_min(x, y) ((x) < (y) ? (x) : (y))
-- 
2.39.3



[PATCH] vect: Fix ICE in vect_analyze_loop_costing [PR113210]

2024-01-06 Thread Jakub Jelinek
Hi!

The following testcase ICEs (on ARM/RISCV with certain options), because niters 
analysis
computes number of latch executions for the loop as
(short unsigned int) (a.0_1 + 255) + 1 > 256 ? ~(short unsigned int) (a.0_1 + 
255) : 0
where a.0_1 is unsigned char.  This is correct, but given that a.0_1 + 255
is done in unsigned char the condition is never true and so it is actually
equivalent to 0, but the folders don't know that.
The vectorizer sets LOOP_VINFO_NITERSM1 to that expression and does on with
computing LOOP_VINFO_NITERS by fold_build2 PLUS_EXPR of that expression
unshared and INTEGER_CST one.  In that folding we trigger various
optimizations, first it is correctly simplified into
(short unsigned int) (a.0_1 + 255) + 1 > 256 ? -(short unsigned int) (a.0_1 + 
255) : 1
and next using
/* (X + 1) > Y ? -X : 1 simplifies to X >= Y ? -X : 1 when
   X is unsigned, as when X + 1 overflows, X is -1, so -X == 1.  */
into
(short unsigned int) (a.0_1 + 255) >= 256 ? -(short unsigned int) (a.0_1 + 255) 
: 1
and for this the first COND_EXPR argument is folded and figured out to be 0
and so while LOOP_VINFO_NITERSM1 is a complex expression (unknown to be
equivalent to 0), LOOP_VINFO_NITERS is INTEGER_CST 1.
vect_analyze_loop_costing then uses LOOP_VINFO_NITERS_KNOWN_P (which checks
if LOOP_VINFO_NITERS is INTEGER_CST which fits into shwi or something like
that) and from that assumes that LOOP_VINFO_NITERSM1 will be INTEGER_CST.

The following patch fixes that by adding verification for that too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-01-06  Jakub Jelinek  

PR tree-optimization/113210
* tree-vect-loop.cc (vect_analyze_loop_costing): If LOOP_VINFO_NITERSM1
is not INTEGER_CST, don't try to use it.

* gcc.c-torture/compile/pr113210.c: New test.

--- gcc/tree-vect-loop.cc.jj2024-01-03 11:51:22.787852547 +0100
+++ gcc/tree-vect-loop.cc   2024-01-05 17:12:06.511512557 +0100
@@ -2264,7 +2264,8 @@ vect_analyze_loop_costing (loop_vec_info
  epilogue we can also decide whether the main loop leaves us
  with enough iterations, prefering a smaller vector epilog then
  also possibly used for the case we skip the vector loop.  */
-  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+  && TREE_CODE (LOOP_VINFO_NITERSM1 (loop_vinfo)) == INTEGER_CST)
 {
   widest_int scalar_niters
= wi::to_widest (LOOP_VINFO_NITERSM1 (loop_vinfo)) + 1;
--- gcc/testsuite/gcc.c-torture/compile/pr113210.c.jj   2024-01-05 
17:18:29.792257043 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr113210.c  2024-01-05 
17:17:57.522699521 +0100
@@ -0,0 +1,13 @@
+/* PR tree-optimization/113210 */
+
+unsigned char a, c;
+unsigned short b;
+
+void
+foo (void)
+{
+  c = a + 255;
+  b = c;
+  while (++b > 256)
+;
+}

Jakub



Re: [PATCH] Fortran: bogus warnings with REPEAT intrinsic and -Wconversion-extra [PR96724]

2024-01-06 Thread FX Coudert
Hi Harald,

OK to push, thanks for picking it up!

FX


Re: [PATCH 2/3] LoongArch: Redundant sign extension elimination optimization.

2024-01-06 Thread Xi Ruoyao
On Sat, 2024-01-06 at 16:54 +0800, Lulu Cheng wrote:
> +(define_expand "addsi3"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
> + (plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r")
> +  (match_operand:SI 2 "plus_si_operand"  "r,I,La,Le,Lb")))]
> +  ""
> +{
> +  if (TARGET_64BIT)

I think for 32 bit we can just skip the expand and use *addsi3?  I. e.
add TARGET_64BIT into the expand condition two lines above.

> +    {
> +  if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2])
> +   && ADDU16I_OPERAND (INTVAL (operands[2])))
> + {
> +   rtx t1 = gen_reg_rtx (DImode);
> +   rtx t2 = gen_reg_rtx (DImode);
> +   rtx t3 = gen_reg_rtx (DImode);
> +   emit_insn (gen_extend_insn (t1, operands[1], DImode, SImode, 0));
> +   t2 = operands[2];
> +   emit_insn (gen_adddi3 (t3, t1, t2));
> +   t3 = gen_lowpart (SImode, t3);
> +   emit_move_insn (operands[0], t3);
> +   DONE;
> + }
> +  else
> + {
> +   rtx t = gen_reg_rtx (DImode);
> +   emit_insn (gen_addsi3_extended (t, operands[1], operands[2]));

AFAIK if !TARGET_64BIT a DImode should be actually a pair of hardware
registers, but addsi3_extended don't output such a pair so this seems
invalid...

> +   t = gen_lowpart (SImode, t);
> +   SUBREG_PROMOTED_VAR_P (t) = 1;
> +   SUBREG_PROMOTED_SET (t, SRP_SIGNED);
> +   emit_move_insn (operands[0], t);
> +   DONE;
> + }
> +    }
> +})

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH 1/3] LoongArch: Optimized some of the symbolic expansion instructions generated during bitwise operations.

2024-01-06 Thread Xi Ruoyao
On Sat, 2024-01-06 at 16:54 +0800, Lulu Cheng wrote:
> There are two mode iterators defined in the loongarch.md:
>   (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
>   and
>   (define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
> Replace the mode in the bit arithmetic from GPR to X.
> 
> Since the bitwise operation instruction does not distinguish between 64-bit,
> 32-bit, etc., it is necessary to perform symbolic expansion if the bitwise
> operation is less than 64 bits.
> The original definition would have generated a lot of redundant symbolic
> extension instructions. This problem is optimized with reference to the
> implementation of RISCV.
> 
> Add this patch spec2017 500.perlbench performance improvement by 1.8%
> 
> gcc/ChangeLog:
> 
>   * config/loongarch/loongarch.md (one_cmpl2): Replace GPR with X.
>   (*nor3): Likewise.
>   (nor3): Likewise.
>   (*negsi2_extended): New template.
>   (*si3_internal): Likewise.
>   (*one_cmplsi2_internal): Likewise.
>   (*norsi3_internal): Likewise.
>   (*nsi_internal): Likewise.
>   (bytepick_w__extend): Modify this template according to 
> the
>   modified bit operation to make the optimization work.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/loongarch/sign-extend-bitwise.c: New test.
> ---

LGTM.

>  gcc/config/loongarch/loongarch.md | 93 ++-
>  .../loongarch/sign-extend-bitwise.c   | 21 +
>  2 files changed, 90 insertions(+), 24 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/loongarch/sign-extend-bitwise.c
> 
> diff --git a/gcc/config/loongarch/loongarch.md 
> b/gcc/config/loongarch/loongarch.md
> index d1f5b94f5d6..436b9a93235 100644
> --- a/gcc/config/loongarch/loongarch.md
> +++ b/gcc/config/loongarch/loongarch.md
> @@ -736,7 +736,7 @@ (define_insn "sub3"
>  
>  (define_insn "sub3"
>    [(set (match_operand:GPR 0 "register_operand" "=r")
> - (minus:GPR (match_operand:GPR 1 "register_operand" "rJ")
> + (minus:GPR (match_operand:GPR 1 "register_operand" "r")
>      (match_operand:GPR 2 "register_operand" "r")))]
>    ""
>    "sub.\t%0,%z1,%2"
> @@ -1412,13 +1412,13 @@ (define_insn "neg2"
>    [(set_attr "alu_type"  "sub")
>     (set_attr "mode" "")])
>  
> -(define_insn "one_cmpl2"
> -  [(set (match_operand:GPR 0 "register_operand" "=r")
> - (not:GPR (match_operand:GPR 1 "register_operand" "r")))]
> -  ""
> -  "nor\t%0,%.,%1"
> -  [(set_attr "alu_type" "not")
> -   (set_attr "mode" "")])
> +(define_insn "*negsi2_extended"
> +  [(set (match_operand:DI 0 "register_operand" "=r")
> + (sign_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"]
> +  "TARGET_64BIT"
> +  "sub.w\t%0,%.,%1"
> +  [(set_attr "alu_type" "sub")
> +   (set_attr "mode" "SI")])
>  
>  (define_insn "neg2"
>    [(set (match_operand:ANYF 0 "register_operand" "=f")
> @@ -1438,14 +1438,39 @@ (define_insn "neg2"
>  ;;
>  
>  (define_insn "3"
> -  [(set (match_operand:GPR 0 "register_operand" "=r,r")
> - (any_bitwise:GPR (match_operand:GPR 1 "register_operand" "%r,r")
> -  (match_operand:GPR 2 "uns_arith_operand" "r,K")))]
> +  [(set (match_operand:X 0 "register_operand" "=r,r")
> + (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
> +    (match_operand:X 2 "uns_arith_operand" "r,K")))]
>    ""
>    "%i2\t%0,%1,%2"
>    [(set_attr "type" "logical")
>     (set_attr "mode" "")])
>  
> +(define_insn "*si3_internal"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> + (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
> + (match_operand:SI 2 "uns_arith_operand"    " r,K")))]
> +  "TARGET_64BIT"
> +  "%i2\t%0,%1,%2"
> +  [(set_attr "type" "logical")
> +   (set_attr "mode" "SI")])
> +
> +(define_insn "one_cmpl2"
> +  [(set (match_operand:X 0 "register_operand" "=r")
> + (not:X (match_operand:X 1 "register_operand" "r")))]
> +  ""
> +  "nor\t%0,%.,%1"
> +  [(set_attr "alu_type" "not")
> +   (set_attr "mode" "")])
> +
> +(define_insn "*one_cmplsi2_internal"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> + (not:SI (match_operand:SI 1 "register_operand" " r")))]
> +  "TARGET_64BIT"
> +  "nor\t%0,%.,%1"
> +  [(set_attr "type" "logical")
> +   (set_attr "mode" "SI")])
> +
>  (define_insn "and3_extended"
>    [(set (match_operand:GPR 0 "register_operand" "=r")
>   (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "r")
> @@ -1561,25 +1586,43 @@ (define_insn "*iorhi3"
>    [(set_attr "type" "logical")
>     (set_attr "mode" "HI")])
>  
> -(define_insn "*nor3"
> -  [(set (match_operand:GPR 0 "register_operand" "=r")
> - (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "%r"))
> -  (not:GPR (match_operand:GPR 2 "register_operand" "r"]
> +(define_insn "nor3"
> +  [(set (match_operand:X 0 "register_operand" "=r")
> + (and:X (not:X (match_operand:X 1 "register_operand" "%r"))
> +  

Re: [PATCH 3/3] LoongArch: Redundant sign extension elimination optimization 2.

2024-01-06 Thread Xi Ruoyao
On Sat, 2024-01-06 at 16:54 +0800, Lulu Cheng wrote:

/* snip */

> diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c 
> b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
> index a45dde4f73f..428535cb8e3 100644
> --- a/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
> +++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-2.c
> @@ -1,6 +1,6 @@
>  /* { dg-do compile } */
>  /* { dg-options "-mabi=lp64d -O2" } */
> -/* { dg-final { scan-assembler-times "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" 
> 1 } } */
> +/* { dg-final { scan-assembler-times "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" 
> 0 } } */

Use scan-assembler-not instead of scan-assembler-times ... 0.

Otherwise LGTM.

>  #include 
>  #define my_min(x, y) ((x) < (y) ? (x) : (y))

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH v7 1/1] c++: Initial support for P0847R7 (Deducing This) [PR102609]

2024-01-06 Thread waffl3x
I found a bugged test while finishing off the patch.
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C
line 72 has
same_type(); // { dg-error "" "not captured" }
The behavior has changed now, and this test should have failed, but
didn't as it has an empty regex expression. The actual error being
emitted here is this:
error: invalid use of incomplete type 'struct same_type'

This still happens to pass because the types don't match, but it should
be fixed to reflect the new intended behavior.

The finished patch will be coming soon(ish), I had to make some changes
so you will have to look over it quickly but hopefully it will be split
up enough to make that convenient.

Alex


On Monday, January 1st, 2024 at 10:12 AM, waffl3x  
wrote:


> 
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113191
> 
> I've posted the report here, I ended up doing a bit more investigation,
> so the contents might interest you. I'm really starting to think that
> we want to do a more thorough re-engineering of how using declarations
> are handled, instead of handling it with little hacks like the one
> added to more_specialized_fn.
> 
> As I note in the report, the addition of xobj member functions really
> makes [over.match.funcs.general.4] a lot more relevant, and I don't
> think we can get away with not following it more closely anymore. I
> know I'm wording myself here as if that passage has existed forever,
> but I recognize it might be as recent as C++23 that it was added. I
> don't mean to imply anything with how I'm wording it, it's just way
> easier to express it this way. Especially since we really could get
> away with these kinds of hacks if xobj member functions did not exist.
> Unfortunately, the type of the implicit object parameter is suddenly
> relevant for cases like this.
> 
> Anyway, as I've stated a few times, I'm going to implement my function
> that checks correspondence of the object parameter of iobj and xobj
> member functions assuming that iobj member functions introduced by
> using declarations are handled properly. I think that's the best option
> for my patch right now.
> 
> Well that investigation took the majority of my day. I'm just glad I'm
> certain of what direction to take now.
> 
> Alex
> 
> 
> On Monday, January 1st, 2024 at 8:34 AM, waffl3x waff...@protonmail.com wrote:
> 
> 
> 
> > That was faster than I expected, the problem is exactly just that we
> > aren't implementing [over.match.funcs.general.4] at all. The result of
> > compparms for the 2 functions is false which I believe to be wrong. I
> > believe we have a few choices here, but no matter what we go with it
> > will be a bit of an overhaul. I will post a PR on bugzilla in a little
> > bit as this problem feels somewhat out of the scope of my patch now.
> > 
> > I think what I will do is instead of comparing the xobj parameter to
> > the DECL_CONTEXT of the xobj function, I will compare it to the type of
> > the iobj member function's object parameter. If I do it like this, it
> > will work as expected if we rewrite functions that are introduced with
> > a using declaration.
> > 
> > This might still cause problems, I will look into how the this pointer
> > for iobj member functions is determined again. Depending on how it is
> > determined, it might be possible to change the function signature of
> > iobj member functions without altering their behavior. It would be
> > incorrect, and would change the meaning of code, if changing the
> > function signature changed the type of the this pointer.
> > 
> > Anyhow, this is a fairly big change to consider so I won't pretend I
> > know what the right call is. But the way I've decided to implement
> > correspondence checking will be consistent with how GCC currently
> > (incorrectly) treats constraints on iobj member functions introduced
> > with a using declaration, so I think doing it this way is the right
> > choice for now.
> > 
> > Some days feel really unproductive when the majority is investigation
> > and thinking. This was one of them, but at least I'm confident that my
> > conclusions are correct. Aren't edge cases fun?
> > 
> > Alex
> > 
> > On Monday, January 1st, 2024 at 8:17 AM, waffl3x waff...@protonmail.com 
> > wrote:
> > 
> > > I've been at this for a while, and I'm not sure what the proper way to
> > > fix this is.
> > > 
> > > `struct S; struct B { void f(this S&) {} void g() {} }; struct S : B { 
> > > using B::f; using B::g; void f() {} void g(this S&) {} }; int main() { S 
> > > s{}; s.f(); s.g(); }`
> > > 
> > > In short, the call to f is ambiguous, but the call to g is not. I
> > > already know where the problem is, but since I share this code in
> > > places that don't know about whether a function was introduced by a
> > > using declaration (cand_parms_match), I don't want to rely on that to
> > > solve the problem.
> > > 
> > > `/* An iobj member function's object parameter can't be an unrelated 
> > > type, if the xobj member function's object parameter is an

Re: [PATCH wwwdocs 1/1] gcc-14: document P1689R5 scanning output support

2024-01-06 Thread Arsen Arsenović
Hi Ben,

Ben Boeckel  writes:

> Ping? Is this the right place to submit this patch?

Yes, this is the correct list, though it is usually recommended to use
--subject-prefix='PATCH wwwdocs' or such, to catch the right eyes.  See:
https://gcc.gnu.org/contribute.html#webchanges

I've added it to my subject, hopefully that works.

Have a lovely day!
--
Arsen Arsenović


signature.asc
Description: PGP signature


[x86 PATCH] PR target/113231: Improved costs in Scalar-To-Vector (STV) pass.

2024-01-06 Thread Roger Sayle

This patch improves the cost/gain calculation used during the i386 backend's
SImode/DImode scalar-to-vector (STV) conversion pass.  The current code
handles loads and stores, but doesn't consider that converting other
scalar operations with a memory destination, requires an explicit load
before and an explicit store after the vector equivalent.

To ease the review, the significant change looks like:

 /* For operations on memory operands, include the overhead
of explicit load and store instructions.  */
 if (MEM_P (dst))
   igain += !optimize_insn_for_size_p ()
? (m * (ix86_cost->int_load[2]
+ ix86_cost->int_store[2])
   - (ix86_cost->sse_load[sse_cost_idx] +
  ix86_cost->sse_store[sse_cost_idx]))
: -COSTS_N_BYTES (8);

however the patch itself is complicated by a change in indentation
which leads to a number of lines with only whitespace changes.
For architectures where integer load/store costs are the same as
vector load/store costs, there should be no change without -Os/-Oz.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?


2024-01-06  Roger Sayle  

gcc/ChangeLog
PR target/113231
* config/i386/i386-features.cc (compute_convert_gain): Include
the overhead of explicit load and store (movd) instructions when
converting non-store scalar operations with memory destinations.

gcc/testsuite/ChangeLog
PR target/113231
* gcc.target/i386/pr113231.c: New test case.


Thanks again,
Roger
--

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 4ae3e75..3677aef 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -563,183 +563,195 @@ general_scalar_chain::compute_convert_gain ()
   else if (MEM_P (src) && REG_P (dst))
igain += m * ix86_cost->int_load[2] - ix86_cost->sse_load[sse_cost_idx];
   else
-   switch (GET_CODE (src))
- {
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
-   if (m == 2)
- {
-   if (INTVAL (XEXP (src, 1)) >= 32)
- igain += ix86_cost->add;
-   /* Gain for extend highpart case.  */
-   else if (GET_CODE (XEXP (src, 0)) == ASHIFT)
- igain += ix86_cost->shift_const - ix86_cost->sse_op;
-   else
- igain += ix86_cost->shift_const;
- }
-
-   igain += ix86_cost->shift_const - ix86_cost->sse_op;
+   {
+ /* For operations on memory operands, include the overhead
+of explicit load and store instructions.  */
+ if (MEM_P (dst))
+   igain += !optimize_insn_for_size_p ()
+? (m * (ix86_cost->int_load[2]
++ ix86_cost->int_store[2])
+   - (ix86_cost->sse_load[sse_cost_idx] +
+  ix86_cost->sse_store[sse_cost_idx]))
+: -COSTS_N_BYTES (8);
 
-   if (CONST_INT_P (XEXP (src, 0)))
- igain -= vector_const_cost (XEXP (src, 0));
-   break;
+ switch (GET_CODE (src))
+   {
+   case ASHIFT:
+   case ASHIFTRT:
+   case LSHIFTRT:
+ if (m == 2)
+   {
+ if (INTVAL (XEXP (src, 1)) >= 32)
+   igain += ix86_cost->add;
+ /* Gain for extend highpart case.  */
+ else if (GET_CODE (XEXP (src, 0)) == ASHIFT)
+   igain += ix86_cost->shift_const - ix86_cost->sse_op;
+ else
+   igain += ix86_cost->shift_const;
+   }
 
- case ROTATE:
- case ROTATERT:
-   igain += m * ix86_cost->shift_const;
-   if (TARGET_AVX512VL)
- igain -= ix86_cost->sse_op;
-   else if (smode == DImode)
- {
-   int bits = INTVAL (XEXP (src, 1));
-   if ((bits & 0x0f) == 0)
- igain -= ix86_cost->sse_op;
-   else if ((bits & 0x07) == 0)
- igain -= 2 * ix86_cost->sse_op;
-   else
- igain -= 3 * ix86_cost->sse_op;
- }
-   else if (INTVAL (XEXP (src, 1)) == 16)
- igain -= ix86_cost->sse_op;
-   else
- igain -= 2 * ix86_cost->sse_op;
-   break;
+ igain += ix86_cost->shift_const - ix86_cost->sse_op;
 
- case AND:
- case IOR:
- case XOR:
- case PLUS:
- case MINUS:
-   igain += m * ix86_cost->add - ix86_cost->sse_op;
-   /* Additional gain for andnot for targets without BMI.  */
-   if (GET_CODE (XEXP (src, 0)) == NOT
-   && !TARGET_BMI)
- 

Re: [PATCH] libstdc++: Fix testsuite with -Wformat

2024-01-06 Thread Jonathan Wakely
On Fri, 5 Jan 2024 at 14:12, Jonathan Wakely wrote:
>
> On 06/12/23 15:34 +0100, Gwenole Beauchesne wrote:
> >Tested on x86_64-pc-linux-gnu with --enable-languages=c,c++ and
> >additional -Wformat to CXXFLAGS.
>
> Please CC the libstd...@gcc.gnu.org list on all libstdc++ patches, as
> documented at https://gcc.gnu.org/lists.html
>
> Otherwise I won't see the patches unless I happen to glance at the
> gcc-patches archive by chance.
>
> The patch seems OK, but what exactly is it fixing? I don't see any
> warning when adding -Wformat to the test flags.

I've pushed the patch to trunk, but I'm still curious why I don't see warnings.


>
> >-- >8 --
> >
> >Fix testsuite when compiling with -Wformat. Use nonnull arguments so
> >that -Wformat does not cause extraneous output to be reported as an
> >error.
> >
> >FAIL: tr1/8_c_compatibility/cinttypes/functions.cc (test for excess errors)
> >
> >libstdc++-v3/ChangeLog:
> >
> >* testsuite/tr1/8_c_compatibility/cinttypes/functions.cc: Use
> >nonnull arguments to strtoimax() and wcstoimax() functions.
> >
> >Signed-off-by: Gwenole Beauchesne 
> >---
> > .../testsuite/tr1/8_c_compatibility/cinttypes/functions.cc| 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> >diff --git 
> >a/libstdc++-v3/testsuite/tr1/8_c_compatibility/cinttypes/functions.cc 
> >b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cinttypes/functions.cc
> >index 518ddf49875..21f5263b5cc 100644
> >--- a/libstdc++-v3/testsuite/tr1/8_c_compatibility/cinttypes/functions.cc
> >+++ b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cinttypes/functions.cc
> >@@ -29,10 +29,10 @@ void test01()
> > #if _GLIBCXX_USE_C99_INTTYPES_TR1
> >
> >   std::tr1::intmax_t i = 0, numer = 0, denom = 0, base = 0;
> >-  const char* s = 0;
> >+  const char* s = "0";
> >   char** endptr = 0;
> > #if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1
> >-  const wchar_t* ws = 0;
> >+  const wchar_t* ws = L"0";
> >   wchar_t** wendptr = 0;
> > #endif
> >
>



Re: [PATCH v2] libstdc++: Add Unicode-aware width estimation for std::format

2024-01-06 Thread Lewis Hyatt
On Sat, Jan 6, 2024 at 11:40 AM Jonathan Wakely  wrote:
>
> Here's a V2 patch which addresses the two things I mentioned: the new
> Python script now generates a complete file that can just be included by
> , and the full Unicode 15.1.0 grapheme cluster break
> rules are supported (I think ... more testing needed for some of the
> complex rules).
>
> -- >8 --

Thanks, by the way, for fixing the typo in gen_wcwidth.py.
One thing I wanted to point out, the file contrib/unicode/README
contains a list of steps to follow in order to update to a new Unicode
version. There are 10 or so steps to generate everything libcpp and
diagnostics care about. Do you think it's worth adding something for
the new libstdc++ parts there too? I guess it may not be desirable to
update them always at the same time though.

-Lewis


Re: [PATCH v2] libstdc++: Add Unicode-aware width estimation for std::format

2024-01-06 Thread Jonathan Wakely
On Sat, 6 Jan 2024 at 16:57, Lewis Hyatt  wrote:
>
> On Sat, Jan 6, 2024 at 11:40 AM Jonathan Wakely  wrote:
> >
> > Here's a V2 patch which addresses the two things I mentioned: the new
> > Python script now generates a complete file that can just be included by
> > , and the full Unicode 15.1.0 grapheme cluster break
> > rules are supported (I think ... more testing needed for some of the
> > complex rules).
> >
> > -- >8 --
>
> Thanks, by the way, for fixing the typo in gen_wcwidth.py.
> One thing I wanted to point out, the file contrib/unicode/README
> contains a list of steps to follow in order to update to a new Unicode
> version. There are 10 or so steps to generate everything libcpp and
> diagnostics care about. Do you think it's worth adding something for
> the new libstdc++ parts there too?

Ah, thanks for pointing that out. Yes, I should add to that.

> I guess it may not be desirable to
> update them always at the same time though.

We might not always want to do so e.g. if there's some new grapheme
cluster rule that requires code changes in libstdc++ but doesn't need
changes in the compiler. But we should at least _try_ to update them
in tandem, and see if it works. Ideally the std::lib will use the same
Unicode version as the compiler, otherwise you might be able to refer
to a new code point in literals using its \N{FOO BAR} name, but the
std::lib would not know the properties of that new code point. That
wouldn't be a disaster, but certainly a suboptimal user experience.



[Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-01-06 Thread Paul Richard Thomas
These PRs come about because of gfortran's single pass parsing. If the
function in the title is parsed after the associate construct, then its
type and rank are not known. The point at which this becomes a problem is
when expressions within the associate block are parsed. primary.cc
(gfc_match_varspec) could already deal with intrinsic types and so
component references were the trigger for the problem.

The two major parts of this patch are the fixup needed in gfc_match_varspec
and the resolution of  expressions with references in resolve.cc
(gfc_fixup_inferred_type_refs). The former relies on the two new functions
in symbol.cc to search for derived types with an appropriate component to
match the component reference and then set the associate name to have a
matching derived type. gfc_fixup_inferred_type_refs is called in resolution
and so the type of the selector function is known.
gfc_fixup_inferred_type_refs ensures that the component references use this
derived type and that array references occur in the right place in
expressions and match preceding array specs. Most of the work in preparing
the patch was sorting out cases where the selector was not a derived type
but, instead, a class function. If it were not for this, the patch would
have been submitted six months ago :-(

The patch is relatively safe because most of the chunks are guarded by
testing for the associate name being an inferred type, which is set in
gfc_match_varspec. For this reason, I do not think it likely that the patch
will cause regressions. However, it is more than possible that variants not
appearing in the submitted testcase will throw up new bugs.

Jerry has already given the patch a whirl and found that it applies
cleanly, regtests OK and works as advertised.

OK for trunk?

Paul

Fortran: Fix class/derived type function associate selectors [PR87477]

2024-01-06  Paul Thomas  

gcc/fortran
PR fortran/87477
PR fortran/89645
PR fortran/99065
* class.cc (gfc_change_class): New function needed for
associate names, when rank changes or a derived type is
produced by resolution
* dump-parse-tree.cc (show_code_node): Make output for SELECT
TYPE more comprehensible.
* gfortran.h : Add 'gfc_association_list' to structure
'gfc_association_list'. Add prototypes for
'gfc_find_derived_types', 'gfc_fixup_inferred_type_refs' and
'gfc_change_class'. Add macro IS_INFERRED_TYPE.
* match.cc (copy_ts_from_selector_to_associate): Add bolean arg
'select_type' with default false. If this is a select type name
and the selector is a inferred type, build the class type and
apply it to the associate name.
(build_associate_name): Pass true to 'select_type' in call to
previous.
* parse.cc (parse_associate): If the selector is a inferred type
the associate name is too. Make sure that function selector
class and rank, if known, are passed to the associate name. If
a function result exists, pass its typespec to the associate
name.
* primary.cc (gfc_match_varspec): If a scalar derived type
select type temporary has an array reference, match the array
reference, treating this in the same way as an equivalence
member. If this is a inferred type with a component reference,
call 'gfc_find_derived_types' to find a suitable derived type.
* resolve.cc (resolve_variable): Call new function below.
(gfc_fixup_inferred_type_refs): New function to ensure that the
expression references for a inferred type are consistent with
the now fixed up selector.
(resolve_assoc_var): Ensure that derived type or class function
selectors transmit the correct arrayspec to the associate name.
(resolve_select_type): If the selector is an associate name of
inferred type and has no component references, the associate
name should have its typespec.
* symbol.cc (gfc_set_default_type): If an associate name with
unknown type has a selector expression, try resolving the expr.
(find_derived_types, gfc_find_derived_types): New functions
that search for a derived type with a given name.
* trans-expr.cc (gfc_conv_variable): Some inferred type exprs
escape resolution so call 'gfc_fixup_inferred_type_refs'.
* trans-stmt.cc (trans_associate_var): Tidy up expression for
'class_target'. Correctly handle selectors that are class array
references, passed as derived types.

gcc/testsuite/
PR fortran/87477
PR fortran/89645
PR fortran/99065
* gfortran.dg/associate_64.f90 : New test
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 5c43b77dba3..7db1ecbd264 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -815,6 +815,56 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
 }
 
 
+/* Change class, using gfc_build_class_symbol. This is needed for associate
+   names, when rank changes or a derived type is produced by resolution.  */
+
+void
+gfc_change_class (gfc_typespec *ts, symbol_attribute *sym_attr,
+		  gfc_array_spec *sym_as, int rank, int corank)
+{
+  symbol_attribute attr;
+  gfc_component *c;
+  gfc_array_spec *as = NULL;
+  gfc_symbol *der = ts->u.derived;
+

[patch,testsuite,applied] PR52641: Fix more sloppy tests

2024-01-06 Thread Georg-Johann Lay

This fixes more of the sloppy tests that assume sizeof(int) = 4 etc.

Johann

--

testsuite/52641: Fix sloppy tests that did not care for sizeof(int)=2 etc.

gcc/testsuite/
PR testsuite/52641
* gcc.c-torture/compile/attr-complex-method-2.c [target=avr]: Check
for "divsc3" as double = float per default.
* gcc.c-torture/compile/pr106537-1.c: Use __INTPTR_TYPE__ instead of
hard-coded "long".
* gcc.c-torture/compile/pr106537-2.c: Same.
* gcc.c-torture/compile/pr106537-3.c: Same.
* gcc.c-torture/execute/20230630-3.c: Use __INT32_TYPE__ for bit-field
wider than 16 bits.
* gcc.c-torture/execute/20230630-4.c: Same.
* gcc.c-torture/execute/pr109938.c: Require int32plus.
* gcc.c-torture/execute/pr109986.c: Same.
* gcc.dg/fold-ior-4.c: Same.
* gcc.dg/fold-ior-5.c: Same
* gcc.dg/fold-parity-5.c: Same.
* gcc.dg/fold-popcount-5.c: Same.
* gcc.dg/builtin-bswap-13.c [sizeof(int) < 4]: Use __INT32_TYPE__
instead of int.
* gcc.dg/builtin-bswap-14.c: Use __INT32_TYPE__ instead of int where
required by code.
* gcc.dg/c23-constexpr-9.c: Require large_double.
* gcc.dg/c23-nullptr-1.c [target=avr]: xfail.
* gcc.dg/loop-unswitch-10.c: Require size32plus.
* gcc.dg/loop-unswitch-14.c: Same.
* gcc.dg/loop-unswitch-11.c: Require int32.
* gcc.dg/pr101836.c: Use __SIZEOF_INT instead of hard-coded 4.
* gcc.dg/pr101836_1.c: Same.
* gcc.dg/pr101836_2.c: Same.
* gcc.dg/pr101836_3.c: Same.diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
index 0c5311ec675..dc28e2c99c6 100644
--- a/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
@@ -8,4 +8,5 @@ void do_div (_Complex double *a, _Complex double *b)
   *a = *b / (4.0 - 5.0fi);
 }
 
-/* { dg-final { scan-tree-dump "__(?:gnu_)?divdc3" "optimized" } } */
+/* { dg-final { scan-tree-dump "__(?:gnu_)?divdc3" "optimized" { target { ! { avr-*-* } } } } } */
+/* { dg-final { scan-tree-dump "__(?:gnu_)?divsc3" "optimized" { target { avr-*-* } } } } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
index b67b6090dc3..a53fe2e35f3 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
@@ -3,7 +3,7 @@
This testcase checks that warn_compare_distinct_pointer_types is enabled by
default.  */
 
-typedef int __u32;
+typedef __INT32_TYPE__ __u32;
 
 struct xdp_md
 {
@@ -13,8 +13,8 @@ struct xdp_md
 
 int xdp_context (struct xdp_md *xdp)
 {
-  void *data = (void *)(long)xdp->data;
-  __u32 *metadata = (void *)(long)xdp->data_meta;
+  void *data = (void *)(__INTPTR_TYPE__)xdp->data;
+  __u32 *metadata = (void *)(__INTPTR_TYPE__)xdp->data_meta;
   __u32 ret;
 
   if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
index d4223c25c94..d5a2afa163c 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-Wcompare-distinct-pointer-types" } */
 
-typedef int __u32;
+typedef __INT32_TYPE__ __u32;
 
 struct xdp_md
 {
@@ -11,8 +11,8 @@ struct xdp_md
 
 int xdp_context (struct xdp_md *xdp)
 {
-  void *data = (void *)(long)xdp->data;
-  __u32 *metadata = (void *)(long)xdp->data_meta;
+  void *data = (void *)(__INTPTR_TYPE__)xdp->data;
+  __u32 *metadata = (void *)(__INTPTR_TYPE__)xdp->data_meta;
   __u32 ret;
 
   if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
index 73c9b251824..13876eab337 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O0 -Wno-compare-distinct-pointer-types" } */
 
-typedef int __u32;
+typedef __INT32_TYPE__ __u32;
 
 struct xdp_md
 {
@@ -11,8 +11,8 @@ struct xdp_md
 
 int xdp_context (struct xdp_md *xdp)
 {
-  void *data = (void *)(long)xdp->data;
-  __u32 *metadata = (void *)(long)xdp->data_meta;
+  void *data = (void *)(__INTPTR_TYPE__)xdp->data;
+  __u32 *metadata = (void *)(__INTPTR_TYPE__)xdp->data_meta;
   __u32 ret;
 
   if (metadata + 1 > data) /* There shouldn't be a warning here.  */
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-3.c b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
index fc106c97b5b..735cb9b2ede 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
@

[PATCH 0/8] OpenMP: Implement metadirective support

2024-01-06 Thread Sandra Loosemore
This patch set adds support for metadirectives and dynamic selectors
in metadirectives.  To give credit where it's due, this is primarily
Kwok's work, originally posted 2+ years ago (and WIP for some time
before that):

https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586600.html

There's also currently an improved version of those patches on the
OG13 branch, along with several followup bug fixes contributed by
others.

My contributions have been collecting, rebasing, and refactoring all
the patches, adding the missing attribute syntax and template support
to the C++ front end, fixing more bugs, adding documentation, and
making some improvements to the internal engineering aspect of the
code.

Although the original patches were posted long ago, I suspect it is
now too late in the release cycle for this feature to make it into GCC
14, although it would certainly make users happy if it could be
squeezed in.  Another concern is that I'm facing some short-term
disruptions in my ability to continue work on this and I need to at
least publish the current patches so they don't get lost in the
shuffle.  Plus, if this patch set doesn't make it into GCC 14, it will
still be useful as a better starting point for OG14 than the patch set
currently on OG13.

In terms of what is still missing:

- Dynamic context selectors are currently supported only by
  metadirective and not declare variant.
- The C and C++ front ends attempt to do early resolution of
  metadirectives at parse time, but the Fortran front end does not do
  that yet.
- IIUC the construct selector set is supposed to allow you to specify
  the name of any OpenMP construct, but it only recognizes a small subset.
- Needs more test cases.  (Everything always needs more test cases.)
- Other unimplemented features beyond what was specified in OpenMP 5.1???

BTW, I'm aware that there are some open Bugzilla issues relating to
the OG13 implementation of metadirectives, at least PRs 112779,
107067, and 106730, although I haven't investigated or worked on any
of those directly.  I do know that at least items (a) and (h) from PR
112779 have been fixed in this patch set, though.

Anyway, I think it would be reasonable to do the missing features and
bug fixes and follow-up patches rather than continuing to sit on the
entire patch set until it's complete and perfect in every way.  :-)

-Sandra


Kwok Cheung Yeung (7):
  OpenMP: metadirective tree data structures and front-end interfaces
  OpenMP: middle-end support for metadirectives
  libgomp: runtime support for target_device selector
  OpenMP: C front end support for metadirectives
  OpenMP: C++ front-end support for metadirectives
  OpenMP: common c/c++ testcases for metadirectives
  OpenMP: Fortran front-end support for metadirectives.

Sandra Loosemore (1):
  OpenMP: Update documentation of metadirective implementation status.

 gcc/Makefile.in   |   2 +-
 gcc/builtin-types.def |   2 +
 gcc/c-family/c-common.h   |   4 +-
 gcc/c-family/c-gimplify.cc|  27 +
 gcc/c-family/c-omp.cc |  60 +-
 gcc/c-family/c-pragma.cc  |   1 +
 gcc/c-family/c-pragma.h   |   1 +
 gcc/c/c-parser.cc | 493 ++-
 gcc/cgraph.h  |   3 +
 gcc/cgraphclones.cc   |   1 +
 gcc/cp/decl.cc|   2 +-
 gcc/cp/parser.cc  | 526 +++-
 gcc/cp/parser.h   |   7 +
 gcc/cp/pt.cc  | 118 
 gcc/doc/generic.texi  |  32 +
 gcc/fortran/decl.cc   |  29 +
 gcc/fortran/dump-parse-tree.cc|  21 +
 gcc/fortran/gfortran.h|  24 +-
 gcc/fortran/io.cc |   2 +-
 gcc/fortran/match.h   |   2 +
 gcc/fortran/openmp.cc | 265 +++-
 gcc/fortran/parse.cc  | 571 +++---
 gcc/fortran/parse.h   |   8 +-
 gcc/fortran/resolve.cc|   6 +
 gcc/fortran/st.cc |   4 +
 gcc/fortran/symbol.cc |  25 +-
 gcc/fortran/trans-decl.cc |   5 +-
 gcc/fortran/trans-openmp.cc   | 243 +---
 gcc/fortran/trans-stmt.h  |   1 +
 gcc/fortran/trans.cc  |   1 +
 gcc/fortran/types.def |   2 +
 gcc/gimple-low.cc |  36 ++
 gcc/gimple-pretty-print.cc|  64 ++
 gcc/gimple-streamer-in.cc |  10 +
 gcc/gimple-streamer-out.cc|   6 +
 gcc/gimple-walk.cc|  28 +
 gcc/gimple.cc |  35 ++
 gcc/gimpl

[PATCH 1/8] OpenMP: metadirective tree data structures and front-end interfaces

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch adds the OMP_METADIRECTIVE tree node and shared tree-level
support for manipulating metadirectives.  It defines/exposes
interfaces that will be used in subsequent patches that add front-end
and middle-end support, but nothing generates these nodes yet.

This patch also adds compile-time support for dynamic context
selectors (the target_device selector set and the condition selector
of the user selector set) for metadirectives only.  The "declare
variant" directive still supports only static selectors.

gcc/ChangeLog
* Makefile.in (GTFILES): Move omp-general.h earlier in the list.
* builtin-types.def (BT_FN_BOOL_INT_CONST_PTR_CONST_PTR_CONST_PTR):
New.
* doc/generic.texi (OpenMP): Document OMP_METADIRECTIVE and
context selector interfaces.
* omp-builtins.def (BUILT_IN_GOMP_EVALUATE_TARGET_DEVICE): New.
* omp-general.cc (omp_check_context_selector): Add metadirective_p
parameter, use it to conditionalize target_device support.
(make_omp_metadirective_variant): New.
(omp_context_selector_matches): Add metadirective_p and delay_p
parameters, use them to control things that can only be matched
late.  Handle OMP_TRAIT_SET_TARGET_DEVICE.
(score_wide_int): Move definition to omp-general.h.
(omp_dynamic_cond): New.
(omp_context_compute_score): Handle OMP_TRAIT_SET_TARGET_DEVICE.
(omp_resolve_late_declare_variant, omp_resolve_declare_variant):
Adjust calls to omp_context_selector_matches.
(sort_variant): New.
(omp_get_dynamic_candidates): New.
(omp_resolve_metadirective): New.
* omp-general.h (score_wide_int): Moved here from omp-general.cc.
(struct omp_metadirective_variant): New.
(OMP_METADIRECTIVE_VARIANT_SELECTOR): New.
(OMP_METADIRECTIVE_VARIANT_DIRECTIVE): New.
(OMP_METADIRECTIVE_VARIANT_BODY): New.
(make_omp_metadirective_variant): Declare.
(omp_check_context_selector): Adjust to match definition.
(omp_context_selector_matches): Likewise.
(omp_resolve_metadirective): New.
* tree-pretty-print.cc (dump_omp_context_selector): Remove
static qualifier.
(dump_generic_node): Handle OMP_METADIRECTIVE.
* tree-pretty-print.h (dump_omp_context_selector): Declare.
* tree.def (OMP_METADIRECTIVE): New.
* tree.h (OMP_METADIRECTIVE_VARIANTS): New.

gcc/c/ChangeLog
* c-parser.cc (c_finish_omp_declare_variant): Update calls to
omp_context_selector_patches to pass additional arguments.

gcc/cp/ChangeLog
* decl.cc (omp_declare_variant_finalize_one):  Update call to
omp_context_selector_patches to pass additional arguments.
* parser.cc (cp_finish_omp_declare_variant): Likewise.

gcc/fortran/ChangeLog
* trans-openmp.cc (gfc_trans_omp_declare_variant):  Update calls to
omp_context_selector_patches to pass additional arguments.
* types.def (BT_FN_BOOL_INT_CONST_PTR_CONST_PTR_CONST_PTR): New.

Co-Authored-By: Sandra Loosemore 
---
 gcc/Makefile.in |   2 +-
 gcc/builtin-types.def   |   2 +
 gcc/c/c-parser.cc   |   4 +-
 gcc/cp/decl.cc  |   2 +-
 gcc/cp/parser.cc|   2 +-
 gcc/doc/generic.texi|  32 
 gcc/fortran/trans-openmp.cc |   4 +-
 gcc/fortran/types.def   |   2 +
 gcc/omp-builtins.def|   3 +
 gcc/omp-general.cc  | 337 ++--
 gcc/omp-general.h   |  31 +++-
 gcc/tree-pretty-print.cc|  36 +++-
 gcc/tree-pretty-print.h |   2 +
 gcc/tree.def|   6 +
 gcc/tree.h  |   3 +
 15 files changed, 441 insertions(+), 27 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index deb12e17d25..06134e61a3d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2868,6 +2868,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h 
$(srcdir)/coretypes.h \
   $(srcdir)/tree-ssa-operands.h \
   $(srcdir)/tree-profile.cc $(srcdir)/tree-nested.cc \
   $(srcdir)/omp-offload.h \
+  $(srcdir)/omp-general.h \
   $(srcdir)/omp-general.cc \
   $(srcdir)/omp-low.cc \
   $(srcdir)/targhooks.cc $(out_file) $(srcdir)/passes.cc \
@@ -2894,7 +2895,6 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h 
$(srcdir)/coretypes.h \
   $(srcdir)/ipa-strub.cc \
   $(srcdir)/internal-fn.h \
   $(srcdir)/calls.cc \
-  $(srcdir)/omp-general.h \
   $(srcdir)/analyzer/analyzer-language.cc \
   @all_gtfiles@
 
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c97d6bad1de..605a38ab84d 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -878,6 +878,8 @@ DEF_FUNCTION_TYPE_4 (BT_FN_VOID_UINT_PTR_INT_PTR, BT_VOID, 
BT_INT, BT_PTR,
 BT_INT, BT_PTR)
 DEF_FUNCTION_TYPE_4 (BT_FN_BOOL_UINT_UINT_UINT_BOOL,
 BT_BOOL, BT_UINT, BT_UINT, BT_UINT, BT_BOOL)
+DEF_FUNCTION_TYPE_4 (BT_FN_BOOL_INT_CONST_PTR_CONST_PTR_C

[PATCH 2/8] OpenMP: middle-end support for metadirectives

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch adds middle-end support for OpenMP metadirectives.  Some
context selectors can be resolved during gimplification, but others need to
be deferred until the omp_device_lower pass, which requires that cgraph,
LTO streaming, inlining, etc all know about this construct as well.

gcc/ChangeLog
* cgraph.h (struct cgraph_node): Add has_metadirectives flag.
* cgraphclones.cc (cgraph_node::create_clone): Copy has_metadirectives
flag.
* gimple-low.cc (lower_omp_metadirective): New.
(lower_stmt): Call it.
* gimple-pretty-print.cc (dump_gimple_omp_metadirective): New.
(pp_gimple_stmt_1): Call it.
* gimple-streamer-in.cc (input_gimple_stmt): Handle
GIMPLE_OMP_METADIRECTIVE.
* gimple-streamer-out.cc (output_gimple_stmt): Likewise.
* gimple-walk.cc (walk_gimple_op): Likewise.
(walk_gimple_stmt): Likewise.
* gimple.cc (gimple_alloc_omp_metadirective): New.
(gimple_build_omp_metadirective): New.
(gimple_build_omp_metadirective_variant): New.
* gimple.def (GIMPLE_OMP_METADIRECTIVE): New.
(GIMPLE_OMP_METADIRECTIVE_VARIANT): New.
* gimple.h (gomp_metadirective_variant, gomp_metadirective): New.
(is_a_helper ::test): New.
(is_a_helper ::test): New.
(is_a_helper ::test): New.
(is_a_helper ::test): New.
(gimple_alloc_omp_metadirective): New.
(gimple_build_omp_metadirective): New.
(gimple_build_omp_metadirective_variant): New.
(gimple_has_substatements): Handle GIMPLE_OMP_METADIRECTIVE.
(gimple_has_ops): Likewise.
(gimple_omp_metadirective_label): New.
(gimple_omp_metadirective_set_label): New.
(gimple_omp_metadirective_variants): New.
(gimple_omp_metadirective_set_variants): New.
(gimple_return_set_retval): Handle GIMPLE_OMP_METADIRECTIVE.
* gimplify.cc (is_gimple_stmt): HANDLE OMP_METADIRECTIVE.
(expand_omp_metadirective): New.
(gimplify_omp_metadirective): New.
(gimplify_expr): Call it.
* gsstruct.def (GSS_OMP_METADIRECTIVE): New.
(GSS_OMP_METADIRECTIVE_VARIANT): New.
* lto-cgraph.cc (lto_output_node): Handle has_metadirectives flag.
(input_overwrite_node): Likewise.
* omp-expand.cc (expand_omp_target): Propagate has_metadirectives
flag.
(build_omp_regions_1): Handle GIMPLE_OMP_METADIRECTIVE.
(omp_make_gimple_edges): Likewise.
* omp-general.cc (make_omp_metadirective_variant): New.
* omp-general.h (make_omp_metadirective_variant): Declare.
* omp-low.cc (struct omp_context): Add next_clone field.
(new_omp_context): Handle next_clone field.
(clone_omp_context): New.
(delete_omp_context): Delete clones.
(scan_omp_metadirective): New.
(scan_omp_1_stmt): Handle GIMPLE_OMP_METADIRECTIVE.
(lower_omp_metadirective): New.
(lower_omp_1): Handle GIMPLE_OMP_METADIRECTIVE.  Warn about
direct calls to offloadable functions containing metadirectives.
* omp-offload.cc: Include cfganal.h and cfghooks.h.
(omp_expand_metadirective): New.
(execute_omp_device_lower): Handle metadirectives.
(pass_omp_device_lower::gate):  Handle metadirectives.
* omp-simd-clone.cc (simd_clone_create): Propagate has_metadirectives
flag.
* tree-cfg.cc (cleanup_dead_labels): Handle GIMPLE_OMP_METADIRECTIVE.
(gimple_redirect_edge_and_branch): Likewise.
* tree-inline.cc (remap_gimple_stmt): Handle GIMPLE_OMP_METADIRECTIVE.
(estimate_num_instructions): Likewise.
(expand_call_inline): Propagate has_metadirectives flag.
(tree_function_versioning): Likewise.
* tree-ssa-operands.cc: Include omp-general.h.
(operands_scanner::parse_ssa_operands): Handle
GIMPLE_OMP_METADIRECTIVE.

Co-Authored-By: Sandra Loosemore 
Co-Authored-By: Marcel Vollweiler 
---
 gcc/cgraph.h   |   3 +
 gcc/cgraphclones.cc|   1 +
 gcc/gimple-low.cc  |  36 
 gcc/gimple-pretty-print.cc |  64 +
 gcc/gimple-streamer-in.cc  |  10 ++
 gcc/gimple-streamer-out.cc |   6 ++
 gcc/gimple-walk.cc |  28 ++
 gcc/gimple.cc  |  35 +++
 gcc/gimple.def |   7 ++
 gcc/gimple.h   | 100 +++-
 gcc/gimplify.cc| 184 +
 gcc/gsstruct.def   |   2 +
 gcc/lto-cgraph.cc  |   2 +
 gcc/omp-expand.cc  |  30 ++
 gcc/omp-general.cc |  22 +
 gcc/omp-general.h  |   1 +
 gcc/omp-low.cc |  80 
 gcc/omp-offload.cc | 105 -
 gcc/omp-simd-clone.cc  |   1 +
 gcc/tree-cfg.cc|  24 +
 gcc/tree-inline.cc |  39 
 gcc/tree-ssa-operands.cc   |  17 
 22 files changed, 79

[PATCH 7/8] OpenMP: Fortran front-end support for metadirectives.

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch adds support for metadirectives to the Fortran front end.

gcc/fortran/ChangeLog
* decl.cc (gfc_match_end): Handle metadirectives.
* dump-parse-tree.cc (show_omp_node): Likewise.
(show_code_node): Likewise.
* gfortran.h (enum gfc_statement): Add ST_OMP_METADIRECTIVE.
(struct gfc_omp_clauses): Rename target_first_st_is_teams field to
target_first_st_is_teams_or_meta.
(struct gfc_omp_metadirective_variant): New.
(struct gfc_st_label): Add omp_region field.
(gfc_exec_op): Add EXEC_OMP_METADIRECTIVE.
(struct gfc_code): Add omp_metadirective_variants field.
(gfc_free_omp_metadirective_variants): Declare.
(match_omp_directive): Declare.
(is_omp_declarative_stmt): Declare.
(gfc_skip_omp_metadirective_variant): Declare.
* io.cc (format_asterisk): Add initializer for new omp_region field.
* match.h (gfc_match_omp_begin_metadirective): Declare.
(gfc_match_omp_metadirective): Declare.
* openmp.cc (gfc_match_omp_eos): Special case for matching an
OpenMP context selector.
(gfc_free_omp_metadirective_variants): New.
(gfc_match_omp_clauses): Remove context_selector parameter, use
global state variable gfc_matching_omp_context_selector instead.
(match_omp): Adjust call to gfc_match_omp_clauses, set
gfc_matching_omp_context_selector instead.
(gfc_match_omp_context_selector): Likewise.
(gfc_match_omp_context_selector_specification): Generalize to take
a set selector list pointer as parameter, instead of a
declare variant pointer.
(gfc_match_omp_declare_variant): Adjust call to match above change.
(match_omp_metadirective): New.
(gfc_match_omp_begin_metadirective): New.
(gfc_match_omp_metadirective): New.
(resolve_omp_metadirective): New.
(resolve_omp_target): Handle metadirectives.
(gfc_resolve_omp_directive): Handle metadirectives.
* parse.cc (gfc_matching_omp_context_selector): New.
(gfc_in_metadirective_body): New.
(gfc_omp_region_count): New.
(decode_omp_directive): Handle "begin metadirective", "end
metadirective", and "metadirective".
(match_omp_directive): New.
(case_omp_structured_block): New define.
(case_omp_do): New define.
(gfc_ascii_statement): Handle ST_OMP_BEGIN_METADIRECTIVE,
ST_OMP_END_METADIRECTIVE, and ST_OMP_METADIRECTIVE.
(accept_statement): Handle ST_OMP_BEGIN_METADIRECTIVE and
ST_OMP_METADIRECTIVE.
(gfc_omp_end_stmt): New.
(parse_omp_do): Use gfc_omp_end_stmt.  Special-case
"omp end metadirective" to end the current construct.
(parse_omp_structured_block): Likewise.  Adjust setting of
target_first_st_is_teams_or_meta flag.
(parse_omp_metadirective_body): New.
(parse_executable): Handle metadirectives.  Use
case_omp_structured_block and case_omp_do here.
(gfc_parse_file): Initialize gfc_omp_region_count,
gfc_in_metadirective_body, and gfc_matching_omp_context_selector.
(is_omp_declarative_stmt): New.
* parse.h (gfc_omp_end_stmt): Declare.
(gfc_matching_omp_context_selector): Declare.
(gfc_in_metadirective_body): Declare.
(gfc_omp_region_count): Declare.
* resolve.cc (gfc_resolve_code): Handle EXEC_OMP_METADIRECTIVE.
* st.cc (gfc_free_statement): Handle EXEC_OMP_METADIRECTIVE.
* symbol.cc (compare_st_labels): Compare omp_region, not just the
value.
(gfc_get_st_label): Likewise.  Initialize the omp_region field when
creating a new label.
* trans-decl.cc (gfc_get_label_decl): Encode the omp_region in the
label name.
* trans-openmp.cc (gfc_trans_omp_directive): Handle
EXEC_OMP_METADIRECTIVE.
(gfc_trans_omp_set_selector): New, split from...
(gfc_trans_omp_declare_variant): ...here.
(gfc_trans_omp_metadirective): New.
(gfc_skip_omp_metadirective_variant): New.
* trans-stmt.h (gfc_trans_omp_metadirective): Declare.
* trans.cc (trans_code): Handle EXEC_OMP_METADIRECTIVE.

gcc/testsuite/ChangeLog

* gfortran.dg/gomp/metadirective-1.f90: New.
* gfortran.dg/gomp/metadirective-10.f90: New.
* gfortran.dg/gomp/metadirective-11.f90: New.
* gfortran.dg/gomp/metadirective-2.f90: New.
* gfortran.dg/gomp/metadirective-3.f90: New.
* gfortran.dg/gomp/metadirective-4.f90: New.
* gfortran.dg/gomp/metadirective-5.f90: New.
* gfortran.dg/gomp/metadirective-6.f90: New.
* gfortran.dg/gomp/metadirective-7.f90: New.
* gfortran.dg/gomp/metadirective-8.f90: New.
* gfortran.dg/gomp/metadirective-9.f90: New.
* gfortran.dg/gomp/metadirective-construct.f90: New.
* gfortran.dg/gomp/metad

[PATCH 3/8] libgomp: runtime support for target_device selector

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch implements the libgomp runtime support for the dynamic
target_device selector via the GOMP_evaluate_target_device function.

include/ChangeLog
* cuda/cuda.h (CUdevice_attribute): Add definitions for
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR and
CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR.

libgomp/ChangeLog
* Makefile.am (libgomp_la_SOURCES): Add selector.c.
* Makefile.am: Regenerate.
* config/gcn/selector.c: New.
* config/linux/selector.c: New.
* config/linux/x86/selector.c: New.
* config/nvptx/selector.c: New.
* libgomp-plugin.h (GOMP_OFFLOAD_evaluate_device): New.
* libgomp.h (struct gomp_device_descr): Add evaluate_device_func field.
* libgomp.map (GOMP_5.1): Add GOMP_evaluate_target_device.
* libgomp_g.h (GOMP_evaluate_current_device): New.
(GOMP_evaluate_target_device): New.
* oacc-host.c (host_evaluate_device): New.
(host_openacc_exec): Initialize evaluate_device_func field to
host_evaluate_device.
* plugin/plugin-gcn.c (GOMP_OFFLOAD_evaluate_device): New.
* plugin/plugin-nvptx.c (struct ptx_device): Add compute_major and
compute_minor fields.
(nvptx_open_device): Read compute capability information from device.
(CHECK_ISA): New macro.
(GOMP_OFFLOAD_evaluate_device): New.
* selector.c: New.
* target.c (GOMP_evaluate_target_device): New.
(gomp_load_plugin_for_device): Load evaluate_device plugin function.
---
 include/cuda/cuda.h |   2 +
 libgomp/Makefile.am |   2 +-
 libgomp/Makefile.in |   5 +-
 libgomp/config/gcn/selector.c   |  57 +
 libgomp/config/linux/selector.c |  43 
 libgomp/config/linux/x86/selector.c | 325 
 libgomp/config/nvptx/selector.c |  65 ++
 libgomp/libgomp-plugin.h|   2 +
 libgomp/libgomp.h   |   1 +
 libgomp/libgomp.map |   1 +
 libgomp/libgomp_g.h |   8 +
 libgomp/oacc-host.c |  11 +
 libgomp/plugin/plugin-gcn.c |  14 ++
 libgomp/plugin/plugin-nvptx.c   |  45 
 libgomp/selector.c  |  36 +++
 libgomp/target.c|  38 
 16 files changed, 652 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/config/gcn/selector.c
 create mode 100644 libgomp/config/linux/selector.c
 create mode 100644 libgomp/config/linux/x86/selector.c
 create mode 100644 libgomp/config/nvptx/selector.c
 create mode 100644 libgomp/selector.c

diff --git a/include/cuda/cuda.h b/include/cuda/cuda.h
index 114aba4e074..0d57bdd68e9 100644
--- a/include/cuda/cuda.h
+++ b/include/cuda/cuda.h
@@ -82,6 +82,8 @@ typedef enum {
   CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR = 39,
   CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT = 40,
   CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING = 41,
+  CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR = 75,
+  CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR = 76,
   CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR = 82
 } CUdevice_attribute;
 
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index 1871590596d..87658da2d5d 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -72,7 +72,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c 
env.c error.c \
target.c splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c \
oacc-init.c oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c \
priority_queue.c affinity-fmt.c teams.c allocator.c oacc-profiling.c \
-   oacc-target.c target-indirect.c
+   oacc-target.c target-indirect.c selector.c
 
 include $(top_srcdir)/plugin/Makefrag.am
 
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index 56a6beab867..81de2ddb943 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -219,7 +219,7 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo 
critical.lo \
oacc-parallel.lo oacc-host.lo oacc-init.lo oacc-mem.lo \
oacc-async.lo oacc-plugin.lo oacc-cuda.lo priority_queue.lo \
affinity-fmt.lo teams.lo allocator.lo oacc-profiling.lo \
-   oacc-target.lo target-indirect.lo $(am__objects_1)
+   oacc-target.lo target-indirect.lo selector.lo $(am__objects_1)
 libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -552,7 +552,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c 
env.c \
oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \
oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
affinity-fmt.c teams.c allocator.c oacc-profiling.c \
-   oacc-target.c target-indirect.c $(am__append_3)
+   oacc-target.c target-indirect.c selector.c $(am__append_3)
 
 # Nvidia PTX OpenACC plugin.
 @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info 
$(libtool_VERSION)
@@ -777,

[PATCH 5/8] OpenMP: C++ front-end support for metadirectives

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch adds C++ support for metadirectives.  It uses the
c-family support committed with the corresponding C front end patch
to do early parse-time metadirective resolution when possible.

Additional C/C++ common testcases are provided in a subsequent
patch in the series.

gcc/cp/ChangeLog
* parser.cc (cp_parser_skip_to_end_of_block_or_statement): Add
metadirective_p parameter, use it to control brace/parentheses
behavior for metadirectives.
(mangle_metadirective_region_label): New.
(cp_parser_label_for_labeled_statement): Use it.
(cp_parser_jump_statement): Likewise.
(cp_parser_omp_context_selector): Add metadirective_p
parameter, use it to control error behavior for non-constant exprs
properties.
(cp_parser_omp_context_selector_specification): Add metadirective_p
parameter, use it for cp_parser_omp_context_selector call.
(cp_finish_omp_declare_variant): Adjust call to
cp_parser_omp_context_selector_specification.
(analyze_metadirective_body): New.
(cp_parser_omp_metadirective): New.
(cp_parser_pragma): Handle PRAGMA_OMP_METADIRECTIVE.
* parser.h (struct cp_parser): Add fields for metadirective parsing
state.
* pt.cc (tsubst_omp_context_selector): New.
(tsubst_stmt): Handle OMP_METADIRECTIVE.

gcc/testsuite/ChangeLog
* g++.dg/gomp/attrs-metadirective-1.C: New.
* g++.dg/gomp/attrs-metadirective-2.C: New.
* g++.dg/gomp/attrs-metadirective-3.C: New.
* g++.dg/gomp/attrs-metadirective-4.C: New.
* g++.dg/gomp/attrs-metadirective-5.C: New.
* g++.dg/gomp/attrs-metadirective-6.C: New.
* g++.dg/gomp/attrs-metadirective-7.C: New.
* g++.dg/gomp/attrs-metadirective-8.C: New.

libgomp/ChangeLog
* testsuite/libgomp.c++/metadirective-template-1.C: New.
* testsuite/libgomp.c++/metadirective-template-2.C: New.
* testsuite/libgomp.c++/metadirective-template-3.C: New.

Co-Authored-By: Sandra Loosemore 
---
 gcc/cp/parser.cc  | 524 +-
 gcc/cp/parser.h   |   7 +
 gcc/cp/pt.cc  | 118 
 .../g++.dg/gomp/attrs-metadirective-1.C   |  40 ++
 .../g++.dg/gomp/attrs-metadirective-2.C   |  74 +++
 .../g++.dg/gomp/attrs-metadirective-3.C   |  31 ++
 .../g++.dg/gomp/attrs-metadirective-4.C   |  41 ++
 .../g++.dg/gomp/attrs-metadirective-5.C   |  24 +
 .../g++.dg/gomp/attrs-metadirective-6.C   |  31 ++
 .../g++.dg/gomp/attrs-metadirective-7.C   |  31 ++
 .../g++.dg/gomp/attrs-metadirective-8.C   |  16 +
 .../libgomp.c++/metadirective-template-1.C|  37 ++
 .../libgomp.c++/metadirective-template-2.C|  41 ++
 .../libgomp.c++/metadirective-template-3.C|  41 ++
 14 files changed, 1043 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-1.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-2.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-3.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-4.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-5.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-6.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-7.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/attrs-metadirective-8.C
 create mode 100644 libgomp/testsuite/libgomp.c++/metadirective-template-1.C
 create mode 100644 libgomp/testsuite/libgomp.c++/metadirective-template-2.C
 create mode 100644 libgomp/testsuite/libgomp.c++/metadirective-template-3.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index b864a9b5275..4ec4ed8a01c 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -2998,7 +2998,7 @@ static void cp_parser_skip_to_end_of_statement
 static void cp_parser_consume_semicolon_at_end_of_statement
   (cp_parser *);
 static void cp_parser_skip_to_end_of_block_or_statement
-  (cp_parser *);
+  (cp_parser *, bool = false);
 static bool cp_parser_skip_to_closing_brace
   (cp_parser *);
 static bool cp_parser_skip_entire_template_parameter_list
@@ -4174,9 +4174,11 @@ cp_parser_consume_semicolon_at_end_of_statement 
(cp_parser *parser)
have consumed a non-nested `;'.  */
 
 static void
-cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
+cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser,
+bool metadirective_p)
 {
   int nesting_depth = 0;
+  int bracket_depth = 0;
 
   /* Unwind generic function template scope if necessary.  */
   if (parser->fully_implicit_function_template_p)
@@ -4198,7 +4200,7 @@ cp_parser_skip_to_end_of_block_or_statement (cp_parser* 
parser)
 
case CPP_SEMICOLON:
  /* Stop if this is an unnested ';'. */
- if (!nesting_d

[PATCH 4/8] OpenMP: C front end support for metadirectives

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

This patch adds support to the C front end to parse OpenMP metadirective
constructs.  It includes support for early parse-time resolution
of metadirectives (when possible) that will also be used by the C++ front
end.

Additional common C/C++ testcases are in a later patch in the series.

gcc/c-family/ChangeLog
* c-common.h (enum c_omp_directive_kind): Add C_OMP_DIR_META.
(c_omp_expand_metadirective): Declare.
* c-gimplify.cc: Include omp-general.h.
(genericize_omp_metadirective_stmt): New.
(c_genericize_control_stmt): Call it.
* c-omp.cc (c_omp_directives): Add "metadirective" and fix
commented-out stubs for the begin/end form.
(c_omp_expand_metadirective_r): New.
(c_omp_expand_metadirective): New.
* c-pragma.cc (omp_pragmas): Add "metadirective".
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_METADIRECTIVE.

gcc/c/ChangeLog
* c-parser.cc (struct c_parser): Add new fields for metadirectives.
(c_parser_skip_to_end_of_block_or_statement):  Add metadirective_p
parameter; use it to control brace and parentheses behavior.
(mangle_metadirective_region_label): New.
(c_parser_label, c_parser_statement_after_labels): Use it.
(c_parser_pragma): Handle metadirective.
(c_parser_omp_context_selector): Add metadirective_p flag, use it
to gate support for non-constant user condition.
(c_parser_omp_context_selector_specification): Add metadirective_p
flag.
(c_parser_finish_omp_declare_variant): Adjust call.
(analyze_metadirective_body): New.
(c_parser_omp_metadirective): New.

gcc/testsuite/ChangeLog
* gcc.dg/gomp/metadirective-1.c: New.

Co-Authored-By: Sandra Loosemore 
---
 gcc/c-family/c-common.h |   4 +-
 gcc/c-family/c-gimplify.cc  |  27 ++
 gcc/c-family/c-omp.cc   |  60 ++-
 gcc/c-family/c-pragma.cc|   1 +
 gcc/c-family/c-pragma.h |   1 +
 gcc/c/c-parser.cc   | 489 +++-
 gcc/testsuite/gcc.dg/gomp/metadirective-1.c |  15 +
 7 files changed, 577 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/metadirective-1.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 3c2d75a0027..bad12c8119f 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1391,7 +1391,8 @@ enum c_omp_directive_kind {
   C_OMP_DIR_CONSTRUCT,
   C_OMP_DIR_DECLARATIVE,
   C_OMP_DIR_UTILITY,
-  C_OMP_DIR_INFORMATIONAL
+  C_OMP_DIR_INFORMATIONAL,
+  C_OMP_DIR_META
 };
 
 struct c_omp_directive {
@@ -1405,6 +1406,7 @@ extern const struct c_omp_directive c_omp_directives[];
 extern const struct c_omp_directive *c_omp_categorize_directive (const char *,
 const char *,
 const char *);
+extern tree c_omp_expand_metadirective (vec 
&);
 
 /* Return next tree in the chain for chain_next walking of tree nodes.  */
 inline tree
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index 494da49791d..c53aca60bcf 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "context.h"
 #include "tree-pass.h"
 #include "internal-fn.h"
+#include "omp-general.h"
 
 /*  The gimplification pass converts the language-dependent trees
 (ld-trees) emitted by the parser into language-independent trees
@@ -485,6 +486,27 @@ genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, 
void *data,
   finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
 }
 
+/* Genericize a OMP_METADIRECTIVE node *STMT_P.  */
+
+static void
+genericize_omp_metadirective_stmt (tree *stmt_p, int *walk_subtrees,
+  void *data, walk_tree_fn func,
+  walk_tree_lh lh)
+{
+  tree stmt = *stmt_p;
+
+  for (tree variant = OMP_METADIRECTIVE_VARIANTS (stmt);
+   variant != NULL_TREE;
+   variant = TREE_CHAIN (variant))
+{
+  walk_tree_1 (&OMP_METADIRECTIVE_VARIANT_DIRECTIVE (variant),
+  func, data, NULL, lh);
+  walk_tree_1 (&OMP_METADIRECTIVE_VARIANT_BODY (variant),
+  func, data, NULL, lh);
+}
+
+  *walk_subtrees = 0;
+}
 
 /* Lower structured control flow tree nodes, such as loops.  The
STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
@@ -533,6 +555,11 @@ c_genericize_control_stmt (tree *stmt_p, int 
*walk_subtrees, void *data,
   genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
   break;
 
+case OMP_METADIRECTIVE:
+  genericize_omp_metadirective_stmt (stmt_p, walk_subtrees, data, func,
+lh);
+  break;
+
 case STATEMENT_LIST:

[PATCH 8/8] OpenMP: Update documentation of metadirective implementation status.

2024-01-06 Thread Sandra Loosemore
libgomp/ChangeLog
* libgomp.texi (OpenMP 5.0): Mark metadirective as implemented.
(OpenMP 5.1): Mark target_device as partially supported.
(OpenMP 5.2): Mark otherwise clause as supported, note that
default is also still accepted.
---
 libgomp/libgomp.texi | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index c727850397d..8ef22086653 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -192,7 +192,7 @@ The OpenMP 4.5 specification is fully supported.
 @item Array shaping @tab N @tab
 @item Array sections with non-unit strides in C and C++ @tab N @tab
 @item Iterators @tab Y @tab
-@item @code{metadirective} directive @tab N @tab
+@item @code{metadirective} directive @tab Y @tab
 @item @code{declare variant} directive
   @tab P @tab @emph{simd} traits not handled correctly
 @item @var{target-offload-var} ICV and @code{OMP_TARGET_OFFLOAD}
@@ -289,8 +289,11 @@ The OpenMP 4.5 specification is fully supported.
 @headitem Description @tab Status @tab Comments
 @item OpenMP directive as C++ attribute specifiers @tab Y @tab
 @item @code{omp_all_memory} reserved locator @tab Y @tab
-@item @emph{target_device trait} in OpenMP Context @tab N @tab
-@item @code{target_device} selector set in context selectors @tab N @tab
+@item @emph{target_device trait} in OpenMP Context @tab Y
+@item @code{target_device} selector set in context selectors @tab P
+  @tab Supported only for @code{metadirective}.  
+  The @code{declare variant} construct does not yet support dynamic
+  selectors.
 @item C/C++'s @code{declare variant} directive: elision support of
   preprocessed code @tab N @tab
 @item @code{declare variant}: new clauses @code{adjust_args} and
@@ -413,8 +416,10 @@ to address of matching mapped list item per 5.1, Sect. 
2.21.7.2 @tab N @tab
 @item Deprecation of traits array following the allocator_handle expression in
   @code{uses_allocators} @tab N @tab
 @item New @code{otherwise} clause as alias for @code{default} on metadirectives
-  @tab N @tab
-@item Deprecation of @code{default} clause on metadirectives @tab N @tab
+  @tab Y @tab
+@item Deprecation of @code{default} clause on metadirectives @tab N
+  @tab Both @code{otherwise} and @code{default} are accepted
+  without diagnostics.
 @item Deprecation of delimited form of @code{declare target} @tab N @tab
 @item Reproducible semantics changed for @code{order(concurrent)} @tab N @tab
 @item @code{allocate} and @code{firstprivate} clauses on @code{scope}
-- 
2.31.1



[PATCH 6/8] OpenMP: common c/c++ testcases for metadirectives

2024-01-06 Thread Sandra Loosemore
From: Kwok Cheung Yeung 

gcc/testsuite/ChangeLog
* c-c++-common/gomp/metadirective-1.c: New.
* c-c++-common/gomp/metadirective-2.c: New.
* c-c++-common/gomp/metadirective-3.c: New.
* c-c++-common/gomp/metadirective-4.c: New.
* c-c++-common/gomp/metadirective-5.c: New.
* c-c++-common/gomp/metadirective-6.c: New.
* c-c++-common/gomp/metadirective-7.c: New.
* c-c++-common/gomp/metadirective-8.c: New.
* c-c++-common/gomp/metadirective-construct.c: New.
* c-c++-common/gomp/metadirective-device.c: New.
* c-c++-common/gomp/metadirective-no-score.c: New.
* c-c++-common/gomp/metadirective-target-device.c: New.

libgomp/ChangeLog
* testsuite/libgomp.c-c++-common/metadirective-1.c: New.
* testsuite/libgomp.c-c++-common/metadirective-2.c: New.
* testsuite/libgomp.c-c++-common/metadirective-3.c: New.
* testsuite/libgomp.c-c++-common/metadirective-4.c: New.
* testsuite/libgomp.c-c++-common/metadirective-5.c: New.

Co-Authored-By: Sandra Loosemore 
---
 .../c-c++-common/gomp/metadirective-1.c   |  52 +
 .../c-c++-common/gomp/metadirective-2.c   |  74 
 .../c-c++-common/gomp/metadirective-3.c   |  31 +++
 .../c-c++-common/gomp/metadirective-4.c   |  40 
 .../c-c++-common/gomp/metadirective-5.c   |  24 +++
 .../c-c++-common/gomp/metadirective-6.c   |  31 +++
 .../c-c++-common/gomp/metadirective-7.c   |  31 +++
 .../c-c++-common/gomp/metadirective-8.c   |  16 ++
 .../gomp/metadirective-construct.c| 177 ++
 .../c-c++-common/gomp/metadirective-device.c  | 147 +++
 .../gomp/metadirective-no-score.c |  95 ++
 .../gomp/metadirective-target-device.c| 147 +++
 .../libgomp.c-c++-common/metadirective-1.c|  35 
 .../libgomp.c-c++-common/metadirective-2.c|  41 
 .../libgomp.c-c++-common/metadirective-3.c|  34 
 .../libgomp.c-c++-common/metadirective-4.c|  52 +
 .../libgomp.c-c++-common/metadirective-5.c|  46 +
 17 files changed, 1073 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-1.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-2.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-3.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-4.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-5.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-6.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-7.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-8.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-construct.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-device.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/metadirective-no-score.c
 create mode 100644 
gcc/testsuite/c-c++-common/gomp/metadirective-target-device.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-2.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-3.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-4.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/metadirective-5.c

diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-1.c 
b/gcc/testsuite/c-c++-common/gomp/metadirective-1.c
new file mode 100644
index 000..37b56237531
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/metadirective-1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+
+#define N 100
+
+void f (int a[], int b[], int c[])
+{
+  int i;
+
+  #pragma omp metadirective \
+  default (teams loop) \
+  default (parallel loop) /* { dg-error "too many 'otherwise' or 'default' 
clauses in 'metadirective'" } */
+for (i = 0; i < N; i++) c[i] = a[i] * b[i];
+
+  #pragma omp metadirective \
+  otherwise (teams loop) \
+  default (parallel loop) /* { dg-error "too many 'otherwise' or 'default' 
clauses in 'metadirective'" } */
+for (i = 0; i < N; i++) c[i] = a[i] * b[i];
+
+  #pragma omp metadirective \
+  otherwise (teams loop) \
+  otherwise (parallel loop) /* { dg-error "too many 'otherwise' or 
'default' clauses in 'metadirective'" } */
+for (i = 0; i < N; i++) c[i] = a[i] * b[i];
+
+  #pragma omp metadirective \
+  default (bad_directive) /* { dg-error "unknown directive name before 
'\\)' token" } */
+for (i = 0; i < N; i++) c[i] = a[i] * b[i];
+
+  #pragma omp metadirective \
+  default (teams loop) \
+  where (device={arch("nvptx")}: parallel loop) /* { dg-error "'where' is 
not valid for 'metadirective'" } */
+for (i = 0; i < N; i++) c[i] = a[i] * b[i];
+
+  #pragma omp metadirective \
+  default (teams loop) \
+  when (device={arch("nvptx")} parallel loop) /* { dg-error "expected ':' 
befo

Re: [PATCH 1/8] OpenMP: metadirective tree data structures and front-end interfaces

2024-01-06 Thread Tobias Burnus

Hi Sandra,

given that it is "just" a revised patch of previously posted patch and 
(code wise not file wise) very localized to OpenMP code - and even there 
touching only 'declare ...' code in a simple way:


I would be still fine to have it in GCC 14, but I want to give Jakub a 
chance to shout...



Glancing at the code, it looks okayish, but I have two quick comments.
(I have now an errant to do - and will continue later with the review.)

Sandra Loosemore wrote:

+static tree
+omp_dynamic_cond (tree ctx)
+{
+  tree expr = NULL_TREE;
+
+  tree user = omp_get_context_selector (ctx, OMP_TRAIT_SET_USER,
+   OMP_TRAIT_USER_CONDITION);
+  if (user)
+{
+  tree expr_list = OMP_TS_PROPERTIES (user);
+
+  gcc_assert (OMP_TP_NAME (expr_list) == NULL_TREE);
+
+  /* The user condition is not dynamic if it is constant.  */
+  if (!tree_fits_shwi_p (TREE_VALUE (expr_list)))
+   expr = TREE_VALUE (expr_list);
+}
+
+  tree target_device
+= omp_get_context_selector_list (ctx, OMP_TRAIT_SET_TARGET_DEVICE);
+  if (target_device)
+{
+  tree device_num = null_pointer_node;
+  tree kind = null_pointer_node;
+  tree arch = null_pointer_node;
+  tree isa = null_pointer_node;
+
+  tree device_num_sel
+   = omp_get_context_selector (ctx, OMP_TRAIT_SET_TARGET_DEVICE,
+   OMP_TRAIT_DEVICE_NUM);
+  if (device_num_sel)
+   device_num = OMP_TP_VALUE (OMP_TS_PROPERTIES (device_num_sel));
+  else
+   device_num = build_int_cst (integer_type_node, -1);


I think this won't correctly distinguish 'omp_initial_device' (= -1) 
from unset. OpenMP has 'omp_invalid_device', 'omp_initial_device' and 
then the values 0 to omp_get_num_devices()  [where the latter denotes 
the host, 0 ... < omp_get_num_device() are non-host devices].




  /* Compute *SCORE for context selector CTX.  Return true if the score
 would be different depending on whether it is a declare simd clone or
@@ -2194,12 +2308,21 @@ omp_context_compute_score (tree ctx, score_wide_int 
*score, bool declare_simd)
  {
tree selectors
  = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
-  bool has_kind = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE,
-   OMP_TRAIT_DEVICE_KIND);
-  bool has_arch = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE,
-   OMP_TRAIT_DEVICE_ARCH);
-  bool has_isa = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE,
-  OMP_TRAIT_DEVICE_ISA);
+  bool has_kind
+= (omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE,
+OMP_TRAIT_DEVICE_KIND)
+   || omp_get_context_selector (ctx, OMP_TRAIT_SET_TARGET_DEVICE,
+   OMP_TRAIT_DEVICE_KIND));


I do not completely understand how that's used, but I have the feeling 
that having a match that contains both 'device' and 'target_device' is 
not correctly handled here.



  int *scores
= (int *) alloca ((2 * nconstructs + 2) * sizeof (int));


That's not new but I have the feeling it should be '+ 3' and not '+ 2'
for device or target_device + and having both device and target device,
it might even need to be + 6.

I also wonder whether 'alloca' will really work - or only when inlined 
at all call sites. (Currenlty, it is called 6 times - and a 7th time 
with this patch.)


That's how far I came and before having to leave for now. (And having no 
time to think about what I wrote about 'score'.)


Tobias


Re: [PATCH v2] libstdc++: Add Unicode-aware width estimation for std::format

2024-01-06 Thread Jonathan Wakely
On Sat, 6 Jan 2024 at 17:03, Jonathan Wakely  wrote:
>
> On Sat, 6 Jan 2024 at 16:57, Lewis Hyatt  wrote:
> >
> > On Sat, Jan 6, 2024 at 11:40 AM Jonathan Wakely  wrote:
> > >
> > > Here's a V2 patch which addresses the two things I mentioned: the new
> > > Python script now generates a complete file that can just be included by
> > > , and the full Unicode 15.1.0 grapheme cluster break
> > > rules are supported (I think ... more testing needed for some of the
> > > complex rules).
> > >
> > > -- >8 --
> >
> > Thanks, by the way, for fixing the typo in gen_wcwidth.py.
> > One thing I wanted to point out, the file contrib/unicode/README
> > contains a list of steps to follow in order to update to a new Unicode
> > version. There are 10 or so steps to generate everything libcpp and
> > diagnostics care about. Do you think it's worth adding something for
> > the new libstdc++ parts there too?
>
> Ah, thanks for pointing that out. Yes, I should add to that.

Here's what I suggest adding to the README:

--- a/contrib/unicode/README
+++ b/contrib/unicode/README
@@ -16,7 +16,12 @@
ftp://ftp.unicode.org/Public/UNIDATA/DerivedNormalizationProps.txt
ftp://ftp.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt
ftp://ftp.unicode.org/Public/UNIDATA/NameAliases.txt

-These files have been added to source control in this directory;
+Two additional files are needed for lookup tables in libstdc++:
+
+ftp://ftp.unicode.org/Public/UNIDATA/auxiliary/GraphemeBreakProperty.txt
+ftp://ftp.unicode.org/Public/UNIDATA/emoji/emoji-data.txt
+
+All these files have been added to source control in this directory;
please see unicode-license.txt for the relevant copyright information.

In order to keep in sync with glibc's wcwidth as much as possible, it is
@@ -24,7 +29,7 @@ desirable for the logic that processes the Unicode
data to be the same as
glibc's.  To that end, we also put in this directory, in the from_glibc/
directory, the glibc python code that implements their logic.  This code was
copied verbatim from glibc, and it can be updated at any time from the glibc
-source code repository.  The files copied from that respository are:
+source code repository.  The files copied from that repository are:

localedata/unicode-gen/unicode_utils.py
localedata/unicode-gen/utf8_gen.py
@@ -71,3 +76,6 @@ The procedure to update GCC's Unicode support is the
following:
9:  Generate uname2c.h as follows:
  ../../libcpp/makeuname2c UnicodeData.txt NameAliases.txt \
   > ../../libcpp/uname2c.h
+
+See gen_libstdcxx_unicode_data.py for instructions on updating the lookup
+tables in libstdc++.


That refers to gen_libstdcxx_unicode_data.py which I think is a better
name than gen_std_format_width.py so I've renamed the new script in my
local tree.



[Patch] gcn.h: Add builtin_define ("__gfx1030")

2024-01-06 Thread Tobias Burnus

Hi Andrew,

I just spotted that this define was missing.

OK for mainline?

Tobiasgcn.h: Add builtin_define ("__gfx1030")

gcc/ChangeLog:

	* config/gcn/gcn.h (TARGET_CPU_CPP_BUILTINS): Add
	builtin_define ("__gfx1030").

diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index c350cbb0545..54868b72f90 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -43,6 +43,8 @@
 	builtin_define ("__gfx908__"); \
   else if (TARGET_GFX90a)  \
 	builtin_define ("__gfx90a__"); \
+  else if (TARGET_GFX1030) \
+	builtin_define ("__gfx1030");  \
   } while (0)
 
 #define ASSEMBLER_DIALECT (TARGET_RDNA2 ? 1 : 0)


Re: [PATCH 6/4] libbacktrace: Add loaded dlls after initialize

2024-01-06 Thread Björn Schäpers

Am 04.01.2024 um 23:33 schrieb Björn Schäpers:

Am 03.01.2024 um 00:12 schrieb Björn Schäpers:

Am 30.11.2023 um 20:53 schrieb Ian Lance Taylor:

On Fri, Jan 20, 2023 at 2:55 AM Björn Schäpers  wrote:


From: Björn Schäpers 

Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except
that libraries loaded after the backtrace_initialize are not handled.
But as far as I can see that's the same for elf.


Thanks, but I don't want a patch that loops using goto statements.
Please rewrite to avoid that.  It may be simpler to call a function.

Also starting with a module count of 1000 seems like a lot.  Do
typical Windows programs load that many modules?

Ian




Rewritten using a function.

If that is commited, could you attribute that commit to me (--author="Björn 
Schäpers ")?


Thanks and kind regards,
Björn.


I noticed that under 64 bit libraries loaded with LoadLibrary were missing. 
EnumProcessModules stated the correct number of modules, but did not fill the 
the HMODULEs, but set them to 0. While trying to investigate I noticed if I do 
the very same thing from main (in C++) I even got fewer module HMODULEs.


So I went a different way. This detects all libraries correctly, in 32 and 64 
bit. The question is, if it should be a patch on top of the previous, or should 
they be merged, or even only this solution and drop the EnumProcessModules variant?


Kind regards,
Björn.


This patch adds libraries which are loaded after backtrace_initialize, like 
plugins or similar.


I don't know what style is preferred for the Win32 typedefs, should the code use 
PVOID or void*? And I'm not sure I wrapped every long line correctly.


Kind regards,
Björn.From 02e76e727b95dc21dc07d1fe8424b68e37e91a83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= 
Date: Sat, 6 Jan 2024 22:53:54 +0100
Subject: [PATCH 3/3] libbacktrace: Add loaded dlls after initialize

libbacktrace/Changelog:

* pecoff.c [HAVE_WINDOWS_H]:
  (dll_notification_data): Added
  (dll_notification_context): Added
  (dll_notification): Added
  (backtrace_initialize): Use LdrRegisterDllNotification to load
  debug information of later loaded
  dlls.
---
 libbacktrace/pecoff.c | 102 +-
 1 file changed, 101 insertions(+), 1 deletion(-)

diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 647baa39640..bfe12cc2a0a 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -62,6 +62,32 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #undef Module32Next
 #endif
 #endif
+
+#if defined(_ARM_)
+#define NTAPI
+#else
+#define NTAPI __stdcall
+#endif
+
+/* This is a simplified (but binary compatible) version of what Microsoft
+   defines in their documentation. */
+struct dll_notifcation_data
+{
+  ULONG reserved;
+  /* The name as UNICODE_STRING struct. */
+  PVOID full_dll_name;
+  PVOID base_dll_name;
+  PVOID dll_base;
+  ULONG size_of_image;
+};
+
+typedef LONG NTSTATUS;
+typedef VOID CALLBACK (*LDR_DLL_NOTIFICATION)(ULONG,
+ struct dll_notifcation_data*,
+ PVOID);
+typedef NTSTATUS NTAPI (*LDR_REGISTER_FUNCTION)(ULONG,
+   LDR_DLL_NOTIFICATION, PVOID,
+   PVOID*);
 #endif
 
 /* Coff file header.  */
@@ -912,7 +938,8 @@ coff_add (struct backtrace_state *state, int descriptor,
   return 0;
 }
 
-#if defined(HAVE_WINDOWS_H) && !defined(HAVE_TLHELP32_H)
+#ifdef HAVE_WINDOWS_H
+#ifndef HAVE_TLHELP32_H
 static void
 free_modules (struct backtrace_state *state,
  backtrace_error_callback error_callback, void *data,
@@ -958,6 +985,51 @@ get_all_modules (struct backtrace_state *state,
 }
 }
 #endif
+struct dll_notification_context
+{
+  struct backtrace_state *state;
+  backtrace_error_callback error_callback;
+  void *data;
+};
+
+VOID CALLBACK
+dll_notification (ULONG reason,
+struct dll_notifcation_data *notification_data,
+PVOID context)
+{
+  char module_name[MAX_PATH];
+  int descriptor;
+  struct dll_notification_context* dll_context =
+(struct dll_notification_context*) context;
+  struct backtrace_state *state = dll_context->state;
+  void *data = dll_context->data;
+  backtrace_error_callback error_callback = dll_context->data;
+  fileline fileline;
+  int found_sym;
+  int found_dwarf;
+  HMODULE module_handle;
+
+  if (reason != /*LDR_DLL_NOTIFICATION_REASON_LOADED*/1)
+return;
+
+  if (!GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+ | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (TCHAR*) notification_data->dll_base,
+ &module_handle))
+return;
+
+  if (!GetModuleFileNameA ((HMODULE) module_handle, module_name, MAX_PATH - 1))
+return;
+
+  descriptor = backtrace_open (module_name, error_c

Re: [PATCH] c++/modules: seed namespaces for bindings [PR106363]

2024-01-06 Thread Nathan Sidwell

Ok,
I think I js=ust thought this unnecessary.


On 11/11/23 20:59, Nathaniel Shead wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu. I don't have write
access.

-- >8 --

Currently the first depset for an EK_BINDING is not seeded. This breaks
the attached testcase as then the namespace is not considered referenced
yet during streaming, but we've already finished importing.

There doesn't seem to be any particular reason I could find for skipping
the first depset for bindings, and removing the condition doesn't appear
to cause any test failures, so this patch removes that check.

PR c++/106363

gcc/cp/ChangeLog:

* module.cc (module_state::write_cluster): Don't skip first
depset for bindings.

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr106363_a.C: New test.
* g++.dg/modules/pr106363_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/module.cc  |  4 +---
  gcc/testsuite/g++.dg/modules/pr106363_a.C |  9 +
  gcc/testsuite/g++.dg/modules/pr106363_b.C | 10 ++
  3 files changed, 20 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/pr106363_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/pr106363_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index c1c8c226bc1..411a3b9411c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -14741,9 +14741,7 @@ module_state::write_cluster (elf_out *to, depset 
*scc[], unsigned size,
for (unsigned ix = 0; ix != size; ix++)
  {
depset *b = scc[ix];
-  for (unsigned jx = (b->get_entity_kind () == depset::EK_BINDING
- || b->is_special ()) ? 1 : 0;
-  jx != b->deps.length (); jx++)
+  for (unsigned jx = b->is_special (); jx != b->deps.length (); jx++)
{
  depset *dep = b->deps[jx];
  
diff --git a/gcc/testsuite/g++.dg/modules/pr106363_a.C b/gcc/testsuite/g++.dg/modules/pr106363_a.C

new file mode 100644
index 000..c18d2eef1c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr106363_a.C
@@ -0,0 +1,9 @@
+// PR c++/106363
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi pr106363.a }
+
+export module pr106363.a;
+
+namespace ns {
+  export int x;
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr106363_b.C 
b/gcc/testsuite/g++.dg/modules/pr106363_b.C
new file mode 100644
index 000..0508c0d6193
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr106363_b.C
@@ -0,0 +1,10 @@
+// PR c++/106363
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi pr106363.b }
+
+export module pr106363.b;
+import pr106363.a;
+
+namespace ns {
+  export using ns::x;
+}


--
Nathan Sidwell



Re: [PATCH v2] c++: Follow module grammar more closely [PR110808]

2024-01-06 Thread Nathan Sidwell

This is ok -- sorry, I thought I'd already acked this


On 12/16/23 06:03, Nathaniel Shead wrote:

Ping for https://gcc.gnu.org/pipermail/gcc-patches/2023-November/638089.html

On Fri, Nov 24, 2023 at 10:32:13PM +1100, Nathaniel Shead wrote:

On Thu, Nov 23, 2023 at 12:11:58PM -0500, Nathan Sidwell wrote:

On 11/14/23 01:24, Nathaniel Shead wrote:

I'll also note that the comments above the parsing functions here no
longer exactly match with the grammar in the standard, should they be
updated as well?


please.



As I was attempting to rewrite the comments I ended up splitting up the
work that was being done by cp_parser_module_name a lot to better match
the grammar, and also caught a few other segfaults that were occurring
along the way.

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

This patch cleans up the parsing of module-declarations and
import-declarations to more closely follow the grammar defined by the
standard.

For instance, currently we allow declarations like 'import A:B', even
from an unrelated source file (not part of module A), which causes
errors in merging declarations. However, the syntax in [module.import]
doesn't even allow this form of import, so this patch prevents this from
parsing at all and avoids the error that way.

Additionally, we sometimes allow statements like 'import :X' or
'module :X' even when not in a named module, and this causes segfaults,
so we disallow this too.

PR c++/110808

gcc/cp/ChangeLog:

* parser.cc (cp_parser_module_name): Rewrite to handle
module-names and module-partitions independently.
(cp_parser_module_partition): New function.
(cp_parser_module_declaration): Parse module partitions
explicitly. Don't change state if parsing module decl failed.
(cp_parser_import_declaration): Handle different kinds of
import-declarations locally.

gcc/testsuite/ChangeLog:

* g++.dg/modules/part-hdr-1_c.C: Fix syntax.
* g++.dg/modules/part-mac-1_c.C: Likewise.
* g++.dg/modules/mod-invalid-1.C: New test.
* g++.dg/modules/part-8_a.C: New test.
* g++.dg/modules/part-8_b.C: New test.
* g++.dg/modules/part-8_c.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/parser.cc | 100 ---
  gcc/testsuite/g++.dg/modules/mod-invalid-1.C |   7 ++
  gcc/testsuite/g++.dg/modules/part-8_a.C  |   6 ++
  gcc/testsuite/g++.dg/modules/part-8_b.C  |   6 ++
  gcc/testsuite/g++.dg/modules/part-8_c.C  |   8 ++
  gcc/testsuite/g++.dg/modules/part-hdr-1_c.C  |   2 +-
  gcc/testsuite/g++.dg/modules/part-mac-1_c.C  |   2 +-
  7 files changed, 95 insertions(+), 36 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/mod-invalid-1.C
  create mode 100644 gcc/testsuite/g++.dg/modules/part-8_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/part-8_b.C
  create mode 100644 gcc/testsuite/g++.dg/modules/part-8_c.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f6d088bc73f..20bd8d45a08 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -14853,58 +14853,64 @@ cp_parser_already_scoped_statement (cp_parser* 
parser, bool *if_p,
  
  /* Modules */
  
-/* Parse a module-name,

-   identifier
-   module-name . identifier
-   header-name
+/* Parse a module-name or module-partition.
  
-   Returns a pointer to module object, NULL.   */

+   module-name:
+ module-name-qualifier [opt] identifier
  
-static module_state *

-cp_parser_module_name (cp_parser *parser)
-{
-  cp_token *token = cp_lexer_peek_token (parser->lexer);
-  if (token->type == CPP_HEADER_NAME)
-{
-  cp_lexer_consume_token (parser->lexer);
+   module-partition:
+ : module-name-qualifier [opt] identifier
  
-  return get_module (token->u.value);

-}
+   module-name-qualifier:
+ identifier .
+ module-name-qualifier identifier .
  
-  module_state *parent = NULL;

-  bool partitioned = false;
-  if (token->type == CPP_COLON && named_module_p ())
-{
-  partitioned = true;
-  cp_lexer_consume_token (parser->lexer);
-}
+   Returns a pointer to the module object, or NULL on failure.
+   For PARTITION_P, PARENT is the module this is a partition of.  */
+
+static module_state *
+cp_parser_module_name (cp_parser *parser, bool partition_p = false,
+  module_state *parent = NULL)
+{
+  if (partition_p
+  && cp_lexer_consume_token (parser->lexer)->type != CPP_COLON)
+return NULL;
  
for (;;)

  {
if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME)
{
- cp_parser_error (parser, "expected module-name");
- break;
+ if (partition_p)
+   cp_parser_error (parser, "expected module-partition");
+ else
+   cp_parser_error (parser, "expected module-name");
+ return NULL;
}
  
tree name = cp_lexer_consume_token (parser->lexer)->u.value;

-  parent = get_module (name

Re: [PATCH] c++: Export usings referring to global module fragment [PR109679]

2024-01-06 Thread Nathan Sidwell

ok


On 1/3/24 05:01, Nathaniel Shead wrote:

Bootstrapped & regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

This patch stops 'add_binding_entity' from ignoring all names in the
global module fragment, since they should still be exported if named
in an exported using-declaration.

PR c++/109679

gcc/cp/ChangeLog:

* module.cc (depset::hash::add_binding_entity): Don't skip names
in the GMF if they've been exported with a using declaration.

gcc/testsuite/ChangeLog:

* g++.dg/modules/using-11.h: New test.
* g++.dg/modules/using-11_a.C: New test.
* g++.dg/modules/using-11_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/module.cc  | 6 --
  gcc/testsuite/g++.dg/modules/using-11.h   | 2 ++
  gcc/testsuite/g++.dg/modules/using-11_a.C | 9 +
  gcc/testsuite/g++.dg/modules/using-11_b.C | 8 
  4 files changed, 23 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/using-11.h
  create mode 100644 gcc/testsuite/g++.dg/modules/using-11_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/using-11_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 82b61a2c2ad..865a4b77eca 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12837,8 +12837,10 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags 
flags, void *data_)
else if (TREE_CODE (inner) == TEMPLATE_DECL)
inner = DECL_TEMPLATE_RESULT (inner);
  
-  if (!DECL_LANG_SPECIFIC (inner) || !DECL_MODULE_PURVIEW_P (inner))

-   /* Ignore global module fragment entities.  */
+  if ((!DECL_LANG_SPECIFIC (inner) || !DECL_MODULE_PURVIEW_P (inner))
+ && !(flags & (WMB_Using | WMB_Export)))
+   /* Ignore global module fragment entities unless explicitly
+  exported with a using declaration.  */
return false;
  
if (VAR_OR_FUNCTION_DECL_P (inner)

diff --git a/gcc/testsuite/g++.dg/modules/using-11.h 
b/gcc/testsuite/g++.dg/modules/using-11.h
new file mode 100644
index 000..64c1b0ca335
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-11.h
@@ -0,0 +1,2 @@
+// PR c++/109679
+inline int foo() { return 42; }
diff --git a/gcc/testsuite/g++.dg/modules/using-11_a.C 
b/gcc/testsuite/g++.dg/modules/using-11_a.C
new file mode 100644
index 000..b846bc79203
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-11_a.C
@@ -0,0 +1,9 @@
+// PR c++/109679
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi M }
+
+module;
+#include "using-11.h"
+
+export module M;
+export using ::foo;
diff --git a/gcc/testsuite/g++.dg/modules/using-11_b.C 
b/gcc/testsuite/g++.dg/modules/using-11_b.C
new file mode 100644
index 000..736a48c98f2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-11_b.C
@@ -0,0 +1,8 @@
+// PR c++/109679
+// { dg-module-do link }
+// { dg-additional-options "-fmodules-ts" }
+
+import M;
+int main() {
+  return foo();
+}


--
Nathan Sidwell



Re: c++/modules: Emit definitions of ODR-used static members imported from modules [PR112899]

2024-01-06 Thread Nathan Sidwell
Richard Smith & I discussed whether we should use the module interface's 
capability of giving vague linkage entities a strong location. I didn't want to 
go messing with that, 'cos it was changing yet more stuff.


But, perhaps we should revisit that?  Any keyless polymorphic class in module 
purview gets its vtables etc emitted in the module's object file?  Likewise 
these kinds of entities.


cc'ing Iain, who probably knows more about Clang's state here.

nathan


On 1/4/24 21:06, Jason Merrill wrote:

On 1/4/24 18:02, Nathaniel Shead wrote:

On Thu, Jan 04, 2024 at 05:42:34PM -0500, Jason Merrill wrote:

On 1/4/24 17:24, Nathaniel Shead wrote:

On Thu, Jan 04, 2024 at 03:31:50PM -0500, Jason Merrill wrote:

On 1/2/24 17:40, Nathaniel Shead wrote:

Static data members marked 'inline' should be emitted in TUs where they
are ODR-used.  We need to make sure that statics imported from modules
are correctly added to the 'pending_statics' map so that they get
emitted if needed, otherwise the attached testcase fails to link.


Hmm, this seems wrong to me; I'd think that static data members marked
inline should be emitted in the module, and not in importers.


That's what I'd initially thought too, but this is at least consistent
with non-class inlines (variables and functions), which similarly only
get emitted in TUs that they're ODR-used rather than always (and only)
being emitted within the module.

I guess an alternative would be to change it around so that all
exported definitions are marked as needed in the module interface file
(and emitted there), and then setting some flag so that they're never
emitted in importers.


Yes, that would be my expectation.  What do other modules implementations
do?


Clang only emits ODR-used declarations (same as GCC currently).

MSVC emits all inline variables (whether exported or not) but no inline
functions.


Hmm, not a strong vote for my direction.


I'm not entirely sure what flag that would be
though, I still haven't quite wrapped my head what controls what with
regards to this, and I'm not convinced it wouldn't break template
instantiations.


I would guess avoid emitting if DECL_MODULE_IMPORT_P &&
DECL_MODULE_ATTACH_P.


Ah yup, that would make sense. I guess, thinking about it more, we
should then also ensure that all TREE_PUBLIC declarations are emitted in
the module interface even if not exported, since they may be needed in
implementation units?


That would also make sense to me; since we know the module interface unit is 
compiled to an object file, everything vague linkage in it can go there.



I wonder if this might also be related to the issue Nathan noted with
regards to block-scope class methods, which I haven't completely worked
out how to solve yet otherwise (see
https://gcc.gnu.org/pipermail/gcc-patches/2023-November/638223.html).


Indeed.


I'll give implementing this a try then, if you think that would be
sensible. (Where by "this" I mean "emit all public declarations in
module interface files, whether used or not".)


I'd like to hear Nathan's thoughts on the matter first, since he's the modules 
implementation designer.


Jason



--
Nathan Sidwell



Re: [PATCH] c++/modules: more checks for exporting names with using-declarations

2024-01-06 Thread Nathan Sidwell

ok


On 11/10/23 17:52, Nathaniel Shead wrote:

I noticed while fixing PR106849 that we don't currently check validity
of exporting non-functions via using-declarations either; this patch
adds those checks factored out into a new function. I also tried to make
the error messages a bit more descriptive.

This patch is based on [1] (with the adjustment to use STRIP_TEMPLATE
Nathan mentioned), but could probably be a replacement for that patch if
preferred - if so I'm happy to re-send rebased off master instead.

The ICEs mentioned in the commit message are caused by code such as

   export module M;

   namespace {
 enum e { x };
   }
   export using ::e;

in depset::hash::finalize_dependencies when attempting to get a
DECL_SOURCE_LOCATION of an OVERLOAD. I haven't fixed that in this patch
though because after this patch I was no longer able to construct an
example of that error, but it's maybe something to fix up later as well.

[1]: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/635869.html

Bootstrapped and regtested on x86_64-pc-linux-gnu. I don't have write
access.

-- >8 --

Currently only functions are directly checked for validity when
exporting via a using-declaration.  This patch also checks exporting
non-external names of variables, types, and enumerators.  This also
prevents ICEs with `export using enum` for internal-linkage enums.

While we're at it we also improve the error messages for these cases to
provide more context about what went wrong.

gcc/cp/ChangeLog:

* name-lookup.cc (check_can_export_using_decl): New.
(do_nonmember_using_decl): Use above to check if names can be
exported.

gcc/testsuite/ChangeLog:

* g++.dg/modules/using-10.C: New test.
* g++.dg/modules/using-enum-2.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/name-lookup.cc   | 74 +++--
  gcc/testsuite/g++.dg/modules/using-10.C | 71 
  gcc/testsuite/g++.dg/modules/using-enum-2.C | 23 +++
  3 files changed, 148 insertions(+), 20 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/using-10.C
  create mode 100644 gcc/testsuite/g++.dg/modules/using-enum-2.C

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index e74084948b6..d19ea5d121c 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -4802,6 +4802,49 @@ pushdecl_outermost_localscope (tree x)
return b ? do_pushdecl_with_scope (x, b) : error_mark_node;
  }
  
+/* Checks if BINDING is a binding that we can export.  */

+
+static bool
+check_can_export_using_decl (tree binding)
+{
+  tree decl = STRIP_TEMPLATE (binding);
+
+  /* Linkage is determined by the owner of an enumerator.  */
+  if (TREE_CODE (decl) == CONST_DECL)
+decl = TYPE_NAME (DECL_CONTEXT (decl));
+
+  /* If the using decl is exported, the things it refers
+ to must also be exported (or not have module attachment).  */
+  if (!DECL_MODULE_EXPORT_P (decl)
+  && (DECL_LANG_SPECIFIC (decl)
+ && DECL_MODULE_ATTACH_P (decl)))
+{
+  bool internal_p = !TREE_PUBLIC (decl);
+
+  /* A template in an anonymous namespace doesn't constrain TREE_PUBLIC
+until it's instantiated, so double-check its context.  */
+  if (!internal_p && TREE_CODE (binding) == TEMPLATE_DECL)
+   internal_p = decl_internal_context_p (decl);
+
+  auto_diagnostic_group d;
+  error ("exporting %q#D that does not have external linkage",
+binding);
+  if (TREE_CODE (decl) == TYPE_DECL && !DECL_IMPLICIT_TYPEDEF_P (decl))
+   /* An un-exported explicit type alias has no linkage.  */
+   inform (DECL_SOURCE_LOCATION (binding),
+   "%q#D declared here with no linkage", binding);
+  else if (internal_p)
+   inform (DECL_SOURCE_LOCATION (binding),
+   "%q#D declared here with internal linkage", binding);
+  else
+   inform (DECL_SOURCE_LOCATION (binding),
+   "%q#D declared here with module linkage", binding);
+  return false;
+}
+
+  return true;
+}
+
  /* Process a local-scope or namespace-scope using declaration.  LOOKUP
 is the result of qualified lookup (both value & type are
 significant).  FN_SCOPE_P indicates if we're at function-scope (as
@@ -4845,22 +4888,7 @@ do_nonmember_using_decl (name_lookup &lookup, bool 
fn_scope_p,
  tree new_fn = *usings;
  bool exporting = revealing_p && module_exporting_p ();
  if (exporting)
-   {
- tree decl = STRIP_TEMPLATE (new_fn);
-
- /* If the using decl is exported, the things it refers
-to must also be exported (or not have module attachment).  */
- if (!DECL_MODULE_EXPORT_P (decl)
- && (DECL_LANG_SPECIFIC (decl)
- && DECL_MODULE_ATTACH_P (decl)))
-   {
- auto_diagnostic_group d;
- error ("%q#D does not have external linkage", new_fn);
-

Re: [PATCH] c++/modules: Prevent overwriting arguments for duplicates [PR112588]

2024-01-06 Thread Nathan Sidwell
I;m not sure about this, there was clearly a reason I did it the way it is, but 
perhaps that reasoning became obsolete -- something about an existing 
declaration and reading in a definition maybe?


nathan

On 11/22/23 06:33, Nathaniel Shead wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu. I don't have write
access.

-- >8 --

When merging duplicate instantiations of function templates, currently
read_function_def overwrites the arguments with that of the existing
duplicate. This is problematic, however, since this means that the
PARM_DECLs in the body of the function definition no longer match with
the PARM_DECLs in the argument list, which causes issues when it comes
to generating RTL.

There doesn't seem to be any reason to do this replacement, so this
patch removes that logic.

PR c++/112588

gcc/cp/ChangeLog:

* module.cc (trees_in::read_function_def): Don't overwrite
arguments.

gcc/testsuite/ChangeLog:

* g++.dg/modules/merge-16.h: New test.
* g++.dg/modules/merge-16_a.C: New test.
* g++.dg/modules/merge-16_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/module.cc  |  2 --
  gcc/testsuite/g++.dg/modules/merge-16.h   | 10 ++
  gcc/testsuite/g++.dg/modules/merge-16_a.C |  7 +++
  gcc/testsuite/g++.dg/modules/merge-16_b.C |  5 +
  4 files changed, 22 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/merge-16.h
  create mode 100644 gcc/testsuite/g++.dg/modules/merge-16_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/merge-16_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 4f5b6e2747a..2520ab659cc 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -11665,8 +11665,6 @@ trees_in::read_function_def (tree decl, tree 
maybe_template)
DECL_RESULT (decl) = result;
DECL_INITIAL (decl) = initial;
DECL_SAVED_TREE (decl) = saved;
-  if (maybe_dup)
-   DECL_ARGUMENTS (decl) = DECL_ARGUMENTS (maybe_dup);
  
if (context)

SET_DECL_FRIEND_CONTEXT (decl, context);
diff --git a/gcc/testsuite/g++.dg/modules/merge-16.h 
b/gcc/testsuite/g++.dg/modules/merge-16.h
new file mode 100644
index 000..fdb38551103
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/merge-16.h
@@ -0,0 +1,10 @@
+// PR c++/112588
+
+void f(int*);
+
+template 
+struct S {
+  void g(int n) { f(&n); }
+};
+
+template struct S;
diff --git a/gcc/testsuite/g++.dg/modules/merge-16_a.C 
b/gcc/testsuite/g++.dg/modules/merge-16_a.C
new file mode 100644
index 000..c243224c875
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/merge-16_a.C
@@ -0,0 +1,7 @@
+// PR c++/112588
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi merge16 }
+
+module;
+#include "merge-16.h"
+export module merge16;
diff --git a/gcc/testsuite/g++.dg/modules/merge-16_b.C 
b/gcc/testsuite/g++.dg/modules/merge-16_b.C
new file mode 100644
index 000..8c7b1f0511f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/merge-16_b.C
@@ -0,0 +1,5 @@
+// PR c++/112588
+// { dg-additional-options "-fmodules-ts" }
+
+#include "merge-16.h"
+import merge16;


--
Nathan Sidwell



Re: [PATCH] c++/modules: Fix ICE when writing nontrivial variable initializers

2024-01-06 Thread Nathan Sidwell

ok

On 1/2/24 17:43, Nathaniel Shead wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

The attached testcase Patrick found in PR c++/112899 ICEs because it is
attempting to write a variable initializer that is no longer in the
static_aggregates map.

The issue is that, for non-header modules, the loop in
c_parse_final_cleanups prunes the static_aggregates list, which means
that by the time we get to emitting module information those
initialisers have been lost.

However, we don't actually need to write non-trivial initialisers for
non-header modules, because they've already been emitted as part of the
module TU itself.  Instead let's just only write the initializers from
header modules (which skipped writing them in c_parse_final_cleanups).

gcc/cp/ChangeLog:

* module.cc (trees_out::write_var_def): Only write initializers
in header modules.

gcc/testsuite/ChangeLog:

* g++.dg/modules/init-5_a.C: New test.
* g++.dg/modules/init-5_b.C: New test.

Signed-off-by: Nathaniel Shead 
---
  gcc/cp/module.cc|  3 ++-
  gcc/testsuite/g++.dg/modules/init-5_a.C |  9 +
  gcc/testsuite/g++.dg/modules/init-5_b.C | 10 ++
  3 files changed, 21 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/init-5_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/init-5_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 14818131a70..82b61a2c2ad 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -11707,7 +11707,8 @@ trees_out::write_var_def (tree decl)
  {
tree dyn_init = NULL_TREE;
  
-  if (DECL_NONTRIVIALLY_INITIALIZED_P (decl))

+  /* We only need to write initializers in header modules.  */
+  if (header_module_p () && DECL_NONTRIVIALLY_INITIALIZED_P (decl))
{
  dyn_init = value_member (decl,
   CP_DECL_THREAD_LOCAL_P (decl)
diff --git a/gcc/testsuite/g++.dg/modules/init-5_a.C 
b/gcc/testsuite/g++.dg/modules/init-5_a.C
new file mode 100644
index 000..466b120b5a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/init-5_a.C
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi M }
+
+export module M;
+
+export struct A {
+  static int f() { return -1; }
+  static inline int x = f();
+};
diff --git a/gcc/testsuite/g++.dg/modules/init-5_b.C 
b/gcc/testsuite/g++.dg/modules/init-5_b.C
new file mode 100644
index 000..40973cc6936
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/init-5_b.C
@@ -0,0 +1,10 @@
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import M;
+
+int main() {
+  const int& x = A::x;
+  if (x != -1)
+__builtin_abort();
+}


--
Nathan Sidwell



Re: [PATCH 3/8] libgomp: runtime support for target_device selector

2024-01-06 Thread Tobias Burnus

Hi Sandra,

looks quite okay, but I have a couple of remarks:

Sandra Loosemore wrote:

From: Kwok Cheung Yeung

This patch implements the libgomp runtime support for the dynamic
target_device selector via the GOMP_evaluate_target_device function.


...

--- /dev/null
+++ b/libgomp/config/gcn/selector.c

...

+GOMP_evaluate_current_device (const char *kind, const char *arch,
+ const char *isa)
+{
+  if (kind && strcmp (kind, "gpu") != 0)
+return false;


This should also match: kind == nohost.


+
+  if (arch && strcmp (arch, "gcn") != 0)
+return false;


"amdgcn" missing - we support both for better compatibility with LLVM.


+  if (!isa)
+return true;
+
+#ifdef __GCN3__
+  if (strcmp (isa, "fiji") == 0 || strcmp (isa, "gfx803") == 0)
+return true;
+#endif
+
+#ifdef __GCN5__
+  if (strcmp (isa, "gfx900") == 0 || strcmp (isa, "gfx906") != 0
+  || strcmp (isa, "gfx908") == 0)
+return true;
+#endif


This misses gfx90a and gfx1030. Additionally, the last conditions 
matches too much. Can you use


#ifdef __fiji__
#ifdef __gfx900__
etc.

instead?


--- /dev/null
+++ b/libgomp/config/linux/selector.c

...

+bool
+GOMP_evaluate_current_device (const char *kind, const char *arch,
+ const char *isa)
+{
+  if (kind && strcmp (kind, "cpu") != 0)
+return false;


You also need to match "host".


diff --git a/libgomp/config/linux/x86/selector.c 
b/libgomp/config/linux/x86/selector.c
new file mode 100644
index 000..2b6c2ba165b
--- /dev/null
+++ b/libgomp/config/linux/x86/selector.c

...


+bool
+GOMP_evaluate_current_device (const char *kind, const char *arch,
+ const char *isa)
+{
+  if (kind && strcmp (kind, "cpu") != 0)
+return false;


This misses "host" as well.


+  if (arch
+  && strcmp (arch, "x86") != 0
+  && strcmp (arch, "ia32") != 0
+#ifdef __x86_64__
+  && strcmp (arch, "x86_64") != 0
+#endif
+#ifdef __ILP32__
+  && strcmp (arch, "x32") != 0
+#endif
+  && strcmp (arch, "i386") != 0
+  && strcmp (arch, "i486") != 0
+#ifndef __i486__
+  && strcmp (arch, "i586") != 0
+#endif
+#if !defined (__i486__) && !defined (__i586__)
+  && strcmp (arch, "i686") != 0
+#endif


The 'i486' seems to lack a #ifdef __i486__ check.
And it seems to be such that
  i486 implies i386
  i586 implies i486 and i386
  etc.
if I understand ix86_omp_device_kind_arch_isa in
gcc/config/i386/i386-options.cc correctly.


There is of course the problem that the compilation flags used for 
libgomp are very likely different to the compilation flags of the user 
program, which in term can differ between files.


Thus, I think we should update
  https://gcc.gnu.org/onlinedocs/libgomp/OpenMP-Context-Selectors.html
(a) the host compiler always also matches "cpu"
(b) We probably should state somewhere that:
* on x86, both the arch = i486 to i686 and the isa flags depend on
  the command line arguments more than on the actual hardware.
* that's especially true for dynamic selectors as the flags used
  can differ between 'compilation units' and also the flags used
  for the run-time library.
* For nvptx: on the device side, the -march= implies that all
  sm_* lower than that value is set.
  For target_device, the actual hardware is checked at run time,
  implying the highest of the gcc-manual listed -march= values is
  selected that the hardware actually supports at runtime.

For (b) we should have to find some better wording and possibly be less 
precise but I think some kind of warning/note is needed here.



+  if (!isa)
+return true;
+
+#ifdef __WBNOINVD__
+  if (strcmp (isa, "wbnoinvd") == 0) return true;
+#endif


I think at least the following are missing:

-mavx10.1-256 and -mavx10.1-512
do not seem to have a #define
→ Maybe we should file a PR given that those
seem to be the only missing ones.

otherwise:

__AVX10_512BIT__ and "avx10-max-512bit"
__AVX10_1__ and "avx10.1"
__AMX_FP16__ and -mamx-fp16
__CMPCCXADD__ and "cmpccxadd"
__AVXNECONVERT__ and "avxneconvert"
__RAOINT__ and "raoint"
__PREFETCHI__ and "refetchi"
__USER_MSR__ and "usermsr".
__EVEX256__ and "evex512".
__AVXVNNIINT8__ and "avxvnniint8"
__SM4__ and "sm4"
__SHA512__ and "sha512"
__SM3__ and "sm3"
__AVXVNNIINT16__ and "avxvnniint16"
__AMX_COMPLEX__ and "amx-complex"
__AVXIFMA__ and avxifma"

and possibly some more but it might be also be complete.



+++ b/libgomp/config/nvptx/selector.c
+bool
+GOMP_evaluate_current_device (const char *kind, const char *arch,
+ const char *isa)
+{
+  if (kind && strcmp (kind, "gpu") != 0)
+return false;

"nohost" missing.


--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -414,6 +414,7 @@ GOMP_5.1 {
GOMP_scope_start;
GOMP_warning;
GOMP_teams4;
+   GOMP_evaluate_target_device;
  } GOMP_5.0.1;


This looks wrong. In my understanding you cannot just randomly
add entries to old map entr

RE: [x86_64 PATCH] PR target/112992: Optimize mode for broadcast of constants.

2024-01-06 Thread Roger Sayle
Hi Hongtao,

Many thanks for the review.  This revised patch implements several
of your suggestions, specifically to use pshufd for V4SImode and
punpcklqdq for V2DImode.  These changes are demonstrated by the
examples below:

typedef unsigned int v4si __attribute((vector_size(16)));
typedef unsigned long long v2di __attribute((vector_size(16)));

v4si foo() { return (v4si){1,1,1,1}; }
v2di bar() { return (v2di){1,1}; }

The previous version of my patch generated:

foo:movdqa  .LC0(%rip), %xmm0
ret
bar:movdqa  .LC1(%rip), %xmm0
ret

with this revised version, -O2 generates:

foo:movl$1, %eax
movd%eax, %xmm0
pshufd  $0, %xmm0, %xmm0
ret
bar:movl$1, %eax
movq%rax, %xmm0
punpcklqdq  %xmm0, %xmm0
ret

However, if it's OK with you, I'd prefer to allow this function to
return false, safely falling back to emitting a vector load from
the constant bool rather than ICEing from a gcc_assert.  For one
thing this isn't a unrecoverable correctness issue, but at worst
a missed optimization.  The deeper reason is that this usefully
provides a handle for tuning on different microarchitectures.
On some (AMD?) machines, where !TARGET_INTER_UNIT_MOVES_TO_VEC,
the first form above may be preferable to the second.  Currently
the start of ix86_convert_const_wide_int_to_broadcast disables
broadcasts for !TARGET_INTER_UNIT_MOVES_TO_VEC even when an
implementation doesn't reuire an inter unit move, such as a
broadcast from memory.  I plan follow-up patches that benefit
from this flexibility.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?

gcc/ChangeLog
PR target/112992
* config/i386/i386-expand.cc
(ix86_convert_const_wide_int_to_broadcast): Allow call to
ix86_expand_vector_init_duplicate to fail, and return NULL_RTX.
(ix86_broadcast_from_constant): Revert recent change; Return a
suitable MEMREF independently of mode/target combinations.
(ix86_expand_vector_move): Allow ix86_expand_vector_init_duplicate
to decide whether expansion is possible/preferrable.  Only try
forcing DImode constants to memory (and trying again) if calling
ix86_expand_vector_init_duplicate fails with an DImode immediate
constant.
(ix86_expand_vector_init_duplicate) : Try using
V4SImode for suitable immediate constants.
: Try using V8SImode for suitable constants.
: Fail for CONST_INT_P, i.e. use constant pool.
: Likewise.
: For CONST_INT_P try using V4SImode via widen.
: For CONT_INT_P try using V8HImode via widen.
: Handle CONT_INTs via simplify_binary_operation.
Allow recursive calls to ix86_expand_vector_init_duplicate to fail.
: For CONST_INT_P try V8SImode via widen.
: For CONST_INT_P try V16HImode via widen.
(ix86_expand_vector_init): Move try using a broadcast for all_same
with ix86_expand_vector_init_duplicate before using constant pool.

gcc/testsuite/ChangeLog
* gcc.target/i386/auto-init-8.c: Update test case.
* gcc.target/i386/avx512f-broadcast-pr87767-1.c: Likewise.
* gcc.target/i386/avx512f-broadcast-pr87767-5.c: Likewise.
* gcc.target/i386/avx512fp16-13.c: Likewise.
* gcc.target/i386/avx512vl-broadcast-pr87767-1.c: Likewise.
* gcc.target/i386/avx512vl-broadcast-pr87767-5.c: Likewise.
* gcc.target/i386/pr100865-1.c: Likewise.
* gcc.target/i386/pr100865-10a.c: Likewise.
* gcc.target/i386/pr100865-10b.c: Likewise.
* gcc.target/i386/pr100865-2.c: Likewise.
* gcc.target/i386/pr100865-3.c: Likewise.
* gcc.target/i386/pr100865-4a.c: Likewise.
* gcc.target/i386/pr100865-4b.c: Likewise.
* gcc.target/i386/pr100865-5a.c: Likewise.
* gcc.target/i386/pr100865-5b.c: Likewise.
* gcc.target/i386/pr100865-9a.c: Likewise.
* gcc.target/i386/pr100865-9b.c: Likewise.
* gcc.target/i386/pr102021.c: Likewise.
* gcc.target/i386/pr90773-17.c: Likewise.

Thanks in advance.
Roger
--

> -Original Message-
> From: Hongtao Liu 
> Sent: 02 January 2024 05:40
> To: Roger Sayle 
> Cc: gcc-patches@gcc.gnu.org; Uros Bizjak 
> Subject: Re: [x86_64 PATCH] PR target/112992: Optimize mode for broadcast of
> constants.
> 
> On Fri, Dec 22, 2023 at 6:25 PM Roger Sayle 
> wrote:
> >
> >
> > This patch resolves the second part of PR target/112992, building upon
> > Hongtao Liu's solution to the first part.
> >
> > The issue addressed by this patch is that when initializing vectors by
> > broadcasting integer constants, the compiler has the flexibility to
> > select the most appropriate vector mode to perform the broadcast, as
> > long as the resulting vector has an identical bit pattern.  For
> > example, the followin

[PATCH v8 1/4] c++: P0847R7 (deducing this) - prerequisite changes. [PR102609]

2024-01-06 Thread waffl3x
Bootstrapped and tested on x86_64-linux with no regressions.

I'm considering this finished, I have CWG2586 working but I have not
included it in this version of the patch. I was not happy with the
amount of work I had done on it. I will try to get it finished before
we get cut off, and I'm pretty sure I can. I just don't want to risk
missing the boat for the whole patch just for that.

There aren't too many changes from v7, it's mostly just cleaned up.
There are a few though, so do take a look, if there's anything severe I
can rush to fix it if necessary.

That's all, hopefully all is good, fingers crossed.

AlexFrom cd122053dfad741a7d90adcd45929af768ce643f Mon Sep 17 00:00:00 2001
From: Waffl3x 
Date: Sun, 31 Dec 2023 03:16:36 -0700
Subject: [PATCH 1/4] C++23 P0847R7 (deducing this) - prerequisite changes.
 [PR102609]

Adds the xobj_flag member to lang_decl_fn and a corresponding member access
macro and predicate to support the addition of explicit object member
functions. Additionally, since explicit object member functions are also
non-static member functions, we need to change uses of
DECL_NONSTATIC_MEMBER_FUNCTION_P to clarify whether they intend to include or
exclude them.

Many of these alterations are authored by Jason Merril.

	PR c++/102609

gcc/cp/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - prerequisite changes. [PR102609]
	* cp-tree.h (struct lang_decl_fn): New data member.
	(DECL_NONSTATIC_MEMBER_FUNCTION_P): Poison.
	(DECL_IOBJ_MEMBER_FUNCTION_P): Define.
	(DECL_FUNCTION_XOBJ_FLAG): Define.
	(DECL_XOBJ_MEMBER_FUNCTION_P): Define.
	(DECL_OBJECT_MEMBER_FUNCTION_P): Define.
	(DECL_FUNCTION_MEMBER_P): Don't use DECL_NONSTATIC_MEMBER_FUNCTION_P.
	(DECL_CONST_MEMFUNC_P): Likewise.
	(DECL_VOLATILE_MEMFUNC_P): Likewise.
	(DECL_NONSTATIC_MEMBER_P): Likewise.
* module.cc (trees_out::lang_decl_bools): Handle xobj_flag.
(trees_in::lang_decl_bools): Handle xobj_flag.
	* call.cc (build_this_conversion):
	(add_function_candidate):
	(add_template_candidate_real):
	(add_candidates):
	(maybe_warn_class_memaccess):
	(cand_parms_match):
	(joust):
	(do_warn_dangling_reference): Don't use it.
	* class.cc (finalize_literal_type_property):
	(finish_struct):
	(resolve_address_of_overloaded_function):
	* constexpr.cc (is_valid_constexpr_fn):
	(cxx_bind_parameters_in_call):
	* contracts.cc (build_contract_condition_function):
	* cp-objcp-common.cc (cp_decl_dwarf_attribute):
	* cxx-pretty-print.cc (cxx_pretty_printer::postfix_expression):
	(cxx_pretty_printer::declaration_specifiers):
	(cxx_pretty_printer::direct_declarator):
	* decl.cc (cp_finish_decl):
	(grok_special_member_properties):
	(start_preparsed_function):
	(record_key_method_defined):
	* decl2.cc (cp_handle_deprecated_or_unavailable):
	* init.cc (find_uninit_fields_r):
	(build_offset_ref):
	* lambda.cc (lambda_expr_this_capture):
	(maybe_generic_this_capture):
	(nonlambda_method_basetype):
	* mangle.cc (write_nested_name):
	* method.cc (early_check_defaulted_comparison):
	(skip_artificial_parms_for):
	(num_artificial_parms_for):
	* module.cc (trees_out::lang_decl_bools):
	(trees_in::lang_decl_bools):
	* pt.cc (is_specialization_of_friend):
	(determine_specialization):
	(copy_default_args_to_explicit_spec):
	(check_explicit_specialization):
	(tsubst_contract_attribute):
	(check_non_deducible_conversions):
	(more_specialized_fn):
	(maybe_instantiate_noexcept):
	(register_parameter_specializations):
	(value_dependent_expression_p):
	* search.cc (shared_member_p):
	(lookup_member):
	(field_access_p):
	* semantics.cc (finish_omp_declare_simd_methods):
	* tree.cc (lvalue_kind):
	* typeck.cc (invalid_nonstatic_memfn_p): Don't use
	DECL_NONSTATIC_MEMBER_FUNCTION_P.

libcc1/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - prerequisite changes. [PR102609]
	* libcp1plugin.cc (plugin_pragma_push_user_expression): Don't use
	DECL_NONSTATIC_MEMBER_FUNCTION_P.

Signed-off-by: Waffl3x 
---
 gcc/cp/call.cc | 25 +
 gcc/cp/class.cc|  6 +++---
 gcc/cp/constexpr.cc|  4 ++--
 gcc/cp/contracts.cc|  6 +++---
 gcc/cp/cp-objcp-common.cc  |  4 ++--
 gcc/cp/cp-tree.h   | 37 ++---
 gcc/cp/cxx-pretty-print.cc |  6 +++---
 gcc/cp/decl.cc |  8 
 gcc/cp/decl2.cc|  2 +-
 gcc/cp/init.cc |  4 ++--
 gcc/cp/lambda.cc   |  9 +
 gcc/cp/mangle.cc   |  4 ++--
 gcc/cp/method.cc   |  8 
 gcc/cp/module.cc   |  6 --
 gcc/cp/pt.cc   | 38 +++---
 gcc/cp/search.cc   |  5 +++--
 gcc/cp/semantics.cc|  2 +-
 gcc/cp/tree.cc |  2 +-
 gcc/cp/typeck.cc   |  2 +-
 libcc1/libcp1plugin.cc |  2 +-
 20 files changed, 104 insertions(+), 76 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 6ac87a298b2..46f2ccdfc48 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -2309,7 +2309,7 @@

[PATCH v8 3/4] c++: P0847R7 (deducing this) - diagnostics. [PR102609]

2024-01-06 Thread waffl3x
Bootstrapped and tested on x86_64-linux with no regressions.From 32a713d9826a042b260e84dcfbfd31c619a122fb Mon Sep 17 00:00:00 2001
From: Waffl3x 
Date: Fri, 5 Jan 2024 14:34:34 -0700
Subject: [PATCH 3/4] C++23 P0847R7 (deducing this) - diagnostics. [PR102609]

Diagnostics for xobj member functions. Also includes some diagnostics for xobj
lambdas which are not implemented here. CWG2554 is also implemented here, we
explicitly error when an xobj member function overrides a virtual function.

	PR c++/102609

gcc/c-family/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - diagnostics.
	* c-cppbuiltin.cc (c_cpp_builtins): Define
	__cpp_explicit_this_parameter=202110L feature test macro.

gcc/cp/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - diagnostics.
	* class.cc (resolve_address_of_overloaded_function): Diagnostics.
	* cp-tree.h (TFF_XOBJ_FUNC): Define.
	* decl.cc (grokfndecl): Diagnostics.
	(grokdeclarator): Diagnostics.
	* error.cc (dump_aggr_type): Pass TFF_XOBJ_FUNC.
	(dump_lambda_function): Formatting for xobj lambda.
	(dump_function_decl): Pass TFF_XOBJ_FUNC.
	(dump_parameters): Formatting for xobj member functions.
	(function_category): Formatting for xobj member functions.
	* parser.cc (cp_parser_decl_specifier_seq): Diagnostics.
	(cp_parser_parameter_declaration): Diagnostics.
	* search.cc (look_for_overrides_here): Make xobj member functions
	override.
	(look_for_overrides_r): Reject an overriding xobj member function
	and diagnose it.
	* semantics.cc (finish_this_expr): Diagnostics.
	* typeck.cc (cp_build_addr_expr_1): Diagnostics.

gcc/testsuite/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - diagnostics.
	* g++.dg/cpp23/feat-cxx2b.C: Test existance and value of
	__cpp_explicit_this_parameter feature test macro.
	* g++.dg/cpp26/feat-cxx26.C: Likewise.
	* g++.dg/cpp23/explicit-obj-cxx-dialect-A.C: New test.
	* g++.dg/cpp23/explicit-obj-cxx-dialect-B.C: New test.
	* g++.dg/cpp23/explicit-obj-cxx-dialect-C.C: New test.
	* g++.dg/cpp23/explicit-obj-cxx-dialect-D.C: New test.
	* g++.dg/cpp23/explicit-obj-cxx-dialect-E.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics1.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics2.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics3.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics4.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics5.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics6.C: New test.
	* g++.dg/cpp23/explicit-obj-diagnostics7.C: New test.

Signed-off-by: Waffl3x 
---
 gcc/c-family/c-cppbuiltin.cc  |   1 +
 gcc/cp/class.cc   |  55 -
 gcc/cp/cp-tree.h  |   5 +-
 gcc/cp/decl.cc| 138 ++--
 gcc/cp/error.cc   |  24 +-
 gcc/cp/parser.cc  |  38 +++-
 gcc/cp/search.cc  |  14 +-
 gcc/cp/semantics.cc   |  25 ++-
 gcc/cp/typeck.cc  |  45 +++-
 .../g++.dg/cpp23/explicit-obj-cxx-dialect-A.C |   7 +
 .../g++.dg/cpp23/explicit-obj-cxx-dialect-B.C |   7 +
 .../g++.dg/cpp23/explicit-obj-cxx-dialect-C.C |   9 +
 .../g++.dg/cpp23/explicit-obj-cxx-dialect-D.C |   8 +
 .../g++.dg/cpp23/explicit-obj-cxx-dialect-E.C |   8 +
 .../g++.dg/cpp23/explicit-obj-diagnostics1.C  | 139 
 .../g++.dg/cpp23/explicit-obj-diagnostics2.C  |  26 +++
 .../g++.dg/cpp23/explicit-obj-diagnostics3.C  |  20 ++
 .../g++.dg/cpp23/explicit-obj-diagnostics4.C  |  16 ++
 .../g++.dg/cpp23/explicit-obj-diagnostics5.C  |  23 ++
 .../g++.dg/cpp23/explicit-obj-diagnostics6.C  | 206 ++
 .../g++.dg/cpp23/explicit-obj-diagnostics7.C  |  95 
 gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C   |   6 +
 gcc/testsuite/g++.dg/cpp26/feat-cxx26.C   |   6 +
 23 files changed, 871 insertions(+), 50 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-A.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-B.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-C.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-D.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-cxx-dialect-E.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics5.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics6.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics7.C

diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 2d1249f29ed..73c14f6d570 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1082

[PATCH v8 4/4] c++: P0847R7 (deducing this) - xobj lambdas. [PR102609]

2024-01-06 Thread waffl3x
Bootstrapped and tested on x86_64-linux with no regressions.

That's it for now. If I manage to finish CWG2586 in time I guess I'll
submit it as patch 5/4? I'm definitely locked in on all these changes
unless there's a really good reason.

Alex


Re: [PATCH v8 4/4] c++: P0847R7 (deducing this) - xobj lambdas. [PR102609]

2024-01-06 Thread Jakub Jelinek
On Sun, Jan 07, 2024 at 12:05:50AM +, waffl3x wrote:
> Bootstrapped and tested on x86_64-linux with no regressions.
> 
> That's it for now. If I manage to finish CWG2586 in time I guess I'll
> submit it as patch 5/4? I'm definitely locked in on all these changes
> unless there's a really good reason.

No patch attached nor included here...

Jakub



[Committed] RISC-V: Use MAX instead of std::max [VSETVL PASS]

2024-01-06 Thread Juzhe-Zhong
Obvious fix, Committed.

gcc/ChangeLog:

* config/riscv/riscv-vsetvl.cc: replace std::max by MAX.

---
 gcc/config/riscv/riscv-vsetvl.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 7d748edc0ef..df7ed149388 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -1668,7 +1668,7 @@ private:
   }
   inline void use_max_sew (vsetvl_info &prev, const vsetvl_info &next)
   {
-auto max_sew = std::max (prev.get_sew (), next.get_sew ());
+int max_sew = MAX (prev.get_sew (), next.get_sew ());
 prev.set_sew (max_sew);
 use_min_of_max_sew (prev, next);
   }
@@ -1702,7 +1702,7 @@ private:
   inline void use_max_sew_and_lmul_with_prev_ratio (vsetvl_info &prev,
const vsetvl_info &next)
   {
-auto max_sew = std::max (prev.get_sew (), next.get_sew ());
+int max_sew = MAX (prev.get_sew (), next.get_sew ());
 prev.set_vlmul (calculate_vlmul (max_sew, prev.get_ratio ()));
 prev.set_sew (max_sew);
   }
-- 
2.36.3



Re: [PATCH v8 4/4] c++: P0847R7 (deducing this) - xobj lambdas. [PR102609]

2024-01-06 Thread waffl3x





On Saturday, January 6th, 2024 at 5:17 PM, Jakub Jelinek  
wrote:


> 
> 
> On Sun, Jan 07, 2024 at 12:05:50AM +, waffl3x wrote:
> 
> > Bootstrapped and tested on x86_64-linux with no regressions.
> > 
> > That's it for now. If I manage to finish CWG2586 in time I guess I'll
> > submit it as patch 5/4? I'm definitely locked in on all these changes
> > unless there's a really good reason.
> 
> 
> No patch attached nor included here...
> 
> Jakub

MY BAD, thank you very much. 

Alex
From aac380e6f7e7fddfa7acf3c166a75bda56d54f7a Mon Sep 17 00:00:00 2001
From: Waffl3x 
Date: Sat, 6 Jan 2024 16:29:45 -0700
Subject: [PATCH 4/4] C++23 P0847R7 (deducing this) - xobj lambdas. [PR102609]

This implements support for xobj lambdas.  There are extensive tests included,
but not exhaustive.  Dependent lambdas should work and have been tested
lightly, but we need more exhaustive tests for them.

	PR c++/102609

gcc/cp/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - xobj lambdas.
	* lambda.cc (build_capture_proxy): Don't fold direct object types.
	* parser.cc (cp_parser_lambda_declarator_opt): Handle xobj lambdas,
	diagnostics.  Comments also updated.
	* pt.cc (tsubst_function_decl): Handle xobj lambdas.  Check object
	type of xobj lambda call operator, diagnose incorrect types.
	(tsubst_lambda_expr): Update comment.
	* semantics.cc (finish_decltype_type): Also consider by-value object
	parameter qualifications.

gcc/testsuite/ChangeLog:

	PR c++/102609
	C++23 P0847R7 (deducing this) - xobj lambdas.
	* g++.dg/cpp23/explicit-obj-diagnostics8.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda1.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda10.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda11.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda12.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda13.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda2.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda3.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda4.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda5.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda6.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda7.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda8.C: New test.
	* g++.dg/cpp23/explicit-obj-lambda9.C: New test.

Signed-off-by: Waffl3x 
---
 gcc/cp/lambda.cc  |   4 +-
 gcc/cp/parser.cc  |  84 +-
 gcc/cp/pt.cc  |  74 +-
 gcc/cp/semantics.cc   |  10 +-
 .../g++.dg/cpp23/explicit-obj-diagnostics8.C  |  68 ++
 .../g++.dg/cpp23/explicit-obj-lambda1.C   |  25 +
 .../g++.dg/cpp23/explicit-obj-lambda10.C  |  39 +
 .../g++.dg/cpp23/explicit-obj-lambda11.C  |  46 +
 .../g++.dg/cpp23/explicit-obj-lambda12.C  | 103 +++
 .../g++.dg/cpp23/explicit-obj-lambda13.C  | 103 +++
 .../g++.dg/cpp23/explicit-obj-lambda2.C   |  23 +
 .../g++.dg/cpp23/explicit-obj-lambda3.C   |  64 ++
 .../g++.dg/cpp23/explicit-obj-lambda4.C   |  23 +
 .../g++.dg/cpp23/explicit-obj-lambda5.C   |  21 +
 .../g++.dg/cpp23/explicit-obj-lambda6.C   | 873 ++
 .../g++.dg/cpp23/explicit-obj-lambda7.C   |  20 +
 .../g++.dg/cpp23/explicit-obj-lambda8.C   |  87 ++
 .../g++.dg/cpp23/explicit-obj-lambda9.C   |  46 +
 18 files changed, 1699 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics8.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda1.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda10.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda11.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda12.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda13.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda2.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda3.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda4.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda5.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda6.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda7.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda8.C
 create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda9.C

diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index fc6a0708b66..09a9f148252 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -404,8 +404,10 @@ build_capture_proxy (tree member, tree init)
   fn = lambda_function (closure);
   lam = CLASSTYPE_LAMBDA_EXPR (closure);
 
+  object = DECL_ARGUMENTS (fn);
   /* The proxy variable forwards to the capture field.  */
-  object = build_fold_indirect_ref (DECL_ARGUMENTS (fn));
+  if (INDIRECT_TYPE_P (TREE_TYPE (object)))
+object = build_fold_indirect_ref (object);
   object = finish_non_static_data_member (member, object, NULL_TREE);
   if (REFERENCE_REF_P (object))
 object = TREE_OPERAND (object, 0);
di

Re: [PATCH] libstdc++: Optimize std::is_trivially_destructible_v

2024-01-06 Thread Jonathan Wakely
Pushed to trunk now.

On Thu, 14 Dec 2023 at 01:09, Jonathan Wakely  wrote:
>
> Tested x86_64-linux.
>
> Does this look right? Can we do it faster, or simplify it?
>
> -- >8 --
>
> This reduces the overhead of using std::is_trivially_destructible_v and
> as a result fixes some recent regressions seen with a non-default
> GLIBCXX_TESTSUITE_STDS env var:
> FAIL: 20_util/variant/87619.cc  -std=gnu++20 (test for excess errors)
> FAIL: 20_util/variant/87619.cc  -std=gnu++23 (test for excess errors)
> FAIL: 20_util/variant/87619.cc  -std=gnu++26 (test for excess errors)
>
> libstdc++-v3/ChangeLog:
>
> * include/std/type_traits (is_trivially_destructible_v): Use
> built-in directly when concepts are supported.
> * testsuite/20_util/is_trivially_destructible/value_v.cc: New
> test.
> ---
>  libstdc++-v3/include/std/type_traits  | 19 +
>  .../is_trivially_destructible/value_v.cc  | 40 +++
>  2 files changed, 59 insertions(+)
>  create mode 100644 
> libstdc++-v3/testsuite/20_util/is_trivially_destructible/value_v.cc
>
> diff --git a/libstdc++-v3/include/std/type_traits 
> b/libstdc++-v3/include/std/type_traits
> index 677cd934b94..a0821347676 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -3300,9 +3300,28 @@ template 
>inline constexpr bool is_trivially_move_assignable_v
>  = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
> __add_rval_ref_t<_Tp>);
> +
> +#if __cpp_concepts
> +template 
> +  inline constexpr bool is_trivially_destructible_v = false;
> +
> +template 
> +  requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); }
> +  inline constexpr bool is_trivially_destructible_v<_Tp>
> += __has_trivial_destructor(_Tp);
> +template 
> +  inline constexpr bool is_trivially_destructible_v<_Tp&> = true;
> +template 
> +  inline constexpr bool is_trivially_destructible_v<_Tp&&> = true;
> +template 
> +  inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]>
> += is_trivially_destructible_v<_Tp>;
> +#else
>  template 
>inline constexpr bool is_trivially_destructible_v =
>  is_trivially_destructible<_Tp>::value;
> +#endif
> +
>  template 
>inline constexpr bool is_nothrow_constructible_v
>  = __is_nothrow_constructible(_Tp, _Args...);
> diff --git 
> a/libstdc++-v3/testsuite/20_util/is_trivially_destructible/value_v.cc 
> b/libstdc++-v3/testsuite/20_util/is_trivially_destructible/value_v.cc
> new file mode 100644
> index 000..7db098a2c4d
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/is_trivially_destructible/value_v.cc
> @@ -0,0 +1,40 @@
> +// { dg-do compile { target c++17 } }
> +#include 
> +#include 
> +
> +template
> +constexpr void test_cv()
> +{
> +  static_assert(std::is_trivially_destructible_v
> +  == std::is_trivially_destructible_v);
> +  static_assert(std::is_trivially_destructible_v
> +  == std::is_trivially_destructible_v);
> +  static_assert(std::is_trivially_destructible_v
> +  == std::is_trivially_destructible_v);
> +}
> +
> +template
> +void test()
> +{
> +  static_assert(std::is_trivially_destructible_v == Expected);
> +  test_cv();
> +}
> +
> +void test01()
> +{
> +  using namespace __gnu_test;
> +
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +  test();
> +}
> --
> 2.43.0
>



[committed] libstdc++: Remove dg-timeout-factor from test

2024-01-06 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

As the comment notes, the increased timeout was needed because of PR
102780, but that was fixed long ago.

libstdc++-v3/ChangeLog:

* testsuite/20_util/variant/87619.cc: Remove dg-timeout-factor.
---
 libstdc++-v3/testsuite/20_util/variant/87619.cc | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/20_util/variant/87619.cc 
b/libstdc++-v3/testsuite/20_util/variant/87619.cc
index 2c2fc50037c..45418e16ca8 100644
--- a/libstdc++-v3/testsuite/20_util/variant/87619.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/87619.cc
@@ -16,8 +16,6 @@
 // .
 
 // { dg-do compile { target c++17 } }
-// FIXME: Need increased timeout due to PR c++/102780
-// { dg-timeout-factor 2 { target c++20 } }
 
 #include 
 #include 
-- 
2.43.0



[committed] libstdc++: Avoid conflicting declaration in eh_call.cc [PR112997]

2024-01-06 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

r14-1527-g2415024e0f81f8 changed the parameter of the
__cxa_call_terminate definition, but there's also a declaration in
unwind-cxx.h which should have been changed too.

libstdc++-v3/ChangeLog:

PR libstdc++/112997
* libsupc++/unwind-cxx.h (__cxa_call_terminate): Change first
parameter to void*.
---
 libstdc++-v3/libsupc++/unwind-cxx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h 
b/libstdc++-v3/libsupc++/unwind-cxx.h
index f7eef0da6e2..abc8b808f26 100644
--- a/libstdc++-v3/libsupc++/unwind-cxx.h
+++ b/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -167,7 +167,7 @@ struct __cxa_eh_globals
 // throws, and if bad_exception needs to be thrown.  Called from the
 // compiler.
 extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__));
-extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw ()
+extern "C" void __cxa_call_terminate (void*) throw ()
   __attribute__((__noreturn__));
 
 #ifdef __ARM_EABI_UNWINDER__
-- 
2.43.0



Re: Problems with strub tests

2024-01-06 Thread Hans-Peter Nilsson
On Tue, 19 Dec 2023, Jeff Law wrote:
> 
> So the strub tests in c-c++-common are problematical.  They get run twice,
> once for C, once for C++.  Yet the name of the test is the same in both runs.
> (by the name, I mean the name emitted into the dejagnu summary and log files).
> 
> Thus if you have a test in there which passes in one context, but fails in the
> other, comparison tools like contrib/compare_tests may erroneously report the
> tests as both a test which now fails, but passed before and a test which now
> passes but failed before.
> 
> It looks like some of the strub tests are currently known to fail with C++ and
> are triggering this problem
> 
> 
> Ideally we'd include the c or c++ in the test name depending on which context
> its being run within.  That would be sufficient to resolve these problems and
> avoid them in the future.  It would also be sufficient to get all the tests to
> the point where their behavior is the same for both languages.
> 
> Not sure if the latter is reasonably in the cards or not.  If it's not likely
> to land soon, any change you could look at the framework for c-c++-common and
> get the names unique across the two times they're run?
> 
> A third option would be to change the compare_tests tool to somehow
> distinguish between the C and C++ tests.  Not sure how feasible that is.

How about including the name of the .sum file in the key?

(They're gcc.sum and g++.sum thus different.  This is what 
contrib/regression/btest-gcc.sh does.  On the other hand, that 
prunes the name of the test at the first space.  Don't copy 
that bit. :)

Also not sure how feasible that is.

brgds, H-P


Re: [PATCH 6/4] libbacktrace: Add loaded dlls after initialize

2024-01-06 Thread Eli Zaretskii
> Date: Sat, 6 Jan 2024 23:15:24 +0100
> From: Björn Schäpers 
> Cc: gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
> 
> This patch adds libraries which are loaded after backtrace_initialize, like 
> plugins or similar.
> 
> I don't know what style is preferred for the Win32 typedefs, should the code 
> use 
> PVOID or void*?

It doesn't matter, at least not if the source file includes the
Windows header files (where PVOID is defined).

> +  if (reason != /*LDR_DLL_NOTIFICATION_REASON_LOADED*/1)

IMO, it would be better to supply a #define if undefined:

#ifndef LDR_DLL_NOTIFICATION_REASON_LOADED
# define LDR_DLL_NOTIFICATION_REASON_LOADED 1
#endif

> +  if (!GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
> +   | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
> +   (TCHAR*) notification_data->dll_base,

Is TCHAR correct here? does libbacktrace indeed use TCHAR and relies
on compile-time definition of UNICODE?  (I'm not familiar with the
internals of libbacktrace, so apologies if this is a silly question.)

Thanks.