Re: [PATCH V4] Add warning options -W[no-]compare-distinct-pointer-types

2024-06-17 Thread Jose E. Marchesi


> On Thu, 17 Aug 2023, Jose E. Marchesi via Gcc-patches wrote:
>> [Changes from V3:
> :
>> LLVM supports an option -W[no-]compare-distinct-pointer-types that can
>> be used in order to enable or disable the emission of such warnings.
>
> It looks this went in, alas is not covered in gcc-14/changes.html?
>
> Was that intentional? If not, would you mind considering adding something?

Will do.


Re: [PATCH v4 5/6] bpf,btf: enable BTF pruning by default for BPF

2024-06-12 Thread Jose E. Marchesi


> On 6/12/24 09:55, Jose E. Marchesi wrote:
>> 
>> Hi Faust.
>> Thanks for the patch.
>> Please see a question below.
>> 
>>> This patch enables -gprune-btf by default in the BPF backend when
>>> generating BTF information, and fixes BPF CO-RE generation when using
>>> -gprune-btf.
>>>
>>> When generating BPF CO-RE information, we must ensure that types used
>>> in CO-RE relocations always have sufficient BTF information emited so
>>> that the CO-RE relocations can be processed by a BPF loader.  The BTF
>>> pruning algorithm on its own does not have sufficient information to
>>> determine which types are used in a BPF CO-RE relocation, so this
>>> information must be supplied by the BPF backend, using a new
>>> btf_mark_type_used function.
>>>
>>> Co-authored-by: Cupertino Miranda 
>>>
>>> gcc/
>>> * btfout.cc (btf_mark_type_used): New.
>>> * ctfc.h (btf_mark_type_used): Declare it here.
>>> * config/bpf/bpf.cc (bpf_option_override): Enable -gprune-btf
>>> by default if -gbtf is enabled.
>>> * config/bpf/core-builtins.cc (extra_fn): New typedef.
>>> (compute_field_expr): Add callback parameter, and call it if supplied.
>>> Fix computation for MEM_REF.
>>> (mark_component_type_as_used): New.
>>> (bpf_mark_types_as_used): Likewise.
>>> (bpf_expand_core_builtin): Call here.
>>> * doc/invoke.texi (Debugging Options): Note that -gprune-btf is
>>> enabled by default for BPF target when generating BTF.
>>>
>>> gcc/testsuite/
>>> * gcc.dg/debug/btf/btf-variables-5.c: Adjust one test for bpf-*-*
>>> target.
>>> ---
>>>  gcc/btfout.cc | 22 ++
>>>  gcc/config/bpf/bpf.cc |  5 ++
>>>  gcc/config/bpf/core-builtins.cc   | 71 +--
>>>  gcc/ctfc.h|  1 +
>>>  gcc/doc/invoke.texi   |  3 +
>>>  .../gcc.dg/debug/btf/btf-variables-5.c|  6 +-
>>>  6 files changed, 100 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
>>> index 34d8cec0a2e3..083ca48d6279 100644
>>> --- a/gcc/btfout.cc
>>> +++ b/gcc/btfout.cc
>>> @@ -1503,6 +1503,28 @@ btf_assign_datasec_ids (ctf_container_ref ctfc)
>>>  }
>>>  }
>>>  
>>> +
>>> +/* Manually mark that type T is used to ensure it will not be pruned.
>>> +   Used by the BPF backend when generating BPF CO-RE to mark types used
>>> +   in CO-RE relocations.  */
>>> +
>>> +void
>>> +btf_mark_type_used (tree t)
>>> +{
>>> +  /* If we are not going to prune anyway, this is a no-op.  */
>>> +  if (!debug_prune_btf)
>>> +return;
>>> +
>>> +  gcc_assert (TYPE_P (t));
>>> +  ctf_container_ref ctfc = ctf_get_tu_ctfc ();
>>> +  ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t);
>>> +
>>> +  if (!dtd)
>>> +return;
>>> +
>>> +  btf_add_used_type (ctfc, dtd, false, false, true);
>>> +}
>>> +
>>>  /* Callback used for assembling the only-used-types list.  Note that this 
>>> is
>>> the same as btf_type_list_cb above, but the hash_set traverse requires a
>>> different function signature.  */
>>> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
>>> index dd1bfe38d29b..c62af7a6efa7 100644
>>> --- a/gcc/config/bpf/bpf.cc
>>> +++ b/gcc/config/bpf/bpf.cc
>>> @@ -221,6 +221,11 @@ bpf_option_override (void)
>>>&& !(target_flags_explicit & MASK_BPF_CORE))
>>>  target_flags |= MASK_BPF_CORE;
>>>  
>>> +  /* -gbtf implies -gprune-btf for BPF target.  */
>>> +  if (btf_debuginfo_p ())
>>> +SET_OPTION_IF_UNSET (_options, _options_set,
>>> +debug_prune_btf, true);
>>> +
>>>/* Determine available features from ISA setting (-mcpu=).  */
>>>if (bpf_has_jmpext == -1)
>>>  bpf_has_jmpext = (bpf_isa >= ISA_V2);
>>> diff --git a/gcc/config/bpf/core-builtins.cc 
>>> b/gcc/config/bpf/core-builtins.cc
>>> index 232bebcadbd5..86e2e9d6e39f 100644
>>> --- a/gcc/config/bpf/core-builtins.cc
>>> +++ b/gcc/config/bpf/core-builtins.cc
>>> @@ -624,13 +624,20 @@ bpf_core_get_index (const tree node, bool *valid)
>>>  
>>

Re: [PATCH v4 5/6] bpf,btf: enable BTF pruning by default for BPF

2024-06-12 Thread Jose E. Marchesi


Hi Faust.
Thanks for the patch.
Please see a question below.

> This patch enables -gprune-btf by default in the BPF backend when
> generating BTF information, and fixes BPF CO-RE generation when using
> -gprune-btf.
>
> When generating BPF CO-RE information, we must ensure that types used
> in CO-RE relocations always have sufficient BTF information emited so
> that the CO-RE relocations can be processed by a BPF loader.  The BTF
> pruning algorithm on its own does not have sufficient information to
> determine which types are used in a BPF CO-RE relocation, so this
> information must be supplied by the BPF backend, using a new
> btf_mark_type_used function.
>
> Co-authored-by: Cupertino Miranda 
>
> gcc/
>   * btfout.cc (btf_mark_type_used): New.
>   * ctfc.h (btf_mark_type_used): Declare it here.
>   * config/bpf/bpf.cc (bpf_option_override): Enable -gprune-btf
>   by default if -gbtf is enabled.
>   * config/bpf/core-builtins.cc (extra_fn): New typedef.
>   (compute_field_expr): Add callback parameter, and call it if supplied.
>   Fix computation for MEM_REF.
>   (mark_component_type_as_used): New.
>   (bpf_mark_types_as_used): Likewise.
>   (bpf_expand_core_builtin): Call here.
>   * doc/invoke.texi (Debugging Options): Note that -gprune-btf is
>   enabled by default for BPF target when generating BTF.
>
> gcc/testsuite/
>   * gcc.dg/debug/btf/btf-variables-5.c: Adjust one test for bpf-*-*
>   target.
> ---
>  gcc/btfout.cc | 22 ++
>  gcc/config/bpf/bpf.cc |  5 ++
>  gcc/config/bpf/core-builtins.cc   | 71 +--
>  gcc/ctfc.h|  1 +
>  gcc/doc/invoke.texi   |  3 +
>  .../gcc.dg/debug/btf/btf-variables-5.c|  6 +-
>  6 files changed, 100 insertions(+), 8 deletions(-)
>
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 34d8cec0a2e3..083ca48d6279 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -1503,6 +1503,28 @@ btf_assign_datasec_ids (ctf_container_ref ctfc)
>  }
>  }
>  
> +
> +/* Manually mark that type T is used to ensure it will not be pruned.
> +   Used by the BPF backend when generating BPF CO-RE to mark types used
> +   in CO-RE relocations.  */
> +
> +void
> +btf_mark_type_used (tree t)
> +{
> +  /* If we are not going to prune anyway, this is a no-op.  */
> +  if (!debug_prune_btf)
> +return;
> +
> +  gcc_assert (TYPE_P (t));
> +  ctf_container_ref ctfc = ctf_get_tu_ctfc ();
> +  ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t);
> +
> +  if (!dtd)
> +return;
> +
> +  btf_add_used_type (ctfc, dtd, false, false, true);
> +}
> +
>  /* Callback used for assembling the only-used-types list.  Note that this is
> the same as btf_type_list_cb above, but the hash_set traverse requires a
> different function signature.  */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index dd1bfe38d29b..c62af7a6efa7 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -221,6 +221,11 @@ bpf_option_override (void)
>&& !(target_flags_explicit & MASK_BPF_CORE))
>  target_flags |= MASK_BPF_CORE;
>  
> +  /* -gbtf implies -gprune-btf for BPF target.  */
> +  if (btf_debuginfo_p ())
> +SET_OPTION_IF_UNSET (_options, _options_set,
> +  debug_prune_btf, true);
> +
>/* Determine available features from ISA setting (-mcpu=).  */
>if (bpf_has_jmpext == -1)
>  bpf_has_jmpext = (bpf_isa >= ISA_V2);
> diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
> index 232bebcadbd5..86e2e9d6e39f 100644
> --- a/gcc/config/bpf/core-builtins.cc
> +++ b/gcc/config/bpf/core-builtins.cc
> @@ -624,13 +624,20 @@ bpf_core_get_index (const tree node, bool *valid)
>  
> ALLOW_ENTRY_CAST is an input arguments and specifies if the function 
> should
> consider as valid expressions in which NODE entry is a cast expression (or
> -   tree code nop_expr).  */
> +   tree code nop_expr).
> +
> +   EXTRA_FN is a callback function to allow extra functionality with this
> +   function traversal.  Currently used for marking used type during expand
> +   pass.  */
> +
> +typedef void (*extra_fn) (tree);
>  
>  static unsigned char
>  compute_field_expr (tree node, unsigned int *accessors,
>   bool *valid,
>   tree *access_node,
> - bool allow_entry_cast = true)
> + bool allow_entry_cast = true,
> + extra_fn callback = NULL)
>  {
>unsigned char n = 0;
>unsigned int fake_accessors[MAX_NR_ACCESSORS];
> @@ -647,6 +654,9 @@ compute_field_expr (tree node, unsigned int *accessors,
>  
>*access_node = node;
>  
> +  if (callback != NULL)
> +callback (node);
> +
>switch (TREE_CODE (node))
>  {
>  case INDIRECT_REF:
> @@ -664,17 +674,19 @@ compute_field_expr (tree node, unsigned int *accessors,
>  case 

[COMMITTED BPF] bpf: fix printing of memory operands in pseudoc asm dialect

2024-05-10 Thread Jose E. Marchesi
The BPF backend was emitting memory operands in pseudo-C syntax
without surrounding parentheses.  These were being provided in the
corresponding instruction templates.

This was causing GCC emitting invalid instructions when finding inline
assembly with memory operands like:

asm volatile (
"r1 = *(u64 *)%[ctx_a];"
"if r1 != 42 goto 1f;"
"r1 = *(u64 *)%[ctx_b];"
"if r1 != 42 goto 1f;"
"r1 = *(u64 *)%[ctx_c];"
"if r1 != 7 goto 1f;"
"r1 /= 0;"
"1:"
:
: [ctx_a]"m"(ctx.a),
  [ctx_b]"m"(ctx.b),
  [ctx_c]"m"(ctx.c)
: "r1"
);

This patch changes the backend to include the surrounding parentheses
in the printed representation of the memory operands (much like
surrounding brackets are included in normal asm syntax) and adapts the
impacted instruction templates accordingly.

Tested in target bpf-unknown-none, host x86_64-linux-gnu.

gcc/ChangeLog:

* config/bpf/bpf.cc (bpf_print_operand_address): Include
surrounding parenthesis around mem operands in pseudoc asm
dialect.
* config/bpf/bpf.md (*mov): Adapt accordingly.
(zero_extendhidi2): Likewise.
(zero_extendqidi2): Likewise.
(*extendsidi2): Likewise.
(*extendsidi2): Likewise.
(extendhidi2): Likewise.
(extendqidi2): Likewise.
(extendhisi2): Likewise.
* config/bpf/atomic.md (atomic_add): Likewise.
(atomic_and): Likewise.
(atomic_or): Likewise.
(atomic_xor): Likewise.
(atomic_fetch_add): Likewise.
(atomic_fetch_and): Likewise.
(atomic_fetch_or): Likewise.
(atomic_fetch_xor): Likewise.
---
 gcc/config/bpf/atomic.md | 16 
 gcc/config/bpf/bpf.cc| 11 ---
 gcc/config/bpf/bpf.md| 18 +-
 3 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/gcc/config/bpf/atomic.md b/gcc/config/bpf/atomic.md
index 4c131cad8a3..65bd5f266a1 100644
--- a/gcc/config/bpf/atomic.md
+++ b/gcc/config/bpf/atomic.md
@@ -34,7 +34,7 @@ (define_insn "atomic_add"
   (match_operand:SI 2 "const_int_operand")] ;; Memory model.
  UNSPEC_AADD))]
   ""
-  "{xadd\t%0,%1|lock *( *)(%w0) += %w1}"
+  "{xadd\t%0,%1|lock *( *)%w0 += %w1}"
   [(set_attr "type" "atomic")])
 
 (define_insn "atomic_and"
@@ -45,7 +45,7 @@ (define_insn "atomic_and"
   (match_operand:SI 2 "const_int_operand")] ;; Memory model.
  UNSPEC_AAND))]
   "bpf_has_v3_atomics"
-  "{aand\t%0,%1|lock *( *)(%w0) &= %w1}")
+  "{aand\t%0,%1|lock *( *)%w0 &= %w1}")
 
 (define_insn "atomic_or"
   [(set (match_operand:AMO 0 "memory_operand" "+m")
@@ -55,7 +55,7 @@ (define_insn "atomic_or"
   (match_operand:SI 2 "const_int_operand")] ;; Memory model.
  UNSPEC_AOR))]
   "bpf_has_v3_atomics"
-  "{aor\t%0,%1|lock *( *)(%w0) %|= %w1}")
+  "{aor\t%0,%1|lock *( *)%w0 %|= %w1}")
 
 (define_insn "atomic_xor"
   [(set (match_operand:AMO 0 "memory_operand" "+m")
@@ -65,7 +65,7 @@ (define_insn "atomic_xor"
   (match_operand:SI 2 "const_int_operand")] ;; Memory model.
  UNSPEC_AXOR))]
   "bpf_has_v3_atomics"
-  "{axor\t%0,%1|lock *( *)(%w0) ^= %w1}")
+  "{axor\t%0,%1|lock *( *)%w0 ^= %w1}")
 
 ;;; Feching (read-modify-store) versions of atomic operations.
 
@@ -79,7 +79,7 @@ (define_insn "atomic_fetch_add"
   (match_operand:AMO 3 "const_int_operand")] ;; Memory model
 UNSPEC_AFADD))]
   "bpf_has_v3_atomics"
-  "{afadd\t%1,%0|%w0 = atomic_fetch_add(( *)(%1), %w0)}")
+  "{afadd\t%1,%0|%w0 = atomic_fetch_add(( *)%1, %w0)}")
 
 (define_insn "atomic_fetch_and"
   [(set (match_operand:AMO 0 "register_operand" "=r")
@@ -91,7 +91,7 @@ (define_insn "atomic_fetch_and"
   (match_operand:AMO 3 "const_int_operand")]
  UNSPEC_AFAND))]
   "bpf_has_v3_atomics"
-  "{afand\t%1,%0|%w0 = atomic_fetch_and(( *)(%1), %w0)}")
+  "{afand\t%1,%0|%w0 = atomic_fetch_and(( *)%1, %w0)}")
 
 (define_insn "atomic_fetch_or"
   [(set (match_operand:AMO 0 "register_operand" "=r")
@@ -103,7 +103,7 @@ (define_insn "atomic_fetch_or"
   (match_operand:AMO 3 "const_int_operand")]
  UNSPEC_AFOR))]
   "bpf_has_v3_atomics"
-  "{afor\t%1,%0|%w0 = atomic_fetch_or(( *)(%1), %w0)}")
+  "{afor\t%1,%0|%w0 = atomic_fetch_or(( *)%1, %w0)}")
 
 (define_insn "atomic_fetch_xor"
   [(set (match_operand:AMO 0 "register_operand" "=r")
@@ -115,7 +115,7 @@ (define_insn "atomic_fetch_xor"
   (match_operand:AMO 3 "const_int_operand")]
  UNSPEC_AFXOR))]
   "bpf_has_v3_atomics"
-  "{afxor\t%1,%0|%w0 = atomic_fetch_xor(( *)(%1), %w0)}")
+  "{afxor\t%1,%0|%w0 = atomic_fetch_xor(( *)%1, %w0)}")
 
 ;; Weird suffixes used in pseudo-c atomic compare-exchange insns.
 (define_mode_attr pcaxsuffix [(SI "32_32") (DI "_64")])
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index e6ea211a2c6..dd1bfe38d29 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -894,10 

Re: [PATCH] bpf: set PREFERRED_DEBUGGING_TYPE to BTF_DEBUG

2024-04-25 Thread Jose E. Marchesi


Hi David.
OK.  Thanks for the patch.

> BTF is the standard debug info used with BPF programs, so it makes sense
> to default to BTF rather than DWARF.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/
>   * config/bpf/bpf.h (PREFERRED_DEBUGGING_TYPE): Set to BTF_DEBUG.
>
> gcc/testsuite/
>   * gcc.target/bpf/bpf-debug-options-1.c: New test.
>   * gcc.target/bpf/bpf-debug-options-2.c: Likewise.
>   * gcc.target/bpf/bpf-debug-options-3.c: Likewise.
>   * gcc.target/bpf/core-options-4.c: Likewise.
> ---
>  gcc/config/bpf/bpf.h   |  5 +
>  .../gcc.target/bpf/bpf-debug-options-1.c   | 17 +
>  .../gcc.target/bpf/bpf-debug-options-2.c   | 18 ++
>  .../gcc.target/bpf/bpf-debug-options-3.c   | 14 ++
>  gcc/testsuite/gcc.target/bpf/core-options-4.c  |  4 
>  5 files changed, 58 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-options-4.c
>
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index c67e17526bf..e163fbf688d 100644
> --- a/gcc/config/bpf/bpf.h
> +++ b/gcc/config/bpf/bpf.h
> @@ -245,6 +245,11 @@ enum reg_class
>  
>  / Debugging Info /
>  
> +/* Use BTF debug info by default.  */
> +
> +#undef  PREFERRED_DEBUGGING_TYPE
> +#define PREFERRED_DEBUGGING_TYPE BTF_DEBUG
> +
>  /* In eBPF it is not possible to unwind frames. Disable CFA.  */
>  
>  #define DWARF2_FRAME_INFO 0
> diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c 
> b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c
> new file mode 100644
> index 000..409466c4ead
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c
> @@ -0,0 +1,17 @@
> +/* Default to BTF debug info.  */
> +/* { dg-do compile } */
> +/* { dg-options "-g -dA" }*/
> +
> +struct A {
> +  int x;
> +  int y;
> +};
> +
> +int
> +foo (struct A *a)
> +{
> +  return a->x;
> +}
> +
> +/* { dg-final { scan-assembler-not "DWARF version" } } */
> +/* { dg-final { scan-assembler "btf_version" } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c 
> b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c
> new file mode 100644
> index 000..03bde12315b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c
> @@ -0,0 +1,18 @@
> +/* -g defaults to BTF, which in turn implies -mco-re.  */
> +/* { dg-do compile } */
> +/* { dg-options "-g -dA" }*/
> +
> +struct A {
> +  int x;
> +  int y;
> +};
> +
> +int
> +foo (struct A *a)
> +{
> +  return __builtin_preserve_access_index (a->x);
> +}
> +
> +/* { dg-final { scan-assembler-not "DWARF version" } } */
> +/* { dg-final { scan-assembler "btf_version" } } */
> +/* { dg-final { scan-assembler "btfext_version" } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c 
> b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c
> new file mode 100644
> index 000..d41790e0928
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c
> @@ -0,0 +1,14 @@
> +/* Using -g does not incorrectly force CO-RE enabled.  */
> +/* { dg-do compile } */
> +/* { dg-options "-g -dA -mno-co-re" }*/
> +
> +struct A {
> +  int x;
> +  int y;
> +};
> +
> +int
> +foo (struct A *a)
> +{
> +  return __builtin_preserve_access_index (a->x); /* { dg-error "BPF CO-RE is 
> required" } */
> +}
> diff --git a/gcc/testsuite/gcc.target/bpf/core-options-4.c 
> b/gcc/testsuite/gcc.target/bpf/core-options-4.c
> new file mode 100644
> index 000..fde4195da42
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-options-4.c
> @@ -0,0 +1,4 @@
> +/* -g implies BTF, -gtoggle turns it off.  CO-RE should not work.  */
> +/* { dg-do compile } */
> +/* { dg-options "-g -mco-re -gtoggle" } */
> +/* { dg-excess-errors "BPF CO-RE requires BTF debugging information" } */


Re: [PATCH] bpf: avoid issues with CO-RE and -gtoggle

2024-04-25 Thread Jose E. Marchesi


Hi Faust.
OK.  Thanks for the patch.

> Compiling a BPF program with CO-RE relocations (and BTF) while also
> passing -gtoggle led to an inconsistent state where CO-RE support was
> enabled but BTF would not be generated, and this was not caught by the
> existing option parsing.  This led to an ICE when generating the CO-RE
> relocation info, since BTF is required for CO-RE.
>
> Update bpf_option_override to avoid this case, and add a few tests for
> the interactions of these options.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/
>   * config/bpf/bpf.cc (bpf_option_override): Improve handling of CO-RE
>   options to avoid issues with -gtoggle.
>
> gcc/testsuite/
>   * gcc.target/bpf/core-options-1.c: New test.
>   * gcc.target/bpf/core-options-2.c: Likewise.
>   * gcc.target/bpf/core-options-3.c: Likewise.
> ---
>  gcc/config/bpf/bpf.cc |  7 +--
>  gcc/testsuite/gcc.target/bpf/core-options-1.c | 15 +++
>  gcc/testsuite/gcc.target/bpf/core-options-2.c | 14 ++
>  gcc/testsuite/gcc.target/bpf/core-options-3.c |  5 +
>  4 files changed, 39 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-options-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-options-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-options-3.c
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 98fb755bb8b..e6ea211a2c6 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -192,7 +192,8 @@ bpf_option_override (void)
>init_machine_status = bpf_init_machine_status;
>  
>/* BPF CO-RE support requires BTF debug info generation.  */
> -  if (TARGET_BPF_CORE && !btf_debuginfo_p ())
> +  if (TARGET_BPF_CORE
> +  && (!btf_debuginfo_p () || (debug_info_level < DINFO_LEVEL_NORMAL)))
>  error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>");
>  
>/* BPF applications always generate .BTF.ext.  */
> @@ -215,7 +216,9 @@ bpf_option_override (void)
>  
>/* -gbtf implies -mcore when using the BPF backend, unless -mno-co-re
>   is specified.  */
> -  if (btf_debuginfo_p () && !(target_flags_explicit & MASK_BPF_CORE))
> +  if (btf_debuginfo_p ()
> +  && (debug_info_level >= DINFO_LEVEL_NORMAL)
> +  && !(target_flags_explicit & MASK_BPF_CORE))
>  target_flags |= MASK_BPF_CORE;
>  
>/* Determine available features from ISA setting (-mcpu=).  */
> diff --git a/gcc/testsuite/gcc.target/bpf/core-options-1.c 
> b/gcc/testsuite/gcc.target/bpf/core-options-1.c
> new file mode 100644
> index 000..7d8c677f239
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-options-1.c
> @@ -0,0 +1,15 @@
> +/* -gbtf for the BPF target should enable CO-RE support automatically.  */
> +/* { dg-do compile } */
> +/* { dg-options "-gbtf" } */
> +
> +struct A {
> +  int x;
> +  int y;
> +  char c;
> +};
> +
> +int
> +foo (struct A *a) {
> +  int y = __builtin_preserve_access_index (a->y);
> +  return y;
> +}
> diff --git a/gcc/testsuite/gcc.target/bpf/core-options-2.c 
> b/gcc/testsuite/gcc.target/bpf/core-options-2.c
> new file mode 100644
> index 000..8f466258e29
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-options-2.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-gbtf -gtoggle" } */
> +
> +struct A {
> +  int x;
> +  int y;
> +  char c;
> +};
> +
> +int
> +foo (struct A *a) {
> +  int y = __builtin_preserve_access_index (a->y); /* { dg-error "BPF CO-RE 
> is required" } */
> +  return y;
> +}
> diff --git a/gcc/testsuite/gcc.target/bpf/core-options-3.c 
> b/gcc/testsuite/gcc.target/bpf/core-options-3.c
> new file mode 100644
> index 000..ca32a7c4012
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-options-3.c
> @@ -0,0 +1,5 @@
> +/* This combination of options tries to enable CO-RE without BTF, and should
> +   produce an error.  */
> +/* { dg-do compile } */
> +/* { dg-options "-gbtf -gtoggle -mco-re" } */
> +/* { dg-excess-errors "BPF CO-RE requires BTF debugging information" } */


[COMMITTED BPF] bpf: default to using pseudo-C assembly syntax by default

2024-04-25 Thread Jose E. Marchesi
At this point the kernel headers that almost all BPF programs use
contain pseudo-C inline assembly and having the GNU toolchain using
the conventional assembly syntax by default would force users to
specify the command-line option explicitly almost all of the time,
which is very inconvenient.

This patch changes GCC in order to recognize and generate the pseudo-C
assembly syntax of BPF by default.  The ASM_SPEC is adapted
accordingly, and in a way that the current release of the BPF
assembler (which still expects conventional assembler syntax by
default) does the right thing.

Tested in bpf-unknown-none-bpf target and x86_64-linux-gnu host.
No regressions.

gcc/ChangeLog

* config/bpf/bpf.opt: Use ASM_PSEUDOC for the default value of
-masm.
* config/bpf/bpf.h (ASM_SPEC): Adapt accordingly.
* doc/invoke.texi (eBPF Options): Update.

gcc/testsuite/ChangeLog

* gcc.target/bpf/alu-1.c: Specify conventional asm dialect.
* gcc.target/bpf/xbpf-indirect-call-1.c: Likewise.
* gcc.target/bpf/sync-fetch-and-add.c: Likewise.
* gcc.target/bpf/smov-2.c: Likewise.
* gcc.target/bpf/smov-1.c: Likewise.
* gcc.target/bpf/smod-1.c: Likewise.
* gcc.target/bpf/sload-1.c: Likewise.
* gcc.target/bpf/sdiv-1.c: Likewise.
* gcc.target/bpf/nop-1.c: Likewise.
* gcc.target/bpf/neg-1.c: Likewise.
* gcc.target/bpf/ldxdw.c: Likewise.
* gcc.target/bpf/jmp-1.c: Likewise.
* gcc.target/bpf/inline-memops-threshold-1.c: Likewise.
* gcc.target/bpf/float-1.c: Likewise.
* gcc.target/bpf/double-2.c: Likewise.
* gcc.target/bpf/double-1.c: Likewise.
* gcc.target/bpf/core-builtin-type-id.c: Likewise.
* gcc.target/bpf/core-builtin-type-based.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-size-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-sign-2.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-sign-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-rshift-2.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-rshift-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-offset-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-lshift-2.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-lshift-1-le.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-lshift-1-be.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-existence-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-errors-2.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-errors-1.c: Likewise.
* gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c:
Likewise.
* gcc.target/bpf/core-builtin-exprlist-4.c: Likewise.
* gcc.target/bpf/core-builtin-exprlist-3.c: Likewise.
* gcc.target/bpf/core-builtin-exprlist-2.c: Likewise.
* gcc.target/bpf/core-builtin-exprlist-1.c: Likewise.
* gcc.target/bpf/core-builtin-enumvalue-opt.c: Likewise.
* gcc.target/bpf/core-builtin-enumvalue-errors.c: Likewise.
* gcc.target/bpf/core-builtin-enumvalue.c: Likewise.
* gcc.target/bpf/core-builtin-3.c: Likewise.
* gcc.target/bpf/core-builtin-2.c: Likewise.
* gcc.target/bpf/core-builtin-1.c: Likewise.
* gcc.target/bpf/core-attr-struct-as-array.c: Likewise.
* gcc.target/bpf/core-attr-6.c: Likewise.
* gcc.target/bpf/core-attr-5.c: Likewise.
* gcc.target/bpf/core-attr-4.c: Likewise.
* gcc.target/bpf/core-attr-3.c: Likewise.
* gcc.target/bpf/core-attr-2.c: Likewise.
* gcc.target/bpf/core-attr-1.c: Likewise.
* gcc.target/bpf/builtin-load.c: Likewise.
* gcc.target/bpf/btfext-funcinfo-nocore.c: Likewise.
* gcc.target/bpf/btfext-funcinfo.c: Likewise.
* gcc.target/bpf/bswap-1.c: Likewise.
* gcc.target/bpf/bswap-2.c: Likewise.
* gcc.target/bpf/attr-kernel-helper.c: Likewise.
* gcc.target/bpf/atomic-xchg-2.c: Likewise.
* gcc.target/bpf/atomic-xchg-1.c: Likewise.
* gcc.target/bpf/atomic-op-3.c: Likewise.
* gcc.target/bpf/atomic-op-2.c: Likewise.
* gcc.target/bpf/atomic-op-1.c: Likewise.
* gcc.target/bpf/atomic-fetch-op-3.c: Likewise.
* gcc.target/bpf/atomic-fetch-op-2.c: Likewise.
* gcc.target/bpf/atomic-fetch-op-1.c: Likewise.
* gcc.target/bpf/atomic-cmpxchg-2.c: Likewise.
* gcc.target/bpf/atomic-cmpxchg-1.c: Likewise.
* gcc.target/bpf/alu-2.c: Likewise.
---
 gcc/config/bpf/bpf.h  | 4 +++-
 gcc/config/bpf/bpf.opt| 2 +-
 gcc/doc/invoke.texi   | 2 +-
 gcc/testsuite/gcc.target/bpf/alu-1.c  | 2 +-
 gcc/testsuite/gcc.target/bpf/alu-2.c  | 2 +-
 

[COMMITTED BPF] bpf: define BPF feature pre-processor macros

2024-04-24 Thread Jose E. Marchesi
This commit makes the BPF backend to define the following macros for
c-family languages:

  __BPF_CPU_VERSION__

This is a numeric value identifying the version of the BPF "cpu"
for which GCC is generating code.

  __BPF_FEATURE_ALU32
  __BPF_FEATURE_JMP32
  __BPF_FEATURE_JMP_EXT
  __BPF_FEATURE_BSWAP
  __BPF_FEATURE_SDIV_SMOD
  __BPF_FEATURE_MOVSX
  __BPF_FEATURE_LDSX
  __BPF_FEATURE_GOTOL
  __BPF_FEATURE_ST

These are defines if the corresponding "feature" is enabled.  The
features are implicitly enabled by the BPF CPU version enabled,
and most of them can also be enabled/disabled using
target-specific -m[no-]FEATURE command line switches.

Note that this patch moves the definition of bpf_target_macros, that
implements TARGET_CPU_CPP_BUILTINS in the BPF backend, to a bpf-c.cc
file.  This is because we are now using facilities from c-family/* and
these features are not available in compilers like lto1.

A couple of tests are also added.
Tested in target bpf-unknown-none-gcc and host x86_64-linux-gnu.
No regressions.

gcc/ChangeLog

* config.gcc: Add bpf-c.o as a target object for C and C++.
* config/bpf/bpf.cc (bpf_target_macros): Move to bpf-c.cc.
* config/bpf/bpf-c.cc: New file.
(bpf_target_macros): Move from bpf.cc and define BPF CPU
feature macros.
* config/bpf/t-bpf: Add rules to build bpf-c.o.

gcc/testsuite/ChangeLog

* gcc.target/bpf/feature-macro-1.c: New test.
* gcc.target/bpf/feature-macro-2.c: Likewise.
---
 gcc/config.gcc|  2 +
 gcc/config/bpf/bpf-c.cc   | 88 +++
 gcc/config/bpf/bpf.cc | 17 
 gcc/config/bpf/t-bpf  |  4 +
 .../gcc.target/bpf/feature-macro-1.c  | 34 +++
 .../gcc.target/bpf/feature-macro-2.c  | 14 +++
 6 files changed, 142 insertions(+), 17 deletions(-)
 create mode 100644 gcc/config/bpf/bpf-c.cc
 create mode 100644 gcc/testsuite/gcc.target/bpf/feature-macro-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/feature-macro-2.c

diff --git a/gcc/config.gcc b/gcc/config.gcc
index ce683adcc8a..c2764095f0c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -394,6 +394,8 @@ bfin*-*)
;;
 bpf-*-*)
cpu_type=bpf
+   c_target_objs="bpf-c.o"
+   cxx_target_objs="bpf-c.o"
;;
 frv*)  cpu_type=frv
extra_options="${extra_options} g.opt"
diff --git a/gcc/config/bpf/bpf-c.cc b/gcc/config/bpf/bpf-c.cc
new file mode 100644
index 000..f12f0627103
--- /dev/null
+++ b/gcc/config/bpf/bpf-c.cc
@@ -0,0 +1,88 @@
+/* BPF-specific code for C family languages.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   Contributed by Oracle Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+
+/* Define target-specific CPP macros.  This function in used in the
+   definition of TARGET_CPU_CPP_BUILTINS in bpf.h */
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+
+void
+bpf_target_macros (cpp_reader *pfile)
+{
+  builtin_define ("__BPF__");
+  builtin_define ("__bpf__");
+
+  if (TARGET_BIG_ENDIAN)
+builtin_define ("__BPF_BIG_ENDIAN__");
+  else
+builtin_define ("__BPF_LITTLE_ENDIAN__");
+
+  switch (bpf_isa)
+{
+case ISA_V1:
+  builtin_define_with_int_value ("__BPF_CPU_VERSION__", 1);
+  break;
+case ISA_V2:
+  builtin_define_with_int_value ("__BPF_CPU_VERSION__", 2);
+  break;
+case ISA_V3:
+  builtin_define_with_int_value ("__BPF_CPU_VERSION__", 3);
+  break;
+case ISA_V4:
+  builtin_define_with_int_value ("__BPF_CPU_VERSION__", 4);
+  break;
+default:
+  gcc_unreachable ();
+  break;
+}
+
+  /* Different BPF CPU versions support different features.  Some of
+ them can be enabled/disabled explicitly.  */
+  if (bpf_has_alu32)
+builtin_define ("__BPF_FEATURE_ALU32");
+  if (bpf_has_jmp32)
+builtin_define ("__BPF_FEATURE_JMP32");
+  if (bpf_has_jmpext)
+builtin_define ("__BPF_FEATURE_JMP_EXT");
+  if (bpf_has_bswap)
+builtin_define ("__BPF_FEATURE_BSWAP");
+  if (bpf_has_sdiv)
+builtin_define ("__BPF_FEATURE_SDIV_SMOD");
+  if (bpf_has_smov)
+builtin_define ("__BPF_FEATURE_MOVSX");

Re: [PATCH 3/3] bpf: add line_info support to BTF.ext section.

2024-04-17 Thread Jose E. Marchesi


>> Jose E. Marchesi writes:
>>
>>> Hi Cuper.
>>> Thanks for the patch.
>>>
>>>> This patch adds line_info debug information support to .BTF.ext
>>>> sections.
>>>> Line info information is used by the BPF verifier to improve error
>>>> reporting and give more precise source core referenced errors.
>>>>
>>>> gcc/Changelog:
>>>>* config/bpf/bpf-protos.h (bpf_output_call): Change prototype.
>>>>* config/bpf/bpf.cc (bpf_output_call): Change to adapt operands
>>>>and return
>>>>the instruction template instead of emmidiatelly emit asm and
>>>>not allow proper final expected execution flow.
>>>>(bpf_output_line_info): Add function to introduce line info
>>>>entries in respective structures
>>>>(bpf_asm_out_unwind_emit): Add function as hook to
>>>>TARGET_ASM_UNWIND_EMIT. This hook is called before any
>>>>instruction is emitted.
>>>
>>> Is it actually necessary to emit a label (plus .BTF.ext entry) for every
>>> instruction?
>> Maybe BPF would be Ok (not complaining of missing line_info) with just a
>> single entry per function pointing to the entry instruction. That
>> is not what clang does. Don't know if it emits any labels either.
>>
>> It is probably possible to add some logic to compute the offset from
>> the function label and emit with an offset to the instruction
>> location.  In case of inline assembly we could add a symbol after, and
>> restart offset computation.  It will need to add code to compute the
>> instruction encoding size, and increment function label offset each
>> time we emit an instruction.
>>
>> Still, my personal preference is to create those labels to properly
>> compute instruction location then some rather intricate solution that
>> would lead to future complications.  I know BPF is not like all the
>> other targets, but I am thinking of assembly/linker relaxation.
>>
>> WDYT ?
>
> What I meant is: if it is not required to emit a line_info entry for
> _every_ BPF instruction, but only for the instructions that "change" the
> current location, then we better do so?
>
> Then, regarding the labels, I assume their purpose is to get the
> assembler to fill in the `insn_off' field of the bpf_line_info in the
> .BTF.ext section:
>
> struct bpf_line_info {
> __u32   insn_off; /* [0, insn_cnt - 1] */
> __u32   file_name_off; /* offset to string table for the filename */
> __u32   line_off; /* offset to string table for the source line */
> __u32   line_col; /* line number and column number */
> };
>
> Which makes sense, since "instruction offset" is really the business of
> the assembler, not the compiler.  I agree with you making it the
> compiler's business would be overcomplicated, given inline assembly and
> variable-sized BPF instructions...
>
> So, what about moving the task of creating these line_info entries
> entirely to the assembler?  GCC already knows how to emit .file and .loc
> directives to track location info in DWARF.
>
> The BPF assembler could then process these and create entries in
> .BTF.ext for line_info, all the fields above: insn_off, file_name_off,
> line_off and line_col.

Regarding file_name_off, hopefully it will be possible to make the
assembler to simply expand the string table in .BTF (with the strings
read from .file directives) without having to understand/redo the whole
BTF section...

>>>>* config/bpf/bpf.md: Change calls to bpf_output_call.
>>>>* config/bpf/btfext-out.cc (struct btf_ext_lineinfo): Add fields
>>>>to struct.
>>>>(bpf_create_lineinfo, btf_add_line_info_for): Add support
>>>>function to insert line_info data in respective structures.
>>>>(output_btfext_line_info): Function to emit line_info data in
>>>>.BTF.ext section.
>>>>(btf_ext_output): Call output_btfext_line_info.
>>>>* config/bpf/btfext-out.h: Add prototype for
>>>>btf_add_line_info_for.
>>>> ---
>>>>  gcc/config/bpf/bpf-protos.h   |   2 +-
>>>>  gcc/config/bpf/bpf.cc | 103 ++---
>>>>  gcc/config/bpf/bpf.md |   4 +-
>>>>  gcc/config/bpf/btfext-out.cc  | 108 +-
>>>>  gcc/config/bpf/btfext-out.h   |   4 +
>>>>  .../gcc.target/bpf/btfext-funcinfo.c  |   3 +-
>>>>  6 

Re: [PATCH 3/3] bpf: add line_info support to BTF.ext section.

2024-04-17 Thread Jose E. Marchesi


> Jose E. Marchesi writes:
>
>> Hi Cuper.
>> Thanks for the patch.
>>
>>> This patch adds line_info debug information support to .BTF.ext
>>> sections.
>>> Line info information is used by the BPF verifier to improve error
>>> reporting and give more precise source core referenced errors.
>>>
>>> gcc/Changelog:
>>> * config/bpf/bpf-protos.h (bpf_output_call): Change prototype.
>>> * config/bpf/bpf.cc (bpf_output_call): Change to adapt operands
>>> and return
>>> the instruction template instead of emmidiatelly emit asm and
>>> not allow proper final expected execution flow.
>>> (bpf_output_line_info): Add function to introduce line info
>>> entries in respective structures
>>> (bpf_asm_out_unwind_emit): Add function as hook to
>>> TARGET_ASM_UNWIND_EMIT. This hook is called before any
>>> instruction is emitted.
>>
>> Is it actually necessary to emit a label (plus .BTF.ext entry) for every
>> instruction?
> Maybe BPF would be Ok (not complaining of missing line_info) with just a
> single entry per function pointing to the entry instruction. That
> is not what clang does. Don't know if it emits any labels either.
>
> It is probably possible to add some logic to compute the offset from
> the function label and emit with an offset to the instruction
> location.  In case of inline assembly we could add a symbol after, and
> restart offset computation.  It will need to add code to compute the
> instruction encoding size, and increment function label offset each
> time we emit an instruction.
>
> Still, my personal preference is to create those labels to properly
> compute instruction location then some rather intricate solution that
> would lead to future complications.  I know BPF is not like all the
> other targets, but I am thinking of assembly/linker relaxation.
>
> WDYT ?

What I meant is: if it is not required to emit a line_info entry for
_every_ BPF instruction, but only for the instructions that "change" the
current location, then we better do so?

Then, regarding the labels, I assume their purpose is to get the
assembler to fill in the `insn_off' field of the bpf_line_info in the
.BTF.ext section:

struct bpf_line_info {
__u32   insn_off; /* [0, insn_cnt - 1] */
__u32   file_name_off; /* offset to string table for the filename */
__u32   line_off; /* offset to string table for the source line */
__u32   line_col; /* line number and column number */
};

Which makes sense, since "instruction offset" is really the business of
the assembler, not the compiler.  I agree with you making it the
compiler's business would be overcomplicated, given inline assembly and
variable-sized BPF instructions...

So, what about moving the task of creating these line_info entries
entirely to the assembler?  GCC already knows how to emit .file and .loc
directives to track location info in DWARF.

The BPF assembler could then process these and create entries in
.BTF.ext for line_info, all the fields above: insn_off, file_name_off,
line_off and line_col.

>>> * config/bpf/bpf.md: Change calls to bpf_output_call.
>>> * config/bpf/btfext-out.cc (struct btf_ext_lineinfo): Add fields
>>> to struct.
>>> (bpf_create_lineinfo, btf_add_line_info_for): Add support
>>> function to insert line_info data in respective structures.
>>> (output_btfext_line_info): Function to emit line_info data in
>>> .BTF.ext section.
>>> (btf_ext_output): Call output_btfext_line_info.
>>> * config/bpf/btfext-out.h: Add prototype for
>>> btf_add_line_info_for.
>>> ---
>>>  gcc/config/bpf/bpf-protos.h   |   2 +-
>>>  gcc/config/bpf/bpf.cc | 103 ++---
>>>  gcc/config/bpf/bpf.md |   4 +-
>>>  gcc/config/bpf/btfext-out.cc  | 108 +-
>>>  gcc/config/bpf/btfext-out.h   |   4 +
>>>  .../gcc.target/bpf/btfext-funcinfo.c  |   3 +-
>>>  6 files changed, 203 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
>>> index b4866d34209..ddaca50af69 100644
>>> --- a/gcc/config/bpf/bpf-protos.h
>>> +++ b/gcc/config/bpf/bpf-protos.h
>>> @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3.  If not see
>>>  /* Routines implemented in bpf.cc.  */
>>>
>>>  extern HOST_WIDE_INT bpf_initial_elimination_offset (int, int);
>>> -extern const char *bpf_output_

Re: [PATCH 3/3] bpf: add line_info support to BTF.ext section.

2024-04-17 Thread Jose E. Marchesi


Hi Cuper.
Thanks for the patch.

> This patch adds line_info debug information support to .BTF.ext
> sections.
> Line info information is used by the BPF verifier to improve error
> reporting and give more precise source core referenced errors.
>
> gcc/Changelog:
>   * config/bpf/bpf-protos.h (bpf_output_call): Change prototype.
>   * config/bpf/bpf.cc (bpf_output_call): Change to adapt operands
>   and return
>   the instruction template instead of emmidiatelly emit asm and
>   not allow proper final expected execution flow.
>   (bpf_output_line_info): Add function to introduce line info
>   entries in respective structures
>   (bpf_asm_out_unwind_emit): Add function as hook to
>   TARGET_ASM_UNWIND_EMIT. This hook is called before any
>   instruction is emitted.

Is it actually necessary to emit a label (plus .BTF.ext entry) for every
instruction?

>   * config/bpf/bpf.md: Change calls to bpf_output_call.
>   * config/bpf/btfext-out.cc (struct btf_ext_lineinfo): Add fields
>   to struct.
>   (bpf_create_lineinfo, btf_add_line_info_for): Add support
>   function to insert line_info data in respective structures.
>   (output_btfext_line_info): Function to emit line_info data in
>   .BTF.ext section.
>   (btf_ext_output): Call output_btfext_line_info.
>   * config/bpf/btfext-out.h: Add prototype for
>   btf_add_line_info_for.
> ---
>  gcc/config/bpf/bpf-protos.h   |   2 +-
>  gcc/config/bpf/bpf.cc | 103 ++---
>  gcc/config/bpf/bpf.md |   4 +-
>  gcc/config/bpf/btfext-out.cc  | 108 +-
>  gcc/config/bpf/btfext-out.h   |   4 +
>  .../gcc.target/bpf/btfext-funcinfo.c  |   3 +-
>  6 files changed, 203 insertions(+), 21 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index b4866d34209..ddaca50af69 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3.  If not see
>  /* Routines implemented in bpf.cc.  */
>  
>  extern HOST_WIDE_INT bpf_initial_elimination_offset (int, int);
> -extern const char *bpf_output_call (rtx);
> +extern const char *bpf_output_call (const char *templ, rtx *, int 
> target_index);
>  extern void bpf_target_macros (cpp_reader *);
>  extern void bpf_print_operand (FILE *, rtx, int);
>  extern void bpf_print_operand_address (FILE *, rtx);
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index d9141dd625a..f1a8eb8d62c 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -754,14 +754,12 @@ bpf_output_destructor (rtx symbol, int priority 
> ATTRIBUTE_UNUSED)
> bpf.md.  */
>  
>  const char *
> -bpf_output_call (rtx target)
> +bpf_output_call (const char *templ, rtx *operands, int target_index)
>  {
> -  rtx xops[1];
> -
> +  rtx target = operands[target_index];
>switch (GET_CODE (target))
>  {
>  case CONST_INT:
> -  output_asm_insn ("call\t%0", );
>break;
>  case SYMBOL_REF:
>{
> @@ -774,26 +772,20 @@ bpf_output_call (rtx target)
> {
>   tree attr_args = TREE_VALUE (attr);
>  
> - xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
> - output_asm_insn ("call\t%0", xops);
> -   }
> - else
> -   output_asm_insn ("call\t%0", );
> + operands[target_index] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE 
> (attr_args)));
>  
> +   }
>   break;
>}
>  default:
> -  if (TARGET_XBPF)
> - output_asm_insn ("call\t%0", );
> -  else
> +  if (!TARGET_XBPF)
>   {
> error ("indirect call in function, which are not supported by eBPF");
> -   output_asm_insn ("call 0", NULL);
> +   operands[target_index] = GEN_INT (0);
>   }
>break;
>  }
> -
> -  return "";
> +  return templ;
>  }
>  
>  const char *
> @@ -1144,6 +1136,87 @@ bpf_debug_unwind_info ()
>  #undef TARGET_DEBUG_UNWIND_INFO
>  #define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info
>  
> +/* Create a BTF.ext line_info entry.  */
> +
> +static void
> +bpf_output_line_info (FILE *asm_out_file, rtx_insn *insn)
> +{
> +  static unsigned int line_info_label = 1;
> +  static tree cfun_decl = NULL_TREE;
> +  static bool func_start_added = false;
> +  const char *label = NULL;
> +  unsigned int loc = 0;
> +  const char *filename = NULL;
> +  unsigned int line = 0;
> +  unsigned int column = 0;
> +
> +  if(!btf_debuginfo_p ())
> +return;

I think it would be better to put this guard in bpf_asm_out_unwind_emit
instead of bpf_output_line_info.

> +
> +  gcc_assert (insn != NULL_RTX);
> +
> +  if (current_function_decl != cfun_decl
> +  && GET_CODE (insn) == NOTE)
> +{
> +  label = current_function_func_begin_label;
> +  loc = DECL_SOURCE_LOCATION (current_function_decl);
> +  filename = LOCATION_FILE (loc);
> +  

Re: [PATCH 1/3] bpf: support more instructions to match CO-RE relocations

2024-04-17 Thread Jose E. Marchesi


Hi Cupertino.
OK for master.
Thanks!

> BPF supports multiple instructions to be CO-RE relocatable regardless of
> the position of the immediate field in the encoding.
> In particular, not only the MOV instruction allows a CO-RE
> relocation of its immediate operand, but the LD and ST instructions can
> have a CO-RE relocation happening to their offset immediate operand,
> even though those operands are encoded in different encoding bits.
> This patch moves matching from a more traditional matching of the
> UNSPEC_CORE_RELOC pattern within a define_insn to a match within the
> constraints of both immediates and address operands from more generic
> mov define_insn rule.
>
> gcc/Changelog:
>   * config/bpf/bpf-protos.h (bpf_add_core_reloc): Renamed function
>   to bpf_output_move.
>   * config/bpf/bpf.cc (bpf_legitimate_address_p): Allow
>   UNSPEC_CORE_RELOC to match an address.
>   (bpf_insn_cost): Make UNSPEC_CORE_RELOC immediate moves
>   expensive to prioritize loads and stores.
>   (TARGET_INSN_COST): Add hook.
>   (bpf_output_move): Wrapper to call bpf_output_core_reloc.
>   (bpf_print_operand): Add support to print immediate operands
>   specified with the UNSPEC_CORE_RELOC.
>   (bpf_print_operand_address): Likewise, but to support
>   UNSPEC_CORE_RELOC in addresses.
>   (bpf_init_builtins): Flag BPF_BUILTIN_CORE_RELOC as NOTHROW.
>   * config/bpf/bpf.md: Wrap patterns for MOV, LD and ST
>   instruction with bpf_output_move call.
>   (mov_reloc_core): Remove now spurious define_insn.
>   * config/bpf/constraints.md: Added "c" and "C" constraints to
>   match immediates represented with UNSPEC_CORE_RELOC.
>   * config/bpf/core-builtins.cc (bpf_add_core_reloc): Remove
>   (bpf_output_core_reloc): Add function to create the CO-RE
>   relocations based on new matching rules.
>   * config/bpf/core-builtins.h (bpf_output_core_reloc): Add
>   prototype.
>   * config/bpf/predicates.md (core_imm_operand) Add predicate.
>   (mov_src_operand): Add match for core_imm_operand.
>
> gcc/testsuite/ChangeLog:
>   * gcc.target/bpf/btfext-funcinfo.c: Updated to changes.
>   * gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c:
>   Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-existence-1.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-lshift-1-be.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-lshift-1-le.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-lshift-2.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-offset-1.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-rshift-1.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-rshift-2.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-sign-1.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-sign-2.c: Likewise.
>   * gcc.target/bpf/core-builtin-fieldinfo-size-1.c: Likewise.
> ---
>  gcc/config/bpf/bpf-protos.h   |  2 +-
>  gcc/config/bpf/bpf.cc | 54 +-
>  gcc/config/bpf/bpf.md | 56 ++-
>  gcc/config/bpf/constraints.md | 20 ++
>  gcc/config/bpf/core-builtins.cc   | 71 ++-
>  gcc/config/bpf/core-builtins.h|  2 +
>  gcc/config/bpf/predicates.md  |  7 +-
>  .../gcc.target/bpf/btfext-funcinfo.c  |  2 -
>  ...core-builtin-fieldinfo-const-elimination.c |  2 +-
>  .../bpf/core-builtin-fieldinfo-existence-1.c  |  2 +-
>  .../bpf/core-builtin-fieldinfo-lshift-1-be.c  |  8 +--
>  .../bpf/core-builtin-fieldinfo-lshift-1-le.c  |  8 +--
>  .../bpf/core-builtin-fieldinfo-lshift-2.c |  6 +-
>  .../bpf/core-builtin-fieldinfo-offset-1.c | 12 ++--
>  .../bpf/core-builtin-fieldinfo-rshift-1.c |  8 +--
>  .../bpf/core-builtin-fieldinfo-rshift-2.c |  4 +-
>  .../bpf/core-builtin-fieldinfo-sign-1.c   |  4 +-
>  .../bpf/core-builtin-fieldinfo-sign-2.c   |  4 +-
>  .../bpf/core-builtin-fieldinfo-size-1.c   |  8 +--
>  19 files changed, 189 insertions(+), 91 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index ac0c2f4038f..b4866d34209 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -30,7 +30,7 @@ extern void bpf_print_operand_address (FILE *, rtx);
>  extern void bpf_expand_prologue (void);
>  extern void bpf_expand_epilogue (void);
>  extern void bpf_expand_cbranch (machine_mode, rtx *);
> -const char *bpf_add_core_reloc (rtx *operands, const char *templ);
> +const char *bpf_output_move (rtx *operands, const char *templ);
>  
>  class gimple_opt_pass;
>  gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index fb60770c170..d9141dd625a 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -584,6 

Re: [PATCH] bpf: define INT8_TYPE as signed char

2024-03-14 Thread Jose E. Marchesi


Hi David.

> Change the BPF backend to define INT8_TYPE with an explicit sign, rather
> than a plain char.  This is in line with other targets and removes the
> risk of int8_t being affected by the signedness of the plain char type
> of the host system.

OK.

I would add to the commit message that the motivation for this change is
that even if `char' is defined to be signed in BPF targets, some BPF
programs use the (mal)practice of including internal libc headers
indirectly via kernel headers and that may trigger compilation errors
regarding redefinitions of types.

Thanks for the patch!

>
> Tested on x86_64-linux-gnu host for bpf-unknown-none.
> Sanity checked compiling Linux kernel BPF selftests.
>
> gcc/
>
>   * config/bpf/bpf.h (INT8_TYPE): Change to signed char.
> ---
>  gcc/config/bpf/bpf.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index f107a5a4c34..3cc5daa1b58 100644
> --- a/gcc/config/bpf/bpf.h
> +++ b/gcc/config/bpf/bpf.h
> @@ -99,7 +99,7 @@
>  
>  #define SIG_ATOMIC_TYPE "char"
>  
> -#define INT8_TYPE "char"
> +#define INT8_TYPE "signed char"
>  #define INT16_TYPE "short int"
>  #define INT32_TYPE "int"
>  #define INT64_TYPE "long int"


Re: [PATCH 1/3] bpf: Fix CO-RE field expression builtins

2024-03-14 Thread Jose E. Marchesi


>> Jose E. Marchesi writes:
>>
>>>> This patch corrects bugs within the CO-RE builtin field expression
>>>> related builtins.
>>>> The following bugs were identified and corrected based on the expected
>>>> results of bpf-next selftests testsuite.
>>>> It addresses the following problems:
>>>>  - Expressions with pointer dereferencing now point to the BTF structure
>>>>type, instead of the structure pointer type.
>>>>  - Pointer addition to structure root is now identified and constructed
>>>>in CO-RE relocations as if it is an array access. For example,
>>>>   "&(s+2)->b" generates "2:1" as an access string where "2" is
>>>>   refering to the access for "s+2".
>>>>
>>>> gcc/ChangeLog:
>>>>* config/bpf/core-builtins.cc (core_field_info): Add
>>>>support for POINTER_PLUS_EXPR in the root of the field expression.
>>>>(bpf_core_get_index): Likewise.
>>>>(pack_field_expr): Make the BTF type to point to the structure
>>>>related node, instead of its pointer type.
>>>>(make_core_safe_access_index): Correct to new code.
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>* gcc.target/bpf/core-attr-5.c: Correct.
>>>>* gcc.target/bpf/core-attr-6.c: Likewise.
>>>>* gcc.target/bpf/core-attr-struct-as-array.c: Add test case for
>>>>pointer arithmetics as array access use case.
>>>> ---
>>>>  gcc/config/bpf/core-builtins.cc   | 54 +++
>>>>  gcc/testsuite/gcc.target/bpf/core-attr-5.c|  4 +-
>>>>  gcc/testsuite/gcc.target/bpf/core-attr-6.c|  4 +-
>>>>  .../bpf/core-attr-struct-as-array.c   | 35 
>>>>  4 files changed, 82 insertions(+), 15 deletions(-)
>>>>  create mode 100644 
>>>> gcc/testsuite/gcc.target/bpf/core-attr-struct-as-array.c
>>>>
>>>> diff --git a/gcc/config/bpf/core-builtins.cc 
>>>> b/gcc/config/bpf/core-builtins.cc
>>>> index 8d8c54c1fb3d..4256fea15e49 100644
>>>> --- a/gcc/config/bpf/core-builtins.cc
>>>> +++ b/gcc/config/bpf/core-builtins.cc
>>>> @@ -388,8 +388,8 @@ core_field_info (tree src, enum btf_core_reloc_kind 
>>>> kind)
>>>>
>>>>src = root_for_core_field_info (src);
>>>>
>>>> -  get_inner_reference (src, , , _off, , 
>>>> ,
>>>> - , );
>>>> +  tree root = get_inner_reference (src, , , _off, 
>>>> ,
>>>> + , , );
>>>>
>>>>/* Note: Use DECL_BIT_FIELD_TYPE rather than DECL_BIT_FIELD here, 
>>>> because it
>>>>   remembers whether the field in question was originally declared as a
>>>> @@ -414,6 +414,23 @@ core_field_info (tree src, enum btf_core_reloc_kind 
>>>> kind)
>>>>  {
>>>>  case BPF_RELO_FIELD_BYTE_OFFSET:
>>>>{
>>>> +  result = 0;
>>>> +  if (var_off == NULL_TREE
>>>> +  && TREE_CODE (root) == INDIRECT_REF
>>>> +  && TREE_CODE (TREE_OPERAND (root, 0)) == POINTER_PLUS_EXPR)
>>>> +{
>>>> +  tree node = TREE_OPERAND (root, 0);
>>>> +  tree offset = TREE_OPERAND (node, 1);
>>>> +  tree type = TREE_TYPE (TREE_OPERAND (node, 0));
>>>> +  type = TREE_TYPE (type);
>>>> +
>>>> +  gcc_assert (TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p 
>>>> (offset)
>>>> +  && COMPLETE_TYPE_P (type) && tree_fits_shwi_p (TYPE_SIZE 
>>>> (type)));
>>>
>>> What if an expression with a non-constant offset (something like s+foo)
>>> is passed to the builtin?  Wouldn't it be better to error there instead
>>> of ICEing?
>>>
>> In that case, var_off == NULL_TREE, and it did not reach the assert.
>> In any case, please notice that this code was copied from some different
>> code in the same file which in that case would actually produce the
>> error earlier.  The assert is there as a safe guard just in case the
>> other function stops detecting this case.
>>
>> In core-builtins.cc:572
>>
>> else if (code == POINTER_PLUS_EXPR)
>>   {
>> tree offset = TREE_OPERAND (node, 1);
>> tree type = TREE_

Re: [PATCH 1/3] bpf: Fix CO-RE field expression builtins

2024-03-14 Thread Jose E. Marchesi


> Jose E. Marchesi writes:
>
>>> This patch corrects bugs within the CO-RE builtin field expression
>>> related builtins.
>>> The following bugs were identified and corrected based on the expected
>>> results of bpf-next selftests testsuite.
>>> It addresses the following problems:
>>>  - Expressions with pointer dereferencing now point to the BTF structure
>>>type, instead of the structure pointer type.
>>>  - Pointer addition to structure root is now identified and constructed
>>>in CO-RE relocations as if it is an array access. For example,
>>>   "&(s+2)->b" generates "2:1" as an access string where "2" is
>>>   refering to the access for "s+2".
>>>
>>> gcc/ChangeLog:
>>> * config/bpf/core-builtins.cc (core_field_info): Add
>>> support for POINTER_PLUS_EXPR in the root of the field expression.
>>> (bpf_core_get_index): Likewise.
>>> (pack_field_expr): Make the BTF type to point to the structure
>>> related node, instead of its pointer type.
>>> (make_core_safe_access_index): Correct to new code.
>>>
>>> gcc/testsuite/ChangeLog:
>>> * gcc.target/bpf/core-attr-5.c: Correct.
>>> * gcc.target/bpf/core-attr-6.c: Likewise.
>>> * gcc.target/bpf/core-attr-struct-as-array.c: Add test case for
>>> pointer arithmetics as array access use case.
>>> ---
>>>  gcc/config/bpf/core-builtins.cc   | 54 +++
>>>  gcc/testsuite/gcc.target/bpf/core-attr-5.c|  4 +-
>>>  gcc/testsuite/gcc.target/bpf/core-attr-6.c|  4 +-
>>>  .../bpf/core-attr-struct-as-array.c   | 35 
>>>  4 files changed, 82 insertions(+), 15 deletions(-)
>>>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-attr-struct-as-array.c
>>>
>>> diff --git a/gcc/config/bpf/core-builtins.cc 
>>> b/gcc/config/bpf/core-builtins.cc
>>> index 8d8c54c1fb3d..4256fea15e49 100644
>>> --- a/gcc/config/bpf/core-builtins.cc
>>> +++ b/gcc/config/bpf/core-builtins.cc
>>> @@ -388,8 +388,8 @@ core_field_info (tree src, enum btf_core_reloc_kind 
>>> kind)
>>>
>>>src = root_for_core_field_info (src);
>>>
>>> -  get_inner_reference (src, , , _off, , ,
>>> -  , );
>>> +  tree root = get_inner_reference (src, , , _off, ,
>>> +  , , );
>>>
>>>/* Note: Use DECL_BIT_FIELD_TYPE rather than DECL_BIT_FIELD here, 
>>> because it
>>>   remembers whether the field in question was originally declared as a
>>> @@ -414,6 +414,23 @@ core_field_info (tree src, enum btf_core_reloc_kind 
>>> kind)
>>>  {
>>>  case BPF_RELO_FIELD_BYTE_OFFSET:
>>>{
>>> +   result = 0;
>>> +   if (var_off == NULL_TREE
>>> +   && TREE_CODE (root) == INDIRECT_REF
>>> +   && TREE_CODE (TREE_OPERAND (root, 0)) == POINTER_PLUS_EXPR)
>>> + {
>>> +   tree node = TREE_OPERAND (root, 0);
>>> +   tree offset = TREE_OPERAND (node, 1);
>>> +   tree type = TREE_TYPE (TREE_OPERAND (node, 0));
>>> +   type = TREE_TYPE (type);
>>> +
>>> +   gcc_assert (TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p 
>>> (offset)
>>> +   && COMPLETE_TYPE_P (type) && tree_fits_shwi_p (TYPE_SIZE 
>>> (type)));
>>
>> What if an expression with a non-constant offset (something like s+foo)
>> is passed to the builtin?  Wouldn't it be better to error there instead
>> of ICEing?
>>
> In that case, var_off == NULL_TREE, and it did not reach the assert.
> In any case, please notice that this code was copied from some different
> code in the same file which in that case would actually produce the
> error earlier.  The assert is there as a safe guard just in case the
> other function stops detecting this case.
>
> In core-builtins.cc:572
>
> else if (code == POINTER_PLUS_EXPR)
>   {
> tree offset = TREE_OPERAND (node, 1);
> tree type = TREE_TYPE (TREE_OPERAND (node, 0));
> type = TREE_TYPE (type);
>
> if (TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset)
> && COMPLETE_TYPE_P (type) && tree_fits_shwi_p (TYPE_SIZE (type)))
>   {
> HOST_WIDE_INT offset_i = tree_to_shwi (offset);
> HOST_WIDE_INT type_size_i = tree_to_shwi

Re: [PATCH 1/3] bpf: Fix CO-RE field expression builtins

2024-03-14 Thread Jose E. Marchesi


> This patch corrects bugs within the CO-RE builtin field expression
> related builtins.
> The following bugs were identified and corrected based on the expected
> results of bpf-next selftests testsuite.
> It addresses the following problems:
>  - Expressions with pointer dereferencing now point to the BTF structure
>type, instead of the structure pointer type.
>  - Pointer addition to structure root is now identified and constructed
>in CO-RE relocations as if it is an array access. For example,
>   "&(s+2)->b" generates "2:1" as an access string where "2" is
>   refering to the access for "s+2".
>
> gcc/ChangeLog:
>   * config/bpf/core-builtins.cc (core_field_info): Add
>   support for POINTER_PLUS_EXPR in the root of the field expression.
>   (bpf_core_get_index): Likewise.
>   (pack_field_expr): Make the BTF type to point to the structure
>   related node, instead of its pointer type.
>   (make_core_safe_access_index): Correct to new code.
>
> gcc/testsuite/ChangeLog:
>   * gcc.target/bpf/core-attr-5.c: Correct.
>   * gcc.target/bpf/core-attr-6.c: Likewise.
>   * gcc.target/bpf/core-attr-struct-as-array.c: Add test case for
>   pointer arithmetics as array access use case.
> ---
>  gcc/config/bpf/core-builtins.cc   | 54 +++
>  gcc/testsuite/gcc.target/bpf/core-attr-5.c|  4 +-
>  gcc/testsuite/gcc.target/bpf/core-attr-6.c|  4 +-
>  .../bpf/core-attr-struct-as-array.c   | 35 
>  4 files changed, 82 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-attr-struct-as-array.c
>
> diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
> index 8d8c54c1fb3d..4256fea15e49 100644
> --- a/gcc/config/bpf/core-builtins.cc
> +++ b/gcc/config/bpf/core-builtins.cc
> @@ -388,8 +388,8 @@ core_field_info (tree src, enum btf_core_reloc_kind kind)
>  
>src = root_for_core_field_info (src);
>  
> -  get_inner_reference (src, , , _off, , ,
> -, );
> +  tree root = get_inner_reference (src, , , _off, ,
> +, , );
>  
>/* Note: Use DECL_BIT_FIELD_TYPE rather than DECL_BIT_FIELD here, because 
> it
>   remembers whether the field in question was originally declared as a
> @@ -414,6 +414,23 @@ core_field_info (tree src, enum btf_core_reloc_kind kind)
>  {
>  case BPF_RELO_FIELD_BYTE_OFFSET:
>{
> + result = 0;
> + if (var_off == NULL_TREE
> + && TREE_CODE (root) == INDIRECT_REF
> + && TREE_CODE (TREE_OPERAND (root, 0)) == POINTER_PLUS_EXPR)
> +   {
> + tree node = TREE_OPERAND (root, 0);
> + tree offset = TREE_OPERAND (node, 1);
> + tree type = TREE_TYPE (TREE_OPERAND (node, 0));
> + type = TREE_TYPE (type);
> +
> + gcc_assert (TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p 
> (offset)
> + && COMPLETE_TYPE_P (type) && tree_fits_shwi_p (TYPE_SIZE 
> (type)));

What if an expression with a non-constant offset (something like s+foo)
is passed to the builtin?  Wouldn't it be better to error there instead
of ICEing?

> +
> + HOST_WIDE_INT offset_i = tree_to_shwi (offset);
> + result += offset_i;
> +   }
> +
>   type = unsigned_type_node;
>   if (var_off != NULL_TREE)
> {
> @@ -422,9 +439,9 @@ core_field_info (tree src, enum btf_core_reloc_kind kind)
> }
>  
>   if (bitfieldp)
> -   result = start_bitpos / 8;
> +   result += start_bitpos / 8;
>   else
> -   result = bitpos / 8;
> +   result += bitpos / 8;
>}
>break;
>  
> @@ -552,6 +569,7 @@ bpf_core_get_index (const tree node, bool *valid)
>  {
>tree offset = TREE_OPERAND (node, 1);
>tree type = TREE_TYPE (TREE_OPERAND (node, 0));
> +  type = TREE_TYPE (type);
>  
>if (TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset)
> && COMPLETE_TYPE_P (type) && tree_fits_shwi_p (TYPE_SIZE (type)))
> @@ -627,14 +645,18 @@ compute_field_expr (tree node, unsigned int *accessors,
>  
>switch (TREE_CODE (node))
>  {
> -case ADDR_EXPR:
> -  return 0;
>  case INDIRECT_REF:
> -  accessors[0] = 0;
> -  return 1;
> -case POINTER_PLUS_EXPR:
> -  accessors[0] = bpf_core_get_index (node, valid);
> -  return 1;
> +  if (TREE_CODE (node = TREE_OPERAND (node, 0)) == POINTER_PLUS_EXPR)
> + {
> +   accessors[0] = bpf_core_get_index (node, valid);
> +   *access_node = TREE_OPERAND (node, 0);
> +   return 1;
> + }
> +  else
> + {
> +   accessors[0] = 0;
> +   return 1;
> + }
>  case COMPONENT_REF:
>n = compute_field_expr (TREE_OPERAND (node, 0), accessors,
> valid,
> @@ -660,6 +682,7 @@ compute_field_expr (tree node, unsigned int *accessors,
> access_node, false);
>return n;
>  
> +case 

Re: [PATCH v2] bpf: add size threshold for inlining mem builtins

2024-03-08 Thread Jose E. Marchesi


Hi Faust.
OK.  Thanks!

> [Changes from v1:
>  - Error if threshold is exceeded instead of silently emitting libcall
>  - Update test accordingly
>  - Expand documentation to explain this behavior  ]
>
> BPF cannot fall back on library calls to implement memmove, memcpy and
> memset, so we attempt to expand these inline always if possible.
> However, this inline expansion was being attempted even for excessively
> large operations, which could result in gcc consuming huge amounts of
> memory and hanging.
>
> Add a size threshold in the BPF backend below which to always expand
> these operations inline, and introduce an option
> -minline-memops-threshold= to control the threshold. Defaults to
> 1024 bytes.
>
> gcc/
>
>   * config/bpf/bpf.cc (bpf_expand_cpymem, bpf_expand_setmem): Do
>   not attempt inline expansion if size is above threshold.
>   * config/bpf/bpf.opt (-minline-memops-threshold): New option.
>   * doc/invoke.texi (eBPF Options) <-minline-memops-threshold>:
>   Document.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/inline-memops-threshold-1.c: New test.
>   * gcc.target/bpf/inline-memops-threshold-2.c: New test.
> ---
>  gcc/config/bpf/bpf.cc | 26 ++-
>  gcc/config/bpf/bpf.opt|  4 +++
>  gcc/doc/invoke.texi   | 11 +++-
>  .../bpf/inline-memops-threshold-1.c   | 15 +++
>  .../bpf/inline-memops-threshold-2.c   | 11 
>  5 files changed, 65 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/inline-memops-threshold-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/inline-memops-threshold-2.c
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 0e33f4347ba..8365cd9fcb1 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1244,9 +1244,9 @@ bool
>  bpf_expand_cpymem (rtx *operands, bool is_move)
>  {
>/* Size must be constant for this expansion to work.  */
> +  const char *name = is_move ? "memmove" : "memcpy";
>if (!CONST_INT_P (operands[2]))
>  {
> -  const char *name = is_move ? "memmove" : "memcpy";
>if (flag_building_libgcc)
>   warning (0, "could not inline call to %<__builtin_%s%>: "
>"size must be constant", name);
> @@ -1275,6 +1275,18 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
>gcc_unreachable ();
>  }
>  
> +  /* For sizes above threshold, always use a libcall.  */
> +  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
> +{
> +  if (flag_building_libgcc)
> + warning (0, "could not inline call to %<__builtin_%s%>: "
> +  "too many bytes, use -minline-memops-threshold", name);
> +  else
> + error ("could not inline call to %<__builtin_%s%>: "
> +"too many bytes, use -minline-memops-threshold", name);
> +  return false;
> +}
> +
>unsigned iters = size_bytes >> ceil_log2 (align);
>unsigned remainder = size_bytes & (align - 1);
>  
> @@ -1347,6 +1359,18 @@ bpf_expand_setmem (rtx *operands)
>gcc_unreachable ();
>  }
>  
> +  /* For sizes above threshold, always use a libcall.  */
> +  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
> +{
> +  if (flag_building_libgcc)
> + warning (0, "could not inline call to %<__builtin_memset%>: "
> +  "too many bytes, use -minline-memops-threshold");
> +  else
> + error ("could not inline call to %<__builtin_memset%>: "
> +"too many bytes, use -minline-memops-threshold");
> +  return false;
> +}
> +
>unsigned iters = size_bytes >> ceil_log2 (align);
>unsigned remainder = size_bytes & (align - 1);
>unsigned inc = GET_MODE_SIZE (mode);
> diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
> index acfddebdad7..541ebe4dfc4 100644
> --- a/gcc/config/bpf/bpf.opt
> +++ b/gcc/config/bpf/bpf.opt
> @@ -108,3 +108,7 @@ Enum(asm_dialect) String(normal) Value(ASM_NORMAL)
>  
>  EnumValue
>  Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC)
> +
> +minline-memops-threshold=
> +Target RejectNegative Joined UInteger Var(bpf_inline_memops_threshold) 
> Init(1024)
> +-minline-memops-threshold= Maximum size of memset/memmove/memcpy to 
> inline, larger sizes will use a library call.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index c0d604a2c5c..85c938d4a14 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -971,7 +971,7 @@ Objective-C and Objective-C++ Dialects}.
>  @gccoptlist{-mbig-endian -mlittle-endian
>  -mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
>  -mjmp32 -malu32 -mv3-atomics -mbswap -msdiv -msmov -mcpu=@var{version}
> --masm=@var{dialect}}
> +-masm=@var{dialect} -minline-memops-threshold=@var{bytes}}
>  
>  @emph{FR30 Options}
>  @gccoptlist{-msmall-model  -mno-lsim}
> @@ -25701,6 +25701,15 @@ Outputs pseudo-c assembly dialect.
>  
>  @end table
>  

Re: [PATCH] bpf: add size threshold for inlining mem builtins

2024-03-08 Thread Jose E. Marchesi


Hi Faust.

> BPF cannot fall back on library calls to implement memmove, memcpy and
> memset, so we attempt to expand these inline always if possible.
> However, this inline expansion was being attempted even for excessively
> large operations, which could result in gcc consuming huge amounts of
> memory and hanging.
>
> Add a size threshold in the BPF backend below which to always expand
> these operations inline, and introduce an option
> -minline-memops-threshold= to control the threshold. Defaults to
> 1024 bytes.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
> Fixes hang in test gcc.c-torture/compile/20050622-1.c for BPF, which
> returns to (correctly) failing due to exceeding the eBPF stack limit.
>
> gcc/
>
>   * config/bpf/bpf.cc (bpf_expand_cpymem, bpf_expand_setmem): Do
>   not attempt inline expansion if size is above threshold.
>   * config/bpf/bpf.opt (-minline-memops-threshold): New option.
>   * doc/invoke.texi (eBPF Options) <-minline-memops-threshold>:
>   Document.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/inline-memops-threshold-1.c: New test.
>   * gcc.target/bpf/inline-memops-threshold-2.c: New test.
> ---
>  gcc/config/bpf/bpf.cc |  8 
>  gcc/config/bpf/bpf.opt|  4 
>  gcc/doc/invoke.texi   |  9 -
>  .../gcc.target/bpf/inline-memops-threshold-1.c| 15 +++
>  .../gcc.target/bpf/inline-memops-threshold-2.c| 14 ++
>  5 files changed, 49 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/inline-memops-threshold-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/inline-memops-threshold-2.c
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 0e33f4347ba..3f3dcb0a46b 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1275,6 +1275,10 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
>gcc_unreachable ();
>  }
>  
> +  /* For sizes above threshold, always use a libcall.  */
> +  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
> +return false;

Shouldn't we emit warning or error in these cases, like in the other
situations that prevent inlining?  Something like:

  if (flag_building_libgcc)
warning (0, "could not inline call to %<__builtin_%s%>: "
 "too many bytes, use -minline-memops-threshold", name);
  else
error ("could not inline call to %<__builtin_%s%>: "
   "too many bytes, use -minline-memops-threshold", name);

> +
>unsigned iters = size_bytes >> ceil_log2 (align);
>unsigned remainder = size_bytes & (align - 1);
>  
> @@ -1347,6 +1351,10 @@ bpf_expand_setmem (rtx *operands)
>gcc_unreachable ();
>  }
>  
> +  /* For sizes above threshold, always use a libcall.  */
> +  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
> +return false;
> +
>unsigned iters = size_bytes >> ceil_log2 (align);
>unsigned remainder = size_bytes & (align - 1);
>unsigned inc = GET_MODE_SIZE (mode);
> diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
> index acfddebdad7..541ebe4dfc4 100644
> --- a/gcc/config/bpf/bpf.opt
> +++ b/gcc/config/bpf/bpf.opt
> @@ -108,3 +108,7 @@ Enum(asm_dialect) String(normal) Value(ASM_NORMAL)
>  
>  EnumValue
>  Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC)
> +
> +minline-memops-threshold=
> +Target RejectNegative Joined UInteger Var(bpf_inline_memops_threshold) 
> Init(1024)
> +-minline-memops-threshold= Maximum size of memset/memmove/memcpy to 
> inline, larger sizes will use a library call.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 2390d478121..7a965631123 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -971,7 +971,7 @@ Objective-C and Objective-C++ Dialects}.
>  @gccoptlist{-mbig-endian -mlittle-endian
>  -mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
>  -mjmp32 -malu32 -mv3-atomics -mbswap -msdiv -msmov -mcpu=@var{version}
> --masm=@var{dialect}}
> +-masm=@var{dialect} -minline-memops-threshold=@var{bytes}}
>  
>  @emph{FR30 Options}
>  @gccoptlist{-msmall-model  -mno-lsim}
> @@ -25700,6 +25700,13 @@ Outputs pseudo-c assembly dialect.
>  
>  @end table
>  
> +@opindex -minline-memops-threshold
> +@item -minline-memops-threshold=@var{bytes}
> +Specifies a size threshold in bytes at or below which memmove, memcpy
> +and memset shall always be expanded inline.  Operations dealing with
> +sizes larger than this threshold will be implemented using a library
> +call instead of being expanded inline.  The default is @samp{1024}.

"[...] would have to be implemented using a library call instead of
 being expanded inline, but since BPF doesn't allow libcalls exceeding
 this threshold results in a compile-time error."

> +
>  @end table
>  
>  @node FR30 Options
> diff --git a/gcc/testsuite/gcc.target/bpf/inline-memops-threshold-1.c 
> 

Re: [PATCH] bpf: testsuite: fix unresolved test in memset-1.c

2024-03-08 Thread Jose E. Marchesi


Hi David.
OK.  Thanks.

> The test was trying to do too much by both checking for an error, and
> checking the resulting assembly. Of course, due to the error no asm was
> produced, so the scan-asm went unresolved. Split it into two separate
> tests to fix the issue.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/memset-1.c: Move error test case to...
>   * gcc.target/bpf/memset-2.c: ... here. New test.
> ---
>  gcc/testsuite/gcc.target/bpf/memset-1.c |  8 
>  gcc/testsuite/gcc.target/bpf/memset-2.c | 22 ++
>  2 files changed, 22 insertions(+), 8 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memset-2.c
>
> diff --git a/gcc/testsuite/gcc.target/bpf/memset-1.c 
> b/gcc/testsuite/gcc.target/bpf/memset-1.c
> index 9e9f8eff028..7c4768c6e73 100644
> --- a/gcc/testsuite/gcc.target/bpf/memset-1.c
> +++ b/gcc/testsuite/gcc.target/bpf/memset-1.c
> @@ -28,12 +28,4 @@ set_large (struct context *ctx)
>__builtin_memset (dest, 0xfe, 130);
>  }
>  
> -void
> -set_variable (struct context *ctx)
> -{
> -  void *data = (void *)(long)ctx->data;
> -  char *dest = data;
> -  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
> inline call" } */
> -}
> -
>  /* { dg-final { scan-assembler-times "call" 0 } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/memset-2.c 
> b/gcc/testsuite/gcc.target/bpf/memset-2.c
> new file mode 100644
> index 000..0602a1a277c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/memset-2.c
> @@ -0,0 +1,22 @@
> +/* Test that we error if memset cannot be expanded inline.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +struct context {
> + unsigned int data;
> + unsigned int data_end;
> + unsigned int data_meta;
> + unsigned int ingress;
> + unsigned int queue_index;
> + unsigned int egress;
> +};
> +
> +
> +void
> +set_variable (struct context *ctx)
> +{
> +  void *data = (void *)(long)ctx->data;
> +  char *dest = data;
> +  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
> inline call" } */
> +}


Re: [PATCH] bpf: add inline memset expansion

2024-03-04 Thread Jose E. Marchesi


Hi David.
Thanks for the patch.
OK.

> Similar to memmove and memcpy, the BPF backend cannot fall back on a
> library call to implement __builtin_memset, and should always expand
> calls to it inline if possible.
>
> This patch implements simple inline expansion of memset in the BPF
> backend in a verifier-friendly way. Similar to memcpy and memmove, the
> size must be an integer constant, as is also required by clang.
>
> Tested for bpf-unknown-none target on x86_64-linux-gnu host.
> Also testetd against kernel BPF verifier by compiling and loading a
> test program using the inline memset expansion.
>
> gcc/
>   * config/bpf/bpf-protos.h (bpf_expand_setmem): New prototype.
>   * config/bpf/bpf.cc (bpf_expand_setmem): New.
>   * config/bpf/bpf.md (setmemdi): New define_expand.
>
> gcc/testsuite/
>   * gcc.target/bpf/memset-1.c: New test.
> ---
>  gcc/config/bpf/bpf-protos.h |  1 +
>  gcc/config/bpf/bpf.cc   | 66 +
>  gcc/config/bpf/bpf.md   | 17 +++
>  gcc/testsuite/gcc.target/bpf/memset-1.c | 39 +++
>  4 files changed, 123 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memset-1.c
>
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index 366acb87ae4..ac0c2f4038f 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -36,5 +36,6 @@ class gimple_opt_pass;
>  gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
>  
>  bool bpf_expand_cpymem (rtx *, bool);
> +bool bpf_expand_setmem (rtx *);
>  
>  #endif /* ! GCC_BPF_PROTOS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 22b0cf2dc46..0e33f4347ba 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1309,6 +1309,72 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
>return true;
>  }
>  
> +/* Expand setmem, as from __builtin_memset.
> +   OPERANDS are the same as the setmem pattern.
> +   Return true if the expansion was successful, false otherwise.  */
> +
> +bool
> +bpf_expand_setmem (rtx *operands)
> +{
> +  /* Size must be constant for this expansion to work.  */
> +  if (!CONST_INT_P (operands[1]))
> +{
> +  if (flag_building_libgcc)
> + warning (0, "could not inline call to %<__builtin_memset%>: "
> +  "size must be constant");
> +  else
> + error ("could not inline call to %<__builtin_memset%>: "
> +"size must be constant");
> +  return false;
> +}
> +
> +  /* Alignment is a CONST_INT.  */
> +  gcc_assert (CONST_INT_P (operands[3]));
> +
> +  rtx dst = operands[0];
> +  rtx size = operands[1];
> +  rtx val = operands[2];
> +  unsigned HOST_WIDE_INT size_bytes = UINTVAL (size);
> +  unsigned align = UINTVAL (operands[3]);
> +  enum machine_mode mode;
> +  switch (align)
> +{
> +case 1: mode = QImode; break;
> +case 2: mode = HImode; break;
> +case 4: mode = SImode; break;
> +case 8: mode = DImode; break;
> +default:
> +  gcc_unreachable ();
> +}
> +
> +  unsigned iters = size_bytes >> ceil_log2 (align);
> +  unsigned remainder = size_bytes & (align - 1);
> +  unsigned inc = GET_MODE_SIZE (mode);
> +  unsigned offset = 0;
> +
> +  for (unsigned int i = 0; i < iters; i++)
> +{
> +  emit_move_insn (adjust_address (dst, mode, offset), val);
> +  offset += inc;
> +}
> +  if (remainder & 4)
> +{
> +  emit_move_insn (adjust_address (dst, SImode, offset), val);
> +  offset += 4;
> +  remainder -= 4;
> +}
> +  if (remainder & 2)
> +{
> +  emit_move_insn (adjust_address (dst, HImode, offset), val);
> +  offset += 2;
> +  remainder -= 2;
> +}
> +  if (remainder & 1)
> +emit_move_insn (adjust_address (dst, QImode, offset), val);
> +
> +  return true;
> +}
> +
>  /* Finally, build the GCC target.  */
>  
>  struct gcc_target targetm = TARGET_INITIALIZER;
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index ca677bc6b50..ea688aadf91 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -663,4 +663,21 @@ (define_expand "movmemdi"
>FAIL;
>  })
>  
> +;; memset
> +;; 0 is dst
> +;; 1 is length
> +;; 2 is value
> +;; 3 is alignment
> +(define_expand "setmemdi"
> +  [(set (match_operand:BLK 0 "memory_operand")
> + (match_operand:QI  2 "nonmemory_operand"))
> +   (use (match_operand:DI  1 "general_operand"))
> +   (match_operand 3 "immediate_operand")]
> + ""
> + {
> +  if (bpf_expand_setmem (operands))
> +DONE;
> +  FAIL;
> +})
> +
>  (include "atomic.md")
> diff --git a/gcc/testsuite/gcc.target/bpf/memset-1.c 
> b/gcc/testsuite/gcc.target/bpf/memset-1.c
> new file mode 100644
> index 000..9e9f8eff028
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/memset-1.c
> @@ -0,0 +1,39 @@
> +/* Ensure memset is expanded inline rather than emitting a libcall.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +struct context {
> + 

Re: [PATCH v3] bpf: add inline memmove and memcpy expansion

2024-02-21 Thread Jose E. Marchesi


Hi David.

This is OK.
Thank you, very nice stuff!

> [Changes from v2: 
>  - Fix incorrectly passing a location instead of OPT_W* for warning ().
>  - Reword warning/error message and test accordingly.  ]
>  
> [Changes from v1: Jose's review comments, all of which I agree with.
>  - Fix 'implments' typo in commit message.
>  - Change check that alignment is CONST_INT to gcc_assert ().
>  - Change default case in alignment switch to gcc_unreachable ().
>  - Reword error message for non-constant size memmove/memcpy, and
>update test for the error accordingly.
>  - Delete CPYMEM_EXPAND_ERR macro, since it was now only used in
>one place.  ]
>
> BPF programs are not typically linked, which means we cannot fall back
> on library calls to implement __builtin_{memmove,memcpy} and should
> always expand them inline if possible.
>
> GCC already successfully expands these builtins inline in many cases,
> but failed to do so for a few for simple cases involving overlapping
> memmove in the kernel BPF selftests and was instead emitting a libcall.
>
> This patch implements a simple inline expansion of memcpy and memmove in
> the BPF backend in a verifier-friendly way, with the caveat that the
> size must be an integer constant, which is also required by clang.
>
> Tested for bpf-unknown-none on x86_64-linux-gnu host.
>
> Also tested against the BPF verifier by compiling and loading a test
> program with overlapping memmove (essentially the memmove-1.c test)
> which failed before due to a libcall, and now successfully loads and
> passes the verifier.
>
> gcc/
>
>   * config/bpf/bpf-protos.h (bpf_expand_cpymem): New.
>   * config/bpf/bpf.cc: (emit_move_loop, bpf_expand_cpymem): New.
>   * config/bpf/bpf.md: (cpymemdi, movmemdi): New define_expands.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/memcpy-1.c: New test.
>   * gcc.target/bpf/memmove-1.c: New test.
>   * gcc.target/bpf/memmove-2.c: New test.
> ---
>  gcc/config/bpf/bpf-protos.h  |   2 +
>  gcc/config/bpf/bpf.cc| 115 +++
>  gcc/config/bpf/bpf.md|  36 +++
>  gcc/testsuite/gcc.target/bpf/memcpy-1.c  |  26 +
>  gcc/testsuite/gcc.target/bpf/memmove-1.c |  46 +
>  gcc/testsuite/gcc.target/bpf/memmove-2.c |  23 +
>  6 files changed, 248 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memcpy-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memmove-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memmove-2.c
>
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index 46d950bd990..366acb87ae4 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -35,4 +35,6 @@ const char *bpf_add_core_reloc (rtx *operands, const char 
> *templ);
>  class gimple_opt_pass;
>  gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
>  
> +bool bpf_expand_cpymem (rtx *, bool);
> +
>  #endif /* ! GCC_BPF_PROTOS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index d6ca47eeecb..f9ac263613a 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1184,6 +1184,121 @@ bpf_use_by_pieces_infrastructure_p (unsigned 
> HOST_WIDE_INT size,
>  #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
>bpf_use_by_pieces_infrastructure_p
>  
> +/* Helper for bpf_expand_cpymem.  Emit an unrolled loop moving the bytes
> +   from SRC to DST.  */
> +
> +static void
> +emit_move_loop (rtx src, rtx dst, machine_mode mode, int offset, int inc,
> + unsigned iters, unsigned remainder)
> +{
> +  rtx reg = gen_reg_rtx (mode);
> +
> +  /* First copy in chunks as large as alignment permits.  */
> +  for (unsigned int i = 0; i < iters; i++)
> +{
> +  emit_move_insn (reg, adjust_address (src, mode, offset));
> +  emit_move_insn (adjust_address (dst, mode, offset), reg);
> +  offset += inc;
> +}
> +
> +  /* Handle remaining bytes which might be smaller than the chunks
> + used above.  */
> +  if (remainder & 4)
> +{
> +  emit_move_insn (reg, adjust_address (src, SImode, offset));
> +  emit_move_insn (adjust_address (dst, SImode, offset), reg);
> +  offset += (inc < 0 ? -4 : 4);
> +  remainder -= 4;
> +}
> +  if (remainder & 2)
> +{
> +  emit_move_insn (reg, adjust_address (src, HImode, offset));
> +  emit_move_insn (adjust_address (dst, HImode, offset), reg);
> +  offset += (inc < 0 ? -2 : 2);
> +  remainder -= 2;
> +}
> +  if (remainder & 1)
> +{
> +  emit_move_insn (reg, adjust_address (src, QImode, offset));
> +  emit_move_insn (adjust_address (dst, QImode, offset), reg);
> +}
> +}
> +
> +/* Expand cpymem/movmem, as from __builtin_memcpy/memmove.
> +   OPERANDS are the same as the cpymem/movmem patterns.
> +   IS_MOVE is true if this is a memmove, false for memcpy.
> +   Return true if we successfully expanded, or false if we cannot
> +   and must punt to a libcall.  */
> +
> 

Re: [PATCH v2] bpf: add inline memmove and memcpy expansion

2024-02-20 Thread Jose E. Marchesi


Hi Faust.

> +bool
> +bpf_expand_cpymem (rtx *operands, bool is_move)
> +{
> +  /* Size must be constant for this expansion to work.  */
> +  if (!CONST_INT_P (operands[2]))
> +{
> +  const char *name = is_move ? "memmove" : "memcpy";
> +  if (flag_building_libgcc)
> + warning (RTL_LOCATION (operands[2]),
> +  "could not expand call to %<__builtin_%s%> inline: "
> +  "size must be constant", name);
> +  else
> + error ("could not expand call to %<__builtin_%s%> inline: "
> +"size must be constant", name);
> +  return false;
> +}

I think you want to use warning_at and error_at above...  the first
argument to `warning' (and second to warning_at) is not a location but
an OPT_W* value.  You should pass 0 to the opt argument in this case as
there is no -W option to handle this warning.

Also, I would not mention 'expand' in the error/warning message, as it
is a GCC internal concept.  I would use perhaps "could not inline call
to %<__builtin_%s%>".

> +  /* Alignment is a CONST_INT.  */
> +  gcc_assert (CONST_INT_P (operands[3]));
> +
> +  rtx dst = operands[0];
> +  rtx src = operands[1];
> +  rtx size = operands[2];
> +  unsigned HOST_WIDE_INT size_bytes = UINTVAL (size);
> +  unsigned align = UINTVAL (operands[3]);
> +  enum machine_mode mode;
> +  switch (align)
> +{
> +case 1: mode = QImode; break;
> +case 2: mode = HImode; break;
> +case 4: mode = SImode; break;
> +case 8: mode = DImode; break;
> +default:
> +  gcc_unreachable ();
> +}
> +
> +  unsigned iters = size_bytes >> ceil_log2 (align);
> +  unsigned remainder = size_bytes & (align - 1);
> +
> +  int inc = GET_MODE_SIZE (mode);
> +  rtx_code_label *fwd_label, *done_label;
> +  if (is_move)
> +{
> +  /* For memmove, be careful of overlap.  It is not a concern for memcpy.
> +  To handle overlap, we check (at runtime) if SRC < DST, and if so do
> +  the move "backwards" starting from SRC + SIZE.  */
> +  fwd_label = gen_label_rtx ();
> +  done_label = gen_label_rtx ();
> +
> +  rtx dst_addr = copy_to_mode_reg (Pmode, XEXP (dst, 0));
> +  rtx src_addr = copy_to_mode_reg (Pmode, XEXP (src, 0));
> +  emit_cmp_and_jump_insns (src_addr, dst_addr, GEU, NULL_RTX, Pmode,
> +true, fwd_label, profile_probability::even ());
> +
> +  /* Emit the "backwards" unrolled loop.  */
> +  emit_move_loop (src, dst, mode, size_bytes, -inc, iters, remainder);
> +  emit_jump_insn (gen_jump (done_label));
> +  emit_barrier ();
> +
> +  emit_label (fwd_label);
> +}
> +
> +  emit_move_loop (src, dst, mode, 0, inc, iters, remainder);
> +
> +  if (is_move)
> +emit_label (done_label);
> +
> +  return true;
> +}
> +
>  /* Finally, build the GCC target.  */
>  
>  struct gcc_target targetm = TARGET_INITIALIZER;
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 50df1aaa3e2..ca677bc6b50 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -627,4 +627,40 @@ (define_insn "ldabs"
>"{ldabs\t%0|r0 = *( *) skb[%0]}"
>[(set_attr "type" "ld")])
>  
> +;;; memmove and memcopy
> +
> +;; 0 is dst
> +;; 1 is src
> +;; 2 is size of copy in bytes
> +;; 3 is alignment
> +
> +(define_expand "cpymemdi"
> +  [(match_operand:BLK 0 "memory_operand")
> +   (match_operand:BLK 1 "memory_operand")
> +   (match_operand:DI 2 "general_operand")
> +   (match_operand:DI 3 "immediate_operand")]
> +   ""
> +{
> +  if (bpf_expand_cpymem (operands, false))
> +DONE;
> +  FAIL;
> +})
> +
> +;; 0 is dst
> +;; 1 is src
> +;; 2 is size of copy in bytes
> +;; 3 is alignment
> +
> +(define_expand "movmemdi"
> +  [(match_operand:BLK 0 "memory_operand")
> +   (match_operand:BLK 1 "memory_operand")
> +   (match_operand:DI 2 "general_operand")
> +   (match_operand:DI 3 "immediate_operand")]
> +   ""
> +{
> +  if (bpf_expand_cpymem (operands, true))
> +DONE;
> +  FAIL;
> +})
> +
>  (include "atomic.md")
> diff --git a/gcc/testsuite/gcc.target/bpf/memcpy-1.c 
> b/gcc/testsuite/gcc.target/bpf/memcpy-1.c
> new file mode 100644
> index 000..6c9707f24e8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/memcpy-1.c
> @@ -0,0 +1,26 @@
> +/* Ensure memcpy is expanded inline rather than emitting a libcall.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +struct context {
> + unsigned int data;
> + unsigned int data_end;
> + unsigned int data_meta;
> + unsigned int ingress;
> + unsigned int queue_index;
> + unsigned int egress;
> +};
> +
> +void
> +cpy_1(struct context *ctx)
> +{
> +  void *data = (void *)(long)ctx->data;
> +  char *dest;
> +  dest = data;
> +  dest += 16;
> +
> +  __builtin_memcpy (dest, data, 8);
> +}
> +
> +/* { dg-final { scan-assembler-times "call" 0 } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/memmove-1.c 
> b/gcc/testsuite/gcc.target/bpf/memmove-1.c
> new file mode 100644
> index 000..3b8ba82639e
> --- /dev/null
> +++ 

Re: [PATCH] bpf: Add documentation for the -mcpu option

2024-02-20 Thread Jose E. Marchesi


Hello Will.

Thanks for the patch.
I just installed it on your behalf.

> Add documentation describing the meaning and values for the -mcpu
> command-line option.
>
> Tested for bpf-unknown-none on x86_64-linux-gnu host.
>
> gcc/ChangeLog:
>
>   * config/bpf/bpf.opt: Add help information for -mcpu.
>
> Signed-off-by: Will Hawkins 
> ---
>  gcc/config/bpf/bpf.opt | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
> index bc5b2220116..acfddebdad7 100644
> --- a/gcc/config/bpf/bpf.opt
> +++ b/gcc/config/bpf/bpf.opt
> @@ -77,9 +77,11 @@ Enable signed move and memory load instructions.
>  
>  mcpu=
>  Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4)
> +Select the eBPF ISA version to target in code generation.
>  
>  Enum
>  Name(bpf_isa) Type(enum bpf_isa_version)
> +Valid ISA versions (for use with the -mcpu= option)
>  
>  EnumValue
>  Enum(bpf_isa) String(v1) Value(ISA_V1)


Re: [PATCH] bpf: add inline memmove and memcpy expansion

2024-02-20 Thread Jose E. Marchesi


Hi David.
Thanks for the patch.

See a couple of comments regarding error handling below.

> BPF programs are not typically linked, which means we cannot fall back
> on library calls to implement __builtin_{memmove,memcpy} and should
> always expand them inline if possible.
>
> GCC already successfully expands these builtins inline in many cases,
> but failed to do so for a few for simple cases involving overlapping
> memmove in the kernel BPF selftests and was instead emitting a libcall.
>
> This patch implments a simple inline expansion of memcpy and memmove in

s/implments/implements/.

> the BPF backend in a verifier-friendly way, with the caveat that the
> size must be an integer constant, which is also required by clang.
>
> Tested for bpf-unknown-none on x86_64-linux-gnu host.
>
> Also tested against the BPF verifier by compiling and loading a test
> program with overlapping memmove (essentially the memmove-1.c test)
> which failed before due to a libcall, and now successfully loads and
> passes the verifier.
>
> gcc/
>
>   * config/bpf/bpf-protos.h (bpf_expand_cpymem): New.
>   * config/bpf/bpf.cc: (emit_move_loop, CPYMEM_EXPAND_ERR)
>   (bpf_expand_cpymem): New.
>   * config/bpf/bpf.md: (cpymemdi, movmemdi): New define_expands.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/memcpy-1.c: New test.
>   * gcc.target/bpf/memmove-1.c: New test.
>   * gcc.target/bpf/memmove-2.c: New test.
> ---
>  gcc/config/bpf/bpf-protos.h  |   2 +
>  gcc/config/bpf/bpf.cc| 129 +++
>  gcc/config/bpf/bpf.md|  36 +++
>  gcc/testsuite/gcc.target/bpf/memcpy-1.c  |  26 +
>  gcc/testsuite/gcc.target/bpf/memmove-1.c |  46 
>  gcc/testsuite/gcc.target/bpf/memmove-2.c |  23 
>  6 files changed, 262 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memcpy-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memmove-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/memmove-2.c
>
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index 46d950bd990..366acb87ae4 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -35,4 +35,6 @@ const char *bpf_add_core_reloc (rtx *operands, const char 
> *templ);
>  class gimple_opt_pass;
>  gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
>  
> +bool bpf_expand_cpymem (rtx *, bool);
> +
>  #endif /* ! GCC_BPF_PROTOS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index d6ca47eeecb..c90d29d12ff 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1184,6 +1184,135 @@ bpf_use_by_pieces_infrastructure_p (unsigned 
> HOST_WIDE_INT size,
>  #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
>bpf_use_by_pieces_infrastructure_p
>  
> +/* Helper for bpf_expand_cpymem.  Emit an unrolled loop moving the bytes
> +   from SRC to DST.  */
> +
> +static void
> +emit_move_loop (rtx src, rtx dst, machine_mode mode, int offset, int inc,
> + unsigned iters, unsigned remainder)
> +{
> +  rtx reg = gen_reg_rtx (mode);
> +
> +  /* First copy in chunks as large as alignment permits.  */
> +  for (unsigned int i = 0; i < iters; i++)
> +{
> +  emit_move_insn (reg, adjust_address (src, mode, offset));
> +  emit_move_insn (adjust_address (dst, mode, offset), reg);
> +  offset += inc;
> +}
> +
> +  /* Handle remaining bytes which might be smaller than the chunks
> + used above.  */
> +  if (remainder & 4)
> +{
> +  emit_move_insn (reg, adjust_address (src, SImode, offset));
> +  emit_move_insn (adjust_address (dst, SImode, offset), reg);
> +  offset += (inc < 0 ? -4 : 4);
> +  remainder -= 4;
> +}
> +  if (remainder & 2)
> +{
> +  emit_move_insn (reg, adjust_address (src, HImode, offset));
> +  emit_move_insn (adjust_address (dst, HImode, offset), reg);
> +  offset += (inc < 0 ? -2 : 2);
> +  remainder -= 2;
> +}
> +  if (remainder & 1)
> +{
> +  emit_move_insn (reg, adjust_address (src, QImode, offset));
> +  emit_move_insn (adjust_address (dst, QImode, offset), reg);
> +}
> +}
> +
> +/* Error if we cannot completely expand the memcpy/memmove inline,
> +   unless we are building libgcc.  */
> +#define CPYMEM_EXPAND_ERR(LOC, MSG)  \
> +  do \
> +{
> \
> +  if (flag_building_libgcc)  
> \
> + warning (LOC, MSG " for BPF memcpy/memmove expansion; " \
> +  "a libcall will be emitted");  \
> +  else   \
> + error (MSG " for BPF memcpy/memmove expansion");\
> +} while (0);

For this error I would suggest to use a less "internal" jargon to 

Re: [PATCH] bpf: fix zero_extendqidi2 ldx template

2024-02-15 Thread Jose E. Marchesi


Hi Faust.
OK, thank you.

> Commit 77d0f9ec3809b4d2e32c36069b6b9239d301c030 inadvertently changed
> the normal asm dialect instruction template for zero_extendqidi2 from
> ldxb to ldxh. Fix that.
>
> Tested for bpf-unknown-none on x86_64-linux-gnu host.
>
> gcc/
>
>   * config/bpf/bpf.md (zero_extendqidi2): Correct asm template to
>   use ldxb instead of ldxh.
> ---
>  gcc/config/bpf/bpf.md | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 080a63cd970..50df1aaa3e2 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -292,7 +292,7 @@ (define_insn "zero_extendqidi2"
>"@
> {and\t%0,0xff|%0 &= 0xff}
> {mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff}
> -   {ldxh\t%0,%1|%0 = *(u8 *) (%1)}"
> +   {ldxb\t%0,%1|%0 = *(u8 *) (%1)}"
>[(set_attr "type" "alu,alu,ldx")])
>  
>  (define_insn "zero_extendsidi2"


[COMMITTED] bpf: emit empty epilogues in naked functions

2024-01-29 Thread Jose E. Marchesi
This patch fixes the BPF backend to not generate `exit' (return)
instructions in epilogues of functions that are declared as naked via
the corresponding compiler attribute.  Having extra exit instructions
upsets the kernel BPF verifier.

Tested in bpf-unknown-none target in x86_64-linux-gnu host.

gcc/ChangeLog

* config/bpf/bpf.cc (bpf_expand_epilogue): Do not emit a return
instruction in naked function epilogues.

gcc/testsuite/ChangeLog

* gcc.target/bpf/naked-1.c: Update test to not expect an exit
instruction in naked function.
* gcc.target/bpf/naked-2.c: New test.
---
 gcc/config/bpf/bpf.cc  |  5 ++---
 gcc/testsuite/gcc.target/bpf/naked-1.c |  1 -
 gcc/testsuite/gcc.target/bpf/naked-2.c | 10 ++
 3 files changed, 12 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/naked-2.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 9af1728d852..d6ca47eeecb 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -420,9 +420,8 @@ bpf_expand_epilogue (void)
   /* See note in bpf_expand_prologue for an explanation on why we are
  not restoring callee-saved registers in BPF.  */
 
-  /* If we ever need to do anything else than just generating a return
- instruction here, please mind the `naked' function attribute.  */
-
+  if (lookup_attribute ("naked", DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
+return;
   emit_jump_insn (gen_exit ());
 }
 
diff --git a/gcc/testsuite/gcc.target/bpf/naked-1.c 
b/gcc/testsuite/gcc.target/bpf/naked-1.c
index cbbc4c51697..dc8ac2619cc 100644
--- a/gcc/testsuite/gcc.target/bpf/naked-1.c
+++ b/gcc/testsuite/gcc.target/bpf/naked-1.c
@@ -9,4 +9,3 @@ int __attribute__((naked)) foo()
   __asm__ volatile ("@ naked");
 }
 /* { dg-final { scan-assembler "\t@ naked" } } */
-/* { dg-final { scan-assembler "\texit\n" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/naked-2.c 
b/gcc/testsuite/gcc.target/bpf/naked-2.c
new file mode 100644
index 000..25aebf84755
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/naked-2.c
@@ -0,0 +1,10 @@
+/* Verify that __attribute__((naked)) produces functions without implicit
+   `exit' instructions in the epilogue.  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int __attribute__((naked)) foo()
+{
+  __asm__ volatile ("exit");
+}
+/* { dg-final { scan-assembler-times "\texit" 1 } } */
-- 
2.30.2



[COMMITTED] bpf: add constant pointer to helper-skb-ancestor-cgroup-id.c test

2024-01-27 Thread Jose E. Marchesi
The purpose of this test is to make sure that constant propagation is
achieved with the proper optimization level, so a BPF call instruction
to a kernel helper is generated.  This patch updates the patch so it
also covers kernel helpers defined with constant static pointers.

The motivation for this patch is:

  
https://lore.kernel.org/bpf/20240127185031.29854-1-jose.march...@oracle.com/T/#u

Tested in bpf-unknown-none target x86_64-linux-gnu host.

gcc/testsuite/ChangeLog

* gcc.target/bpf/helper-skb-ancestor-cgroup-id.c: Add constant
version of kernel helper static pointer.
---
 gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c 
b/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c
index 693f390b9bb..075dbe6f852 100644
--- a/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c
+++ b/gcc/testsuite/gcc.target/bpf/helper-skb-ancestor-cgroup-id.c
@@ -5,6 +5,7 @@
 
 struct __sk_buff;
 static uint64_t (*bpf_skb_ancestor_cgroup_id)(struct __sk_buff *skb, int 
ancestor_level) = (void *) 83;
+static uint64_t (* const const_bpf_skb_ancestor_cgroup_id)(struct __sk_buff 
*skb, int ancestor_level) = (void *) 84;
 
 void
 foo ()
@@ -13,7 +14,9 @@ foo ()
   void *skb;
   int ancestor_level;
 
-  ret = bpf_skb_ancestor_cgroup_id (skb, ancestor_level);
+  ret = bpf_skb_ancestor_cgroup_id (skb, ancestor_level)
++ const_bpf_skb_ancestor_cgroup_id (skb, ancestor_level);
 }
 
 /* { dg-final { scan-assembler "call\t83" } } */
+/* { dg-final { scan-assembler "call\t84" } } */
-- 
2.30.2



Re: [r14-5930 Regression] FAIL: gcc.c-torture/compile/libcall-2.c -Os (test for excess errors) on Linux/x86_64

2023-12-04 Thread Jose E. Marchesi


>> mcmodel=large s not supported (yet) on any Darwin arch [PR90698], so
> the test needs skipping or xfailing, I think (either way with a
> reference to the PR).
>
> Pushed as 
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=b74981b5cf32ebf4bfffd25e7174b5c80243447a

Thanks for fixing this.



Re: [PATCH] btf: fix PR debug/112656

2023-12-01 Thread Jose E. Marchesi


> Hi Indu.
> This is OK.  Thanks.

Oops sorry scratch that, I am no reviewer for the BTF area.
Will have to wait for Faust or someone else to chime in :)

>
>> PR debug/112656 - btf: function prototypes generated with name
>>
>> With this patch, all BTF_KIND_FUNC_PROTO will appear anonymous in the
>> generated BTF section.
>>
>> As noted in the discussion in the bugzilla, the number of
>> BTF_KIND_FUNC_PROTO types output varies across targets (BPF with -mco-re
>> vs non-BPF targets).  Hence the check in the test case merely checks
>> that all BTF_KIND_FUNC_PROTO appear anonymous.
>>
>> gcc/ChangeLog:
>>
>>  PR debug/112656
>> * btfout.cc (btf_asm_type): Fixup ctti_name for all
>>  BTF types of kind BTF_KIND_FUNC_PROTO.
>>
>> gcc/testsuite/ChangeLog:
>>
>>  PR debug/112656
>> * gcc.dg/debug/btf/btf-function-7.c: New test.
>>
>>
>> Testing notes:
>>   - bootstrapped and reg tested on x86_64
>>   - No regressions in btf.exp on BPF target
>>
>> ---
>>  gcc/btfout.cc |  4 
>>  .../gcc.dg/debug/btf/btf-function-7.c | 19 +++
>>  2 files changed, 23 insertions(+)
>>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
>>
>> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
>> index 1c25404b2c0..a5e0d640e19 100644
>> --- a/gcc/btfout.cc
>> +++ b/gcc/btfout.cc
>> @@ -820,6 +820,10 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
>>  btf_kind = BTF_KIND_ENUM64;
>> }
>>  
>> +  /* PR debug/112656.  BTF_KIND_FUNC_PROTO is always anonymous.  */
>> +  if (btf_kind == BTF_KIND_FUNC_PROTO)
>> +dtd->dtd_data.ctti_name = 0;
>> +
>>dw2_asm_output_data (4, dtd->dtd_data.ctti_name,
>> "TYPE %" PRIu64 " BTF_KIND_%s '%s'",
>> get_btf_id (dtd->dtd_type), btf_kind_name (btf_kind),
>> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c 
>> b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
>> new file mode 100644
>> index 000..b560dc75650
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
>> @@ -0,0 +1,19 @@
>> +/* Test BTF for inlined functions.
>> +
>> +   See PR/112656 - btf: function prototypes generated with name
>> +   BTF_KIND_FUNC_PROTO must be anonymous.  */
>> +
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -gbtf -dA" } */
>> +
>> +/* { dg-final { scan-assembler-times "BTF_KIND_FUNC_PROTO 
>> ''\\(\[0-9a-z\]*\\)'" 0 } } */
>> +
>> +static int log_event(const char *event_name, void *dev_ptr)
>> +{
>> +  return 666;
>> +}
>> +
>> +int foo ()
>> +{
>> +  return log_event ("foobar", ((void *)0));
>> +}


Re: [PATCH] btf: fix PR debug/112656

2023-12-01 Thread Jose E. Marchesi


Hi Indu.
This is OK.  Thanks.

> PR debug/112656 - btf: function prototypes generated with name
>
> With this patch, all BTF_KIND_FUNC_PROTO will appear anonymous in the
> generated BTF section.
>
> As noted in the discussion in the bugzilla, the number of
> BTF_KIND_FUNC_PROTO types output varies across targets (BPF with -mco-re
> vs non-BPF targets).  Hence the check in the test case merely checks
> that all BTF_KIND_FUNC_PROTO appear anonymous.
>
> gcc/ChangeLog:
>
>   PR debug/112656
> * btfout.cc (btf_asm_type): Fixup ctti_name for all
>   BTF types of kind BTF_KIND_FUNC_PROTO.
>
> gcc/testsuite/ChangeLog:
>
>   PR debug/112656
> * gcc.dg/debug/btf/btf-function-7.c: New test.
>
>
> Testing notes:
>   - bootstrapped and reg tested on x86_64
>   - No regressions in btf.exp on BPF target
>
> ---
>  gcc/btfout.cc |  4 
>  .../gcc.dg/debug/btf/btf-function-7.c | 19 +++
>  2 files changed, 23 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
>
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 1c25404b2c0..a5e0d640e19 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -820,6 +820,10 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
>   btf_kind = BTF_KIND_ENUM64;
> }
>  
> +  /* PR debug/112656.  BTF_KIND_FUNC_PROTO is always anonymous.  */
> +  if (btf_kind == BTF_KIND_FUNC_PROTO)
> +dtd->dtd_data.ctti_name = 0;
> +
>dw2_asm_output_data (4, dtd->dtd_data.ctti_name,
>  "TYPE %" PRIu64 " BTF_KIND_%s '%s'",
>  get_btf_id (dtd->dtd_type), btf_kind_name (btf_kind),
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c 
> b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
> new file mode 100644
> index 000..b560dc75650
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c
> @@ -0,0 +1,19 @@
> +/* Test BTF for inlined functions.
> +
> +   See PR/112656 - btf: function prototypes generated with name
> +   BTF_KIND_FUNC_PROTO must be anonymous.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -gbtf -dA" } */
> +
> +/* { dg-final { scan-assembler-times "BTF_KIND_FUNC_PROTO 
> ''\\(\[0-9a-z\]*\\)'" 0 } } */
> +
> +static int log_event(const char *event_name, void *dev_ptr)
> +{
> +  return 666;
> +}
> +
> +int foo ()
> +{
> +  return log_event ("foobar", ((void *)0));
> +}


[COMMITTED] bpf: quote section names whenever necessary in assembly output

2023-12-01 Thread Jose E. Marchesi
In BPF section names are used to encode the kind of BPF program and
other metadata, involving all sort of non alphanumeric characters.

For example:

  /* use auto-attach format for section definition. */
  SEC("uretprobe//proc/self/exe:trigger_func2")
  int handle_uretprobe_byname(struct pt_regs *ctx)
  {
uretprobe_byname_res = 6;
return 0;
  }

The above requires to quote the section name in the output assembly
file, since otherwise the // in the name would be interpreted by the
assembler lexer as the beginning of a line comment.

This patch makes the BPF backend to emit quoted section names in
.section directives if the name requires to be quoted.  Simple section
names whose constituent characters are in the set [0-9a-zA-Z_] are
still emitted unquoted.

Tested in target bpf-unknown-none-gcc and host x86_64-linux-gnu.

gcc/ChangeLog

* config/bpf/bpf.cc (bpf_asm_named_section): New function.
(TARGET_ASM_NAMED_SECTION): Set to bpf_asm_named_section.

gcc/testsuite/ChangeLog

* gcc.target/bpf/section-name-quoting-1.c: New test.
---
 gcc/config/bpf/bpf.cc | 55 +++
 .../gcc.target/bpf/section-name-quoting-1.c   | 20 +++
 2 files changed, 75 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 4bfba289546..ffd83a73102 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1100,6 +1100,61 @@ bpf_debug_unwind_info ()
 #undef TARGET_ASM_ALIGNED_DI_OP
 #define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
 
+/* Implement target hook TARGET_ASM_NAMED_SECTION.  */
+
+static void
+bpf_asm_named_section (const char *name, unsigned int flags,
+   tree decl)
+{
+  /* In BPF section names are used to encode the kind of BPF program
+ and other metadata, involving all sort of non alphanumeric
+ characters.  This includes for example names like /foo//bar/baz.
+ This makes it necessary to quote section names to make sure the
+ assembler doesn't get confused.  For example, the example above
+ would be interpreted unqouted as a section name "/foo" followed
+ by a line comment "//bar/baz".
+
+ Note that we only quote the section name if it contains any
+ character not in the set [0-9a-zA-Z_].  This is because
+ default_elf_asm_named_section generally expects unquoted names
+ and checks for particular names like
+ __patchable_function_entries.  */
+
+  bool needs_quoting = false;
+
+  for (const char *p = name; *p != '\0'; ++p)
+if (!(*p == '_'
+  || (*p >= '0' && *p <= '9')
+  || (*p >= 'a' && *p <= 'z')
+  || (*p >= 'A' && *p <= 'Z')))
+  needs_quoting = true;
+
+  if (needs_quoting)
+{
+  char *quoted_name
+= (char *) xcalloc (1, strlen (name) * 2 + 2);
+  char *q = quoted_name;
+
+  *(q++) = '"';
+  for (const char *p = name; *p != '\0'; ++p)
+{
+  if (*p == '"' || *p == '\\')
+*(q++) = '\\';
+  *(q++) = *p;
+}
+  *(q++) = '"';
+  *(q++) = '\0';
+
+  default_elf_asm_named_section (quoted_name, flags, decl);
+  free (quoted_name);
+}
+  else
+default_elf_asm_named_section (name, flags, decl);
+}
+
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION bpf_asm_named_section
+
 /* Implement target hook small_register_classes_for_mode_p.  */
 
 static bool
diff --git a/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c 
b/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c
new file mode 100644
index 000..2fa48de23fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/section-name-quoting-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Make sure that section names that contain characters not in the set
+   [0-9a-zA-Z_] get quoted for the assembler.  */
+
+__attribute__((section ("uretprobe//proc/self/exe:trigger_func2")))
+void
+foo ()
+{
+}
+
+__attribute__((section ("trigger_func3")))
+void
+bar ()
+{
+}
+
+/* { dg-final { scan-assembler 
{\.section\t"uretprobe//proc/self/exe:trigger_func2"} } } */
+/* { dg-final { scan-assembler {\.section\ttrigger_func3} } } */
-- 
2.30.2



Re: [PATCH] bpf: change ASM_COMMENT_START to '#'

2023-11-29 Thread Jose E. Marchesi


Hi David.
OK.  Thanks.

> The BPF "pseudo-C" assembly dialect uses semi-colon (;) to separate
> statements, not to begin line comments. The GNU assembler was recently
> changed accordingly:
>
>   https://sourceware.org/pipermail/binutils/2023-November/130867.html
>
> This patch adapts the BPF backend in GCC accordingly, to use a hash (#)
> instead of semi-colon (;) for ASM_COMMENT_START. This is supported
> already in clang.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/
>   * config/bpf/bpf.h (ASM_COMMENT_START): Change from ';' to '#'.
>
> gcc/testsuite/
>   * gcc.target/bpf/core-builtin-enumvalue-opt.c: Change dg-final
>   scans to not assume a specific comment character.
>   * gcc.target/bpf/core-builtin-enumvalue.c: Likewise.
>   * gcc.target/bpf/core-builtin-type-based.c: Likewise.
>   * gcc.target/bpf/core-builtin-type-id.c: Likewise.
> ---
>  gcc/config/bpf/bpf.h |  2 +-
>  .../gcc.target/bpf/core-builtin-enumvalue-opt.c  |  8 
>  .../gcc.target/bpf/core-builtin-enumvalue.c  | 12 ++--
>  .../gcc.target/bpf/core-builtin-type-based.c |  8 
>  gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c  |  6 +++---
>  5 files changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index 1f177ec4c4e..d175e99046c 100644
> --- a/gcc/config/bpf/bpf.h
> +++ b/gcc/config/bpf/bpf.h
> @@ -393,7 +393,7 @@ enum reg_class
>  
>  /*** The Overall Framework of an Assembler File.  */
>  
> -#define ASM_COMMENT_START ";"
> +#define ASM_COMMENT_START "#"
>  
>  /* Output to assembler file text saying following lines
> may contain character constants, extra white space, comments, etc.  */
> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c 
> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
> index c87e1a3ba3b..fc3c299fe9c 100644
> --- a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue-opt.c
> @@ -26,10 +26,10 @@ unsigned long foo(void *data)
>   return 0;
>  }
>  
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_ue64\\)" 2 } } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_se64\\)" 2} } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 2 } } 
> BPF_ENUMVAL_EXISTS */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 2 } } 
> BPF_ENUMVAL_VALUE */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_ue64\\)" 2 } } */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_se64\\)" 2} } */
> +/* { dg-final { scan-assembler-times "0xa\[\t \]+\[^\n\]*bpfcr_kind" 2 } } 
> BPF_ENUMVAL_EXISTS */
> +/* { dg-final { scan-assembler-times "0xb\[\t \]+\[^\n\]*bpfcr_kind" 2 } } 
> BPF_ENUMVAL_VALUE */
>  
>  /* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0\"\\)" 4 } } */
>  
> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c 
> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
> index 2f16903b8d6..23dfd8a10bf 100644
> --- a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
> @@ -40,12 +40,12 @@ int foo(void *data)
>   return 0;
>  }
>  
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_ue64\\)" 5 } } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_se64\\)" 5} } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_ue\\)" 5 } } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0x\[0-9a-f\]+\t; bpfcr_type 
> \\(named_se\\)" 5} } */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 12 } } 
> BPF_ENUMVAL_EXISTS */
> -/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 8 } } 
> BPF_ENUMVAL_VALUE */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_ue64\\)" 5 } } */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_se64\\)" 5} } */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_ue\\)" 5 } } */
> +/* { dg-final { scan-assembler-times "bpfcr_type \\(named_se\\)" 5} } */
> +/* { dg-final { scan-assembler-times "0xa\[\t \]+\[^\n\]*bpfcr_kind" 12 } } 
> BPF_ENUMVAL_EXISTS */
> +/* { dg-final { scan-assembler-times "0xb\[\t \]+\[^\n\]*bpfcr_kind" 8 } } 
> BPF_ENUMVAL_VALUE */
>  
>  /* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0\"\\)" 8 } } */
>  /* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"1\"\\)" 8 } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c 
> b/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c
> index 16b48ae0a00..74a8d5a14d9 100644
> --- a/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c
> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c
> @@ 

Re: [r14-5930 Regression] FAIL: gcc.c-torture/compile/libcall-2.c -Os (test for excess errors) on Linux/x86_64

2023-11-29 Thread Jose E. Marchesi


> On Wed, Nov 29, 2023 at 09:20:55AM +0100, Jose E. Marchesi wrote:
>> OK to the patch below?
>> 
>> >From a697f9e9442d96d3eda228b825dd8e8e06206c03 Mon Sep 17 00:00:00 2001
>> From: "Jose E. Marchesi" 
>> Date: Wed, 29 Nov 2023 09:16:48 +0100
>> Subject: [PATCH] testsuite: move gcc.c-torture/compile/libcall-2.c to
>>  gcc.target/i386/libcall-1.c
>> 
>> This patch relocates a test that is really x86 specific, and changes
>> it to use check_effective_target_int128.
>> 
>> gcc/testsuite/ChangeLog
>> 
>>  * gcc.c-torture/compile/libcall-2.c: Remove.
>>  * gcc.target/i386/libcall-1.c: Moved from
>>  gcc.c-torture/compile/libcall-2.c and adapted to use
>>  effective-target for int128_t.
>
> Yes.

Thanks.  Pushed.

>
>> diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
>> b/gcc/testsuite/gcc.target/i386/libcall-1.c
>> similarity index 50%
>> rename from gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> rename to gcc/testsuite/gcc.target/i386/libcall-1.c
>> index 9b889172025..8bd6684a925 100644
>> --- a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> +++ b/gcc/testsuite/gcc.target/i386/libcall-1.c
>> @@ -1,10 +1,8 @@
>>  /* Make sure that external refences for libcalls are generated even for
>> indirect calls.  */
>>  
>> -/* { dg-do compile } */
>> -/* __int128 is not supported in x86 -m32.  */
>> -/* { dg-skip-if "" { ! { x86_64-*-* && { ! ilp32 } } } } */
>> -/* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
>> +/* { dg-do compile { target int128 } } */
>> +/* { dg-options "-O2 -mcmodel=large" } */
>>  /* { dg-final { scan-assembler "globl\t__divti3" } } */
>>  
>>  __int128 a, b; void foo () { a = a / b; }
>> -- 
>> 2.30.2
>
>   Jakub


Re: [r14-5930 Regression] FAIL: gcc.c-torture/compile/libcall-2.c -Os (test for excess errors) on Linux/x86_64

2023-11-29 Thread Jose E. Marchesi


> On Wed, Nov 29, 2023 at 07:51:15AM +0100, Jose E. Marchesi wrote:
>> > FAIL: gcc.c-torture/compile/libcall-2.c   -O1  (test for excess errors)
>> > FAIL: gcc.c-torture/compile/libcall-2.c -O2 -flto
>> > -fno-use-linker-plugin -flto-partition=none (test for excess errors)
>> > FAIL: gcc.c-torture/compile/libcall-2.c -O2 -flto -fuse-linker-plugin
>> > -fno-fat-lto-objects (test for excess errors)
>> > FAIL: gcc.c-torture/compile/libcall-2.c   -O2  (test for excess errors)
>> > FAIL: gcc.c-torture/compile/libcall-2.c   -O3 -g  (test for excess errors)
>> > FAIL: gcc.c-torture/compile/libcall-2.c   -Os  (test for excess errors)
>> 
>> Sorry about the regression.
>> 
>> I installed the patch below to skip the test if the target is not x86_64
>> in lp64, as obvious.  This should fix the issue.
>> 
>> >From 4ed0740c6e807460ce79a351094329fdeb551545 Mon Sep 17 00:00:00 2001
>> From: "Jose E. Marchesi" 
>> Date: Wed, 29 Nov 2023 07:44:59 +0100
>> Subject: [PATCH] testsuite: fix gcc.c-torture/compile/libcall-2.c in -m32
>> 
>> This test relies on having __int128 in x86_64 targets, which is only
>> available in -m64.
>> 
>> gcc/testsuite/ChangeLog
>> 
>>  * gcc.c-torture/compile/libcall-2.c: Skip test in -m32.
>> ---
>>  gcc/testsuite/gcc.c-torture/compile/libcall-2.c | 2 ++
>>  1 file changed, 2 insertions(+)
>> 
>> diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
>> b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> index b33944c83ff..9b889172025 100644
>> --- a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> +++ b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> @@ -2,6 +2,8 @@
>> indirect calls.  */
>>  
>>  /* { dg-do compile } */
>> +/* __int128 is not supported in x86 -m32.  */
>> +/* { dg-skip-if "" { ! { x86_64-*-* && { ! ilp32 } } } } */
>>  /* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
>>  /* { dg-final { scan-assembler "globl\t__divti3" } } */
>
> This is not correct.
> When a test uses __int128, it should be guarded with int128 effective
> target.
> But, as the test doesn't really test anything on non-x86 nor ia32,
> it doesn't belong to gcc.c-torture/compile/ at all, it is x86 specific
> test which should be moved to gcc.target/i386/libcall-1.c
> And, should have
> /* { dg-do compile { target int128 } } */
> /* { dg-options "-O2 -mcmodel=large" } */
> /* { dg-final { scan-assembler "globl\t__divti3" } } */
> I guess no need to bother with the extra guard for -mcmodel=large,
> because -m32/-mx32 don't have __int128 support, and x86_64-*-*
> is incorrect anyway (because with that target one can have all
> of -m32/-m64/-mx32).

OK to the patch below?

>From a697f9e9442d96d3eda228b825dd8e8e06206c03 Mon Sep 17 00:00:00 2001
From: "Jose E. Marchesi" 
Date: Wed, 29 Nov 2023 09:16:48 +0100
Subject: [PATCH] testsuite: move gcc.c-torture/compile/libcall-2.c to
 gcc.target/i386/libcall-1.c

This patch relocates a test that is really x86 specific, and changes
it to use check_effective_target_int128.

gcc/testsuite/ChangeLog

* gcc.c-torture/compile/libcall-2.c: Remove.
* gcc.target/i386/libcall-1.c: Moved from
gcc.c-torture/compile/libcall-2.c and adapted to use
effective-target for int128_t.
---
 .../compile/libcall-2.c => gcc.target/i386/libcall-1.c} | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)
 rename gcc/testsuite/{gcc.c-torture/compile/libcall-2.c => 
gcc.target/i386/libcall-1.c} (50%)

diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
b/gcc/testsuite/gcc.target/i386/libcall-1.c
similarity index 50%
rename from gcc/testsuite/gcc.c-torture/compile/libcall-2.c
rename to gcc/testsuite/gcc.target/i386/libcall-1.c
index 9b889172025..8bd6684a925 100644
--- a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
+++ b/gcc/testsuite/gcc.target/i386/libcall-1.c
@@ -1,10 +1,8 @@
 /* Make sure that external refences for libcalls are generated even for
indirect calls.  */
 
-/* { dg-do compile } */
-/* __int128 is not supported in x86 -m32.  */
-/* { dg-skip-if "" { ! { x86_64-*-* && { ! ilp32 } } } } */
-/* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -mcmodel=large" } */
 /* { dg-final { scan-assembler "globl\t__divti3" } } */
 
 __int128 a, b; void foo () { a = a / b; }
-- 
2.30.2



Re: [r14-5930 Regression] FAIL: gcc.c-torture/compile/libcall-2.c -Os (test for excess errors) on Linux/x86_64

2023-11-28 Thread Jose E. Marchesi


> On Linux/x86_64,
>
> f31a019d1161ec78846473da743aedf49cca8c27 is the first bad commit
> commit f31a019d1161ec78846473da743aedf49cca8c27
> Author: Jose E. Marchesi 
> Date:   Fri Nov 24 06:30:28 2023 +0100
>
> Emit funcall external declarations only if actually used.
>
> caused
>
> FAIL: gcc.c-torture/compile/libcall-2.c   -O0  (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c   -O1  (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c -O2 -flto
> -fno-use-linker-plugin -flto-partition=none (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c -O2 -flto -fuse-linker-plugin
> -fno-fat-lto-objects (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c   -O2  (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c   -O3 -g  (test for excess errors)
> FAIL: gcc.c-torture/compile/libcall-2.c   -Os  (test for excess errors)

Sorry about the regression.

I installed the patch below to skip the test if the target is not x86_64
in lp64, as obvious.  This should fix the issue.

>From 4ed0740c6e807460ce79a351094329fdeb551545 Mon Sep 17 00:00:00 2001
From: "Jose E. Marchesi" 
Date: Wed, 29 Nov 2023 07:44:59 +0100
Subject: [PATCH] testsuite: fix gcc.c-torture/compile/libcall-2.c in -m32

This test relies on having __int128 in x86_64 targets, which is only
available in -m64.

gcc/testsuite/ChangeLog

* gcc.c-torture/compile/libcall-2.c: Skip test in -m32.
---
 gcc/testsuite/gcc.c-torture/compile/libcall-2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
index b33944c83ff..9b889172025 100644
--- a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
@@ -2,6 +2,8 @@
indirect calls.  */
 
 /* { dg-do compile } */
+/* __int128 is not supported in x86 -m32.  */
+/* { dg-skip-if "" { ! { x86_64-*-* && { ! ilp32 } } } } */
 /* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
 /* { dg-final { scan-assembler "globl\t__divti3" } } */
 
-- 
2.30.2


Re: [PATCH] Emit funcall external declarations only if actually used.

2023-11-28 Thread Jose E. Marchesi


>> "Jose E. Marchesi"  writes:
>>> There are many places in GCC where alternative local sequences are
>>> tried in order to determine what is the cheapest or best alternative
>>> to use in the current target.  When any of these sequences involve a
>>> libcall, the current implementation of emit_library_call_value_1
>>> introduce a side-effect consisting on emitting an external declaration
>>> for the funcall (such as __divdi3) which is thus emitted even if the
>>> sequence that does the libcall is not retained.
>>>
>>> This is problematic in targets such as BPF, because the kernel loader
>>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>>> object unloadable.  Note that BPF objects are not linked before being
>>> loaded.
>>>
>>> This patch changes asssemble_external_libcall to defer emitting
>>> declarations of external libcall symbols, by saving the call tree
>>> nodes in a temporary list pending_libcall_symbols and letting
>>> process_pending_assembly_externals to emit them only if they have been
>>> referenced.  Solution suggested and sketched by Richard Sandiford.
>>>
>>> Regtested in x86_64-linux-gnu.
>>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>>>
>>> gcc/ChangeLog
>>>
>>> * varasm.cc (pending_libcall_symbols): New variable.
>>> (process_pending_assemble_externals): Process
>>> pending_libcall_symbols.
>>> (assemble_external_libcall): Defer emitting external libcall
>>> symbols to process_pending_assemble_externals.
>>>
>>> gcc/testsuite/ChangeLog
>>>
>>> * gcc.target/bpf/divmod-libcall-1.c: New test.
>>> * gcc.target/bpf/divmod-libcall-2.c: Likewise.
>>> * gcc.c-torture/compile/libcall-2.c: Likewise.
>>
>> OK, thanks.
>
> Thank you.
> Pushed.

I installed the following fix, since the built got broken in targets
that do not define ASM_OUTPUT_EXTERNAL.

diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index deb7eab7af9..167aea87091 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -2607,7 +2607,9 @@ assemble_external_libcall (rtx fun)
   /* Declare library function name external when first used, if nec.  */
   if (! SYMBOL_REF_USED (fun))
 {
+#ifdef ASM_OUTPUT_EXTERNAL
   gcc_assert (!pending_assemble_externals_processed);
+#endif
   SYMBOL_REF_USED (fun) = 1;
   /* Make sure the libcall symbol is in the symtab so any
  reference to it will mark its tree node as referenced, via
-- 
2.30.2


>
>> Richard
>>
>>> ---
>>>  .../gcc.c-torture/compile/libcall-2.c |  8 +++
>>>  .../gcc.target/bpf/divmod-libcall-1.c | 19 
>>>  .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
>>>  gcc/varasm.cc | 22 ++-
>>>  4 files changed, 64 insertions(+), 1 deletion(-)
>>>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>>>
>>> diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
>>> b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>> new file mode 100644
>>> index 000..b33944c83ff
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>> @@ -0,0 +1,8 @@
>>> +/* Make sure that external refences for libcalls are generated even for
>>> +   indirect calls.  */
>>> +
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
>>> +/* { dg-final { scan-assembler "globl\t__divti3" } } */
>>> +
>>> +__int128 a, b; void foo () { a = a / b; }
>>> diff --git a/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c 
>>> b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>> new file mode 100644
>>> index 000..7481076602a
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>> @@ -0,0 +1,19 @@
>>> +/* This test makes sure that no spurious external symbol declarations are
>>> +   emitted for libcalls in tried but eventually not used code sequences.  
>>> */
>>> +
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O2 -mcpu=v3" } */
>>> +/* { dg-final { scan-assembler-not "global\t__divdi3" } } */
>>> +/* { dg-fina

Re: bpf: Throw error when external libcalls are generated.

2023-11-28 Thread Jose E. Marchesi


> Hi Cuper.
> OK. Thanks for the patch.

This commit is breaking the BPF build, because libgcc emits libcalls to
__builtin_abort.  We need to rethink this.

Please revert:

  commit faf5b148588bd7fbb60ec669aefa704044037cdc
  Author: Cupertino Miranda 
  Date:   Thu Nov 23 22:28:01 2023 +

Thanks!

>
>> Hi everyone,
>>
>> The attached patch is a temporary solution for the lack of proper linker
>> and external library linking of the eBPF platform.
>> Any calls created by the compiler, that would usually be defined within
>> libgcc, will endup being undefined in bpftool, when GCC the compiled
>> code is passed.
>>
>> This patch anticipates that error to the compiler, by verifiying if
>> any of those calls are being generated, and reporting as an error.
>>
>> Looking forward to your comments.
>>
>> Cheers,
>> Cupertino
>>
>> commit c2110ae497c7ff83c309f172bc265973652b760d
>> Author: Cupertino Miranda 
>> Date:   Thu Nov 23 22:28:01 2023 +
>>
>> This patch enables errors when external calls are created.
>> 
>> When architectural limitations or usage of builtins implies the compiler
>> to create function calls to external libraries that implement the
>> functionality, GCC will now report an error claiming that this function
>> calls are not compatible with eBPF target.
>> Examples of those are the usage of __builtin_memmove and a sign division
>> in BPF ISA v3 or below that will require to call __divdi3.
>> This is currently an eBPF limitation which does not support linking of
>> object files but rather "raw" non linked ones. Those object files are
>> loaded and relocated by libbpf and the kernel.
>> 
>> gcc/ChangeLog:
>> * config/bpf/bpf.cc (bpf_output_call): Report error in case the
>> function call is for a builtin.
>> (bpf_external_libcall): Added target hook to detect and report
>> error when other external calls that are not builtins.
>>
>> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
>> index 0c9d5257c384..1c84113055b1 100644
>> --- a/gcc/config/bpf/bpf.cc
>> +++ b/gcc/config/bpf/bpf.cc
>> @@ -744,6 +744,15 @@ bpf_output_call (rtx target)
>>  xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
>>  output_asm_insn ("call\t%0", xops);
>>}
>> +else if (fndecl_built_in_p (decl))
>> +  {
>> +/* For now lets report this as an error while we are not able to
>> +   link eBPF object files.  In particular with libgcc.  */
>> +tree name = DECL_NAME (decl);
>> +error ("call to external builtin %s in function, which is not 
>> supported by "
>> +   "eBPF", name != NULL_TREE ? IDENTIFIER_POINTER (name) : 
>> "(anon)");
>> +output_asm_insn ("call 0", NULL);
>> +  }
>>  else
>>output_asm_insn ("call\t%0", );
>>  
>> @@ -763,6 +772,18 @@ bpf_output_call (rtx target)
>>return "";
>>  }
>>  
>> +static void
>> +bpf_external_libcall (rtx fun)
>> +{
>> +  tree decl = SYMBOL_REF_DECL (fun);
>> +  tree name = DECL_NAME (decl);
>> +  error ("call to external libcall %s in function, which is not supported 
>> by "
>> + "eBPF", name != NULL_TREE ? IDENTIFIER_POINTER (name) : "(anon)");
>> +}
>> +
>> +#undef  TARGET_ASM_EXTERNAL_LIBCALL
>> +#define TARGET_ASM_EXTERNAL_LIBCALL bpf_external_libcall
>> +
>>  /* Print register name according to assembly dialect.  In normal
>> syntax registers are printed like %rN where N is the register
>> number.
>> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c 
>> b/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
>> index 4036570ac601..fec720584e48 100644
>> --- a/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
>> +++ b/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
>> @@ -6,7 +6,7 @@ foo (int *p, int *expected, int desired)
>>  {
>>return __atomic_compare_exchange (p, expected, , 0,
>>  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
>> -}
>> +} /* { dg-error "call to external builtin" } */
>>  
>>  int
>>  foo64 (long *p, long *expected, long desired)
>> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c 
>> b/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
>> index 044a2f76474b..ea1b8e48928a 100644
>> --- a/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
>> +++ b/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
>> @@ -9,7 +9,7 @@ long
>>  test_atomic_fetch_add (long x)
>>  {
>>return __atomic_fetch_add (, x, __ATOMIC_ACQUIRE);
>> -}
>> +} /* { dg-error "call to external builtin" } */
>>  
>>  long
>>  test_atomic_fetch_sub (long x)
>> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-op-3.c 
>> b/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
>> index b2ce28926347..fefafd6b748f 100644
>> --- a/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
>> +++ b/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
>> @@ -20,7 +20,7 @@ void
>>  test_atomic_and (int x)
>>  {
>>__atomic_and_fetch (, x, __ATOMIC_ACQUIRE);
>> 

Re: [PATCH] Emit funcall external declarations only if actually used.

2023-11-28 Thread Jose E. Marchesi


> "Jose E. Marchesi"  writes:
>> There are many places in GCC where alternative local sequences are
>> tried in order to determine what is the cheapest or best alternative
>> to use in the current target.  When any of these sequences involve a
>> libcall, the current implementation of emit_library_call_value_1
>> introduce a side-effect consisting on emitting an external declaration
>> for the funcall (such as __divdi3) which is thus emitted even if the
>> sequence that does the libcall is not retained.
>>
>> This is problematic in targets such as BPF, because the kernel loader
>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>> object unloadable.  Note that BPF objects are not linked before being
>> loaded.
>>
>> This patch changes asssemble_external_libcall to defer emitting
>> declarations of external libcall symbols, by saving the call tree
>> nodes in a temporary list pending_libcall_symbols and letting
>> process_pending_assembly_externals to emit them only if they have been
>> referenced.  Solution suggested and sketched by Richard Sandiford.
>>
>> Regtested in x86_64-linux-gnu.
>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>>
>> gcc/ChangeLog
>>
>>  * varasm.cc (pending_libcall_symbols): New variable.
>>  (process_pending_assemble_externals): Process
>>  pending_libcall_symbols.
>>  (assemble_external_libcall): Defer emitting external libcall
>>  symbols to process_pending_assemble_externals.
>>
>> gcc/testsuite/ChangeLog
>>
>>  * gcc.target/bpf/divmod-libcall-1.c: New test.
>>  * gcc.target/bpf/divmod-libcall-2.c: Likewise.
>>  * gcc.c-torture/compile/libcall-2.c: Likewise.
>
> OK, thanks.

Thank you.
Pushed.

> Richard
>
>> ---
>>  .../gcc.c-torture/compile/libcall-2.c |  8 +++
>>  .../gcc.target/bpf/divmod-libcall-1.c | 19 
>>  .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
>>  gcc/varasm.cc | 22 ++-
>>  4 files changed, 64 insertions(+), 1 deletion(-)
>>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>>
>> diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
>> b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> new file mode 100644
>> index 000..b33944c83ff
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>> @@ -0,0 +1,8 @@
>> +/* Make sure that external refences for libcalls are generated even for
>> +   indirect calls.  */
>> +
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
>> +/* { dg-final { scan-assembler "globl\t__divti3" } } */
>> +
>> +__int128 a, b; void foo () { a = a / b; }
>> diff --git a/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c 
>> b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>> new file mode 100644
>> index 000..7481076602a
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>> @@ -0,0 +1,19 @@
>> +/* This test makes sure that no spurious external symbol declarations are
>> +   emitted for libcalls in tried but eventually not used code sequences.  */
>> +
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -mcpu=v3" } */
>> +/* { dg-final { scan-assembler-not "global\t__divdi3" } } */
>> +/* { dg-final { scan-assembler-not "global\t__moddi3" } } */
>> +
>> +int
>> +foo (unsigned int len)
>> +{
>> +  return ((unsigned long)len) * 234 / 5;
>> +}
>> +
>> +int
>> +bar (unsigned int len)
>> +{
>> +  return ((unsigned long)len) * 234 % 5;
>> +}
>> diff --git a/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c 
>> b/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>> new file mode 100644
>> index 000..792d689395a
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>> @@ -0,0 +1,16 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -mcpu=v3" } */
>> +/* { dg-final { scan-assembler "global\t__divdi3" } } */
>> +/* { dg-final { scan-assembler "global\t__moddi3" } } */
>> +
>> +int
>> +foo (unsigned int len)
>> +{
>> +  return ((long)len) * 234 / 5;
>> +}
>> +
>> +int
&

Re: bpf: Throw error when external libcalls are generated.

2023-11-27 Thread Jose E. Marchesi


Hi Cuper.
OK. Thanks for the patch.

> Hi everyone,
>
> The attached patch is a temporary solution for the lack of proper linker
> and external library linking of the eBPF platform.
> Any calls created by the compiler, that would usually be defined within
> libgcc, will endup being undefined in bpftool, when GCC the compiled
> code is passed.
>
> This patch anticipates that error to the compiler, by verifiying if
> any of those calls are being generated, and reporting as an error.
>
> Looking forward to your comments.
>
> Cheers,
> Cupertino
>
> commit c2110ae497c7ff83c309f172bc265973652b760d
> Author: Cupertino Miranda 
> Date:   Thu Nov 23 22:28:01 2023 +
>
> This patch enables errors when external calls are created.
> 
> When architectural limitations or usage of builtins implies the compiler
> to create function calls to external libraries that implement the
> functionality, GCC will now report an error claiming that this function
> calls are not compatible with eBPF target.
> Examples of those are the usage of __builtin_memmove and a sign division
> in BPF ISA v3 or below that will require to call __divdi3.
> This is currently an eBPF limitation which does not support linking of
> object files but rather "raw" non linked ones. Those object files are
> loaded and relocated by libbpf and the kernel.
> 
> gcc/ChangeLog:
> * config/bpf/bpf.cc (bpf_output_call): Report error in case the
> function call is for a builtin.
> (bpf_external_libcall): Added target hook to detect and report
> error when other external calls that are not builtins.
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 0c9d5257c384..1c84113055b1 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -744,6 +744,15 @@ bpf_output_call (rtx target)
>   xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
>   output_asm_insn ("call\t%0", xops);
> }
> + else if (fndecl_built_in_p (decl))
> +   {
> + /* For now lets report this as an error while we are not able to
> +link eBPF object files.  In particular with libgcc.  */
> + tree name = DECL_NAME (decl);
> + error ("call to external builtin %s in function, which is not 
> supported by "
> +"eBPF", name != NULL_TREE ? IDENTIFIER_POINTER (name) : 
> "(anon)");
> + output_asm_insn ("call 0", NULL);
> +   }
>   else
> output_asm_insn ("call\t%0", );
>  
> @@ -763,6 +772,18 @@ bpf_output_call (rtx target)
>return "";
>  }
>  
> +static void
> +bpf_external_libcall (rtx fun)
> +{
> +  tree decl = SYMBOL_REF_DECL (fun);
> +  tree name = DECL_NAME (decl);
> +  error ("call to external libcall %s in function, which is not supported by 
> "
> +  "eBPF", name != NULL_TREE ? IDENTIFIER_POINTER (name) : "(anon)");
> +}
> +
> +#undef  TARGET_ASM_EXTERNAL_LIBCALL
> +#define TARGET_ASM_EXTERNAL_LIBCALL bpf_external_libcall
> +
>  /* Print register name according to assembly dialect.  In normal
> syntax registers are printed like %rN where N is the register
> number.
> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c 
> b/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
> index 4036570ac601..fec720584e48 100644
> --- a/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
> +++ b/gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
> @@ -6,7 +6,7 @@ foo (int *p, int *expected, int desired)
>  {
>return __atomic_compare_exchange (p, expected, , 0,
>   __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
> -}
> +} /* { dg-error "call to external builtin" } */
>  
>  int
>  foo64 (long *p, long *expected, long desired)
> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c 
> b/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
> index 044a2f76474b..ea1b8e48928a 100644
> --- a/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
> +++ b/gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
> @@ -9,7 +9,7 @@ long
>  test_atomic_fetch_add (long x)
>  {
>return __atomic_fetch_add (, x, __ATOMIC_ACQUIRE);
> -}
> +} /* { dg-error "call to external builtin" } */
>  
>  long
>  test_atomic_fetch_sub (long x)
> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-op-3.c 
> b/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
> index b2ce28926347..fefafd6b748f 100644
> --- a/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
> +++ b/gcc/testsuite/gcc.target/bpf/atomic-op-3.c
> @@ -20,7 +20,7 @@ void
>  test_atomic_and (int x)
>  {
>__atomic_and_fetch (, x, __ATOMIC_ACQUIRE);
> -}
> +} /* { dg-error "call to external builtin" } */
>  
>  void
>  test_atomic_nand (int x)
> diff --git a/gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c 
> b/gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c
> index 3b6324e966b8..eab695bf388c 100644
> --- a/gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c
> +++ b/gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c
> @@ -7,7 +7,7 @@ 

[COMMITTED] bpf: remove bpf-helpers.h

2023-11-26 Thread Jose E. Marchesi
Now that we are finally able to use the kernel provided bpf_helpers.h
file and associated machinery, there is no longer need to distribute
our own version.

This patch removes bpf-helpers.h and deletes most of the associated
tests from the gcc.target/bpf testsuite.  Two tests are adapted and
retained: one testing the kernel_helper attribute, which is still
useful, and the other making sure that proper constant propagation is
performed with -O2, which is necessary to use the helpers defined as
static pointers in the kernel's bpf_helpers.h.

Regtested in target bpf-unknown-none and host x86_64-linux-gnu.

gcc/ChangeLog

* config/bpf/bpf-helpers.h: Remove.
* config.gcc: Adapt accordingly.

gcc/testsuite/ChangeLog

* gcc.target/bpf/helper-bind.c: Do not include bpf-helpers.h.
* gcc.target/bpf/helper-skb-ancestor-cgroup-id.c: Likewise, and
renamed from skb-ancestor-cgroup-id.c.
* gcc.target/bpf/helper-bpf-redirect.c: Remove.
* gcc.target/bpf/helper-clone-redirect.c: Likewise.
* gcc.target/bpf/helper-csum-diff.c: Likewise.
* gcc.target/bpf/helper-csum-update.c: Likewise.
* gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise.
* gcc.target/bpf/helper-fib-lookup.c: Likewise.
* gcc.target/bpf/helper-get-cgroup-classid.c: Likewise.
* gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise.
* gcc.target/bpf/helper-get-current-comm.c: Likewise.
* gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise.
* gcc.target/bpf/helper-get-current-task.c: Likewise.
* gcc.target/bpf/helper-get-current-uid-gid.c: Likewise.
* gcc.target/bpf/helper-get-hash-recalc.c: Likewise.
* gcc.target/bpf/helper-get-listener-sock.c: Likewise.
* gcc.target/bpf/helper-get-local-storage.c: Likewise.
* gcc.target/bpf/helper-get-numa-node-id.c: Likewise.
* gcc.target/bpf/helper-get-prandom-u32.c: Likewise.
* gcc.target/bpf/helper-get-route-realm.c: Likewise.
* gcc.target/bpf/helper-get-smp-processor-id.c: Likewise.
* gcc.target/bpf/helper-get-socket-cookie.c: Likewise.
* gcc.target/bpf/helper-get-socket-uid.c: Likewise.
* gcc.target/bpf/helper-get-stack.c: Likewise.
* gcc.target/bpf/helper-get-stackid.c: Likewise.
* gcc.target/bpf/helper-getsockopt.c: Likewise.
* gcc.target/bpf/helper-ktime-get-ns.c: Likewise.
* gcc.target/bpf/helper-l3-csum-replace.c: Likewise.
* gcc.target/bpf/helper-l4-csum-replace.c: Likewise.
* gcc.target/bpf/helper-lwt-push-encap.c: Likewise.
* gcc.target/bpf/helper-lwt-seg6-action.c: Likewise.
* gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise.
* gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise.
* gcc.target/bpf/helper-map-delete-elem.c: Likewise.
* gcc.target/bpf/helper-map-lookup-elem.c: Likewise.
* gcc.target/bpf/helper-map-peek-elem.c: Likewise.
* gcc.target/bpf/helper-map-pop-elem.c: Likewise.
* gcc.target/bpf/helper-map-push-elem.c: Likewise.
* gcc.target/bpf/helper-map-update-elem.c: Likewise.
* gcc.target/bpf/helper-msg-apply-bytes.c: Likewise.
* gcc.target/bpf/helper-msg-cork-bytes.c: Likewise.
* gcc.target/bpf/helper-msg-pop-data.c: Likewise.
* gcc.target/bpf/helper-msg-pull-data.c: Likewise.
* gcc.target/bpf/helper-msg-push-data.c: Likewise.
* gcc.target/bpf/helper-msg-redirect-hash.c: Likewise.
* gcc.target/bpf/helper-msg-redirect-map.c: Likewise.
* gcc.target/bpf/helper-override-return.c: Likewise.
* gcc.target/bpf/helper-perf-event-output.c: Likewise.
* gcc.target/bpf/helper-perf-event-read-value.c: Likewise.
* gcc.target/bpf/helper-perf-event-read.c: Likewise.
* gcc.target/bpf/helper-perf-prog-read-value.c: Likewise.
* gcc.target/bpf/helper-probe-read-str.c: Likewise.
* gcc.target/bpf/helper-probe-read.c: Likewise.
* gcc.target/bpf/helper-probe-write-user.c: Likewise.
* gcc.target/bpf/helper-rc-keydown.c: Likewise.
* gcc.target/bpf/helper-rc-pointer-rel.c: Likewise.
* gcc.target/bpf/helper-rc-repeat.c: Likewise.
* gcc.target/bpf/helper-redirect-map.c: Likewise.
* gcc.target/bpf/helper-set-hash-invalid.c: Likewise.
* gcc.target/bpf/helper-set-hash.c: Likewise.
* gcc.target/bpf/helper-setsockopt.c: Likewise.
* gcc.target/bpf/helper-sk-fullsock.c: Likewise.
* gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise.
* gcc.target/bpf/helper-sk-lookup-upd.c: Likewise.
* gcc.target/bpf/helper-sk-redirect-hash.c: Likewise.
* gcc.target/bpf/helper-sk-redirect-map.c: Likewise.
* gcc.target/bpf/helper-sk-release.c: Likewise.
* gcc.target/bpf/helper-sk-select-reuseport.c: Likewise.
* gcc.target/bpf/helper-sk-storage-delete.c: Likewise.
* 

[PATCH] Emit funcall external declarations only if actually used.

2023-11-25 Thread Jose E. Marchesi
There are many places in GCC where alternative local sequences are
tried in order to determine what is the cheapest or best alternative
to use in the current target.  When any of these sequences involve a
libcall, the current implementation of emit_library_call_value_1
introduce a side-effect consisting on emitting an external declaration
for the funcall (such as __divdi3) which is thus emitted even if the
sequence that does the libcall is not retained.

This is problematic in targets such as BPF, because the kernel loader
chokes on the spurious symbol __divdi3 and makes the resulting BPF
object unloadable.  Note that BPF objects are not linked before being
loaded.

This patch changes asssemble_external_libcall to defer emitting
declarations of external libcall symbols, by saving the call tree
nodes in a temporary list pending_libcall_symbols and letting
process_pending_assembly_externals to emit them only if they have been
referenced.  Solution suggested and sketched by Richard Sandiford.

Regtested in x86_64-linux-gnu.
Tested with host x86_64-linux-gnu with target bpf-unknown-none.

gcc/ChangeLog

* varasm.cc (pending_libcall_symbols): New variable.
(process_pending_assemble_externals): Process
pending_libcall_symbols.
(assemble_external_libcall): Defer emitting external libcall
symbols to process_pending_assemble_externals.

gcc/testsuite/ChangeLog

* gcc.target/bpf/divmod-libcall-1.c: New test.
* gcc.target/bpf/divmod-libcall-2.c: Likewise.
* gcc.c-torture/compile/libcall-2.c: Likewise.
---
 .../gcc.c-torture/compile/libcall-2.c |  8 +++
 .../gcc.target/bpf/divmod-libcall-1.c | 19 
 .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
 gcc/varasm.cc | 22 ++-
 4 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c

diff --git a/gcc/testsuite/gcc.c-torture/compile/libcall-2.c 
b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
new file mode 100644
index 000..b33944c83ff
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/libcall-2.c
@@ -0,0 +1,8 @@
+/* Make sure that external refences for libcalls are generated even for
+   indirect calls.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcmodel=large" { target x86_64-*-* } } */
+/* { dg-final { scan-assembler "globl\t__divti3" } } */
+
+__int128 a, b; void foo () { a = a / b; }
diff --git a/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c 
b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
new file mode 100644
index 000..7481076602a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
@@ -0,0 +1,19 @@
+/* This test makes sure that no spurious external symbol declarations are
+   emitted for libcalls in tried but eventually not used code sequences.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=v3" } */
+/* { dg-final { scan-assembler-not "global\t__divdi3" } } */
+/* { dg-final { scan-assembler-not "global\t__moddi3" } } */
+
+int
+foo (unsigned int len)
+{
+  return ((unsigned long)len) * 234 / 5;
+}
+
+int
+bar (unsigned int len)
+{
+  return ((unsigned long)len) * 234 % 5;
+}
diff --git a/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c 
b/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
new file mode 100644
index 000..792d689395a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=v3" } */
+/* { dg-final { scan-assembler "global\t__divdi3" } } */
+/* { dg-final { scan-assembler "global\t__moddi3" } } */
+
+int
+foo (unsigned int len)
+{
+  return ((long)len) * 234 / 5;
+}
+
+int
+bar (unsigned int len)
+{
+  return ((long)len) * 234 % 5;
+}
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 6ae35edc5ae..deb7eab7af9 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -2461,6 +2461,10 @@ contains_pointers_p (tree type)
it all the way to final.  See PR 17982 for further discussion.  */
 static GTY(()) tree pending_assemble_externals;
 
+/* A similar list of pending libcall symbols.  We only want to declare
+   symbols that are actually used in the final assembly.  */
+static GTY(()) rtx pending_libcall_symbols;
+
 #ifdef ASM_OUTPUT_EXTERNAL
 /* Some targets delay some output to final using TARGET_ASM_FILE_END.
As a result, assemble_external can be called after the list of externals
@@ -2520,8 +2524,17 @@ process_pending_assemble_externals (void)
   for (list = pending_assemble_externals; list; list = TREE_CHAIN (list))
 assemble_external_real (TREE_VALUE (list));
 
+  for (rtx list = pending_libcall_symbols; list; list = XEXP (list, 1))
+{
+  rtx symbol = XEXP (list, 0);
+  tree id = get_identifier (XSTR (symbol, 0));
+  if 

Re: [PATCH] bpf: Forces __buildin_memcmp not to generate a call upto 1024 bytes.

2023-11-24 Thread Jose E. Marchesi


Hi Cuper.

Sorry, I missed this patch last week.
This is OK.

Thanks!

> This patch forces __builtin_memcmp calls upto data sizes of 1024 to
> become inline in caller.
> This is a requirement by BPF and it mimics the default behaviour of the
> clang BPF implementation.
>
> gcc/ChangeLog:
>   * config/bpf/bpf.cc (bpf_use_by_pieces_infrastructure_p): Added
>   function to bypass default behaviour.
>   * config/bpf/bpf.h (COMPARE_MAX_PIECES): Defined to 1024 bytes.
> ---
>  gcc/config/bpf/bpf.cc | 16 
>  gcc/config/bpf/bpf.h  |  5 +
>  2 files changed, 21 insertions(+)
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index a0956a069729..764a3e487cb6 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -1115,6 +1115,22 @@ bpf_small_register_classes_for_mode_p (machine_mode 
> mode)
>  #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
>bpf_small_register_classes_for_mode_p
>  
> +static bool
> +bpf_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
> + unsigned int align ATTRIBUTE_UNUSED,
> + enum by_pieces_operation op,
> + bool speed_p)
> +{
> +  if (op != COMPARE_BY_PIECES)
> +return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
> +
> +  return size <= COMPARE_MAX_PIECES;
> +}
> +
> +#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
> +#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
> +  bpf_use_by_pieces_infrastructure_p
> +
>  /* Finally, build the GCC target.  */
>  
>  struct gcc_target targetm = TARGET_INITIALIZER;
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index 82702aa7b6ba..1f177ec4c4ef 100644
> --- a/gcc/config/bpf/bpf.h
> +++ b/gcc/config/bpf/bpf.h
> @@ -489,6 +489,11 @@ enum reg_class
> locations.  */
>  #define MOVE_MAX 8
>  
> +/* Allow upto 1024 bytes moves to occur using by_pieces
> +   infrastructure.  This mimics clang behaviour when using
> +   __builtin_memcmp.  */
> +#define COMPARE_MAX_PIECES 1024
> +
>  /* An alias for the machine mode for pointers.  */
>  #define Pmode DImode


Re: [PATCH V2] libgcc: mark __hardcfr_check_fail as always_inline

2023-11-23 Thread Jose E. Marchesi


>> Am 23.11.2023 um 16:17 schrieb Jose E. Marchesi :
>> 
>> [Changes from V1:
>> - Use always_inline only in BPF target.]
>> 
>> The function __hardcfr_check_fail in hardcfr.c is internal and static
>> inline.  It receives many arguments, which require more than five
>> registers to be passed in bpf-none-unknown targets.  BPF is limited to
>> that number of registers to pass arguments, and therefore libgcc fails
>> to build in that target.  This patch marks the function with the
>> always_inline attribute, fixing the bpf build.
>> 
>> Tested in bpf-unknown-none target and x86_64-linux-gnu host.
>
> Ok

Pushed.  Thanks.

> Richard 
>
>> libgcc/ChangeLog:
>> 
>>* hardcfr.c (__hardcfr_check_fail): Mark as always_inline.
>> ---
>> libgcc/hardcfr.c | 4 
>> 1 file changed, 4 insertions(+)
>> 
>> diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
>> index 25ff06742cb..376a36202c8 100644
>> --- a/libgcc/hardcfr.c
>> +++ b/libgcc/hardcfr.c
>> @@ -206,6 +206,10 @@ __hardcfr_debug_cfg (size_t const blocks,
>>enabled, it also forces __hardcfr_debug_cfg (above) to be compiled into an
>>out-of-line function, that could be called from a debugger.
>>*/
>> +
>> +#ifdef __BPF__
>> +__attribute__((__always_inline__))
>> +#endif
>> static inline void
>> __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
>>  vword const *const visited ATTRIBUTE_UNUSED,
>> --
>> 2.30.2
>> 


[PATCH V2] libgcc: mark __hardcfr_check_fail as always_inline

2023-11-23 Thread Jose E. Marchesi
[Changes from V1:
- Use always_inline only in BPF target.]

The function __hardcfr_check_fail in hardcfr.c is internal and static
inline.  It receives many arguments, which require more than five
registers to be passed in bpf-none-unknown targets.  BPF is limited to
that number of registers to pass arguments, and therefore libgcc fails
to build in that target.  This patch marks the function with the
always_inline attribute, fixing the bpf build.

Tested in bpf-unknown-none target and x86_64-linux-gnu host.

libgcc/ChangeLog:

* hardcfr.c (__hardcfr_check_fail): Mark as always_inline.
---
 libgcc/hardcfr.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 25ff06742cb..376a36202c8 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -206,6 +206,10 @@ __hardcfr_debug_cfg (size_t const blocks,
enabled, it also forces __hardcfr_debug_cfg (above) to be compiled into an
out-of-line function, that could be called from a debugger.
*/
+
+#ifdef __BPF__
+__attribute__((__always_inline__))
+#endif
 static inline void
 __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
  vword const *const visited ATTRIBUTE_UNUSED,
-- 
2.30.2



Re: [PATCH] libgcc: mark __hardcfr_check_fail as always_inline

2023-11-23 Thread Jose E. Marchesi


> On Wed, Nov 22, 2023 at 3:39 PM Jose E. Marchesi
>  wrote:
>>
>> The function __hardcfr_check_fail in hardcfr.c is internal and static
>> inline.  It receives many arguments, which require more than five
>> registers to be passed in bpf-none-unknown targets.  BPF is limited to
>> that number of registers to pass arguments, and therefore libgcc fails
>> to build in that target.  This patch marks the function with the
>> always_inline attribute, fixing the bpf build.
>>
>> Tested in bpf-unknown-none target and x86_64-linux-gnu host.
>>
>> libgcc/ChangeLog:
>>
>> * hardcfr.c (__hardcfr_check_fail): Mark as always_inline.
>> ---
>>  libgcc/hardcfr.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
>> index 25ff06742cb..48a87a5a87a 100644
>> --- a/libgcc/hardcfr.c
>> +++ b/libgcc/hardcfr.c
>> @@ -206,7 +206,8 @@ __hardcfr_debug_cfg (size_t const blocks,
>> enabled, it also forces __hardcfr_debug_cfg (above) to be compiled into 
>> an
>> out-of-line function, that could be called from a debugger.
>> */
>> -static inline void
>> +
>> +static inline  __attribute__((__always_inline__)) void
>
> can we gate this with
>
> #ifdef __BPF
>
> or so?

Yep.  Just sent V2.

>>  __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
>>   vword const *const visited ATTRIBUTE_UNUSED,
>>   vword const *const cfg ATTRIBUTE_UNUSED,
>> --
>> 2.30.2
>>


[PATCH] libgcc: mark __hardcfr_check_fail as always_inline

2023-11-22 Thread Jose E. Marchesi
The function __hardcfr_check_fail in hardcfr.c is internal and static
inline.  It receives many arguments, which require more than five
registers to be passed in bpf-none-unknown targets.  BPF is limited to
that number of registers to pass arguments, and therefore libgcc fails
to build in that target.  This patch marks the function with the
always_inline attribute, fixing the bpf build.

Tested in bpf-unknown-none target and x86_64-linux-gnu host.

libgcc/ChangeLog:

* hardcfr.c (__hardcfr_check_fail): Mark as always_inline.
---
 libgcc/hardcfr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 25ff06742cb..48a87a5a87a 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -206,7 +206,8 @@ __hardcfr_debug_cfg (size_t const blocks,
enabled, it also forces __hardcfr_debug_cfg (above) to be compiled into an
out-of-line function, that could be called from a debugger.
*/
-static inline void
+
+static inline  __attribute__((__always_inline__)) void
 __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
  vword const *const visited ATTRIBUTE_UNUSED,
  vword const *const cfg ATTRIBUTE_UNUSED,
-- 
2.30.2



[COMMITTED] bpf: fix pseudo-c asm emitted for *mulsidi3_zeroextend

2023-11-09 Thread Jose E. Marchesi
This patch fixes the pseudo-c BPF assembly syntax used for
*mulsidi3_zeroextend, which was being emitted as:

  rN *= wM

instead of the proper way to denote a mul32 in pseudo-C syntax:

  wN *= wM

Includes test.
Tested in bpf-unknown-none-gcc target in x86_64-linux-gnu host.

gcc/ChangeLog:

* config/bpf/bpf.cc (bpf_print_register): Accept modifier code 'W'
to force emitting register names using the wN form.
* config/bpf/bpf.md (*mulsidi3_zeroextend): Force operands to
always use wN written form in pseudo-C assembly syntax.

gcc/testsuite/ChangeLog:

* gcc.target/bpf/mulsidi3-zeroextend-pseudoc.c: New test.
---
 gcc/config/bpf/bpf.cc  | 18 +++---
 gcc/config/bpf/bpf.md  |  2 +-
 .../bpf/mulsidi3-zeroextend-pseudoc.c  | 14 ++
 3 files changed, 26 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/mulsidi3-zeroextend-pseudoc.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 63637ece78e..a0956a06972 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -763,13 +763,17 @@ bpf_output_call (rtx target)
   return "";
 }
 
-/* Print register name according to assembly dialect.
-   In normal syntax registers are printed like %rN where N is the
-   register number.
+/* Print register name according to assembly dialect.  In normal
+   syntax registers are printed like %rN where N is the register
+   number.
+
In pseudoc syntax, the register names do not feature a '%' prefix.
-   Additionally, the code 'w' denotes that the register should be printed
-   as wN instead of rN, where N is the register number, but only when the
-   value stored in the operand OP is 32-bit wide.  */
+   Additionally, the code 'w' denotes that the register should be
+   printed as wN instead of rN, where N is the register number, but
+   only when the value stored in the operand OP is 32-bit wide.
+   Finally, the code 'W' denotes that the register should be printed
+   as wN instead of rN, in all cases, regardless of the mode of the
+   value stored in the operand.  */
 
 static void
 bpf_print_register (FILE *file, rtx op, int code)
@@ -778,7 +782,7 @@ bpf_print_register (FILE *file, rtx op, int code)
 fprintf (file, "%s", reg_names[REGNO (op)]);
   else
 {
-  if (code == 'w' && GET_MODE_SIZE (GET_MODE (op)) <= 4)
+  if (code == 'W' || (code == 'w' && GET_MODE_SIZE (GET_MODE (op)) <= 4))
{
  if (REGNO (op) == BPF_FP)
fprintf (file, "w10");
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 0e2ad8da5ac..522351a6596 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -184,7 +184,7 @@ (define_insn "*mulsidi3_zeroextend"
  (mult:SI (match_operand:SI 1 "register_operand" "0,0")
   (match_operand:SI 2 "reg_or_imm_operand" "r,I"]
   ""
-  "{mul32\t%0,%2|%w0 *= %w2}"
+  "{mul32\t%0,%2|%W0 *= %W2}"
   [(set_attr "type" "alu32")])
 
 ;;; Division
diff --git a/gcc/testsuite/gcc.target/bpf/mulsidi3-zeroextend-pseudoc.c 
b/gcc/testsuite/gcc.target/bpf/mulsidi3-zeroextend-pseudoc.c
new file mode 100644
index 000..63d63142708
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/mulsidi3-zeroextend-pseudoc.c
@@ -0,0 +1,14 @@
+/* Make sure that we are emitting `wN *= wM' and not `rN *= wM' for a mul32 in
+   pseudo-C assembly syntax when emitting assembly for a recognized
+   *mulsidi3_zeroextend pattern.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=pseudoc" } */
+
+unsigned long foo (unsigned snd_cwnd, unsigned mss_cache)
+{
+  return snd_cwnd * mss_cache;
+}
+
+/* { dg-final { scan-assembler-not {\tr. \*= w.\n} } } */
+/* { dg-final { scan-assembler {\tw. \*= w.\n} } } */
-- 
2.30.2



[COMMITED] bpf: testsuite: fix expected regexp in gcc.target/bpf/ldxdw.c

2023-11-09 Thread Jose E. Marchesi
gcc/testsuite/ChangeLog:

* gcc.target/bpf/ldxdw.c: Fix regexp with expected result.
---
 gcc/testsuite/gcc.target/bpf/ldxdw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/bpf/ldxdw.c 
b/gcc/testsuite/gcc.target/bpf/ldxdw.c
index 0985ea3e6ac..72db8f03324 100644
--- a/gcc/testsuite/gcc.target/bpf/ldxdw.c
+++ b/gcc/testsuite/gcc.target/bpf/ldxdw.c
@@ -4,7 +4,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 
-/* { dg-final { scan-assembler-times "ldxdw\t%r.,\\\[%r.+0\\\]" 1 } } */
+/* { dg-final { scan-assembler-times "ldxdw\t%r.,\\\[%r.\\+\[0-9\]+\\\]" 1 } } 
*/
 /* { dg-final { scan-assembler-not "ldxdw\t%r.,\[0-9\]+" } } */
 
 unsigned long long test () {
-- 
2.30.2



Re: RFC (V2) the proposal to resolve the missing dependency issue for counted_by attribute

2023-11-09 Thread Jose E. Marchesi


> On Thu, Nov 09, 2023 at 03:49:49PM +, Qing Zhao wrote:
>> Is it reasonable to add one option to disable the “counted_by” attribute?
>> (then no insertion of the new .ACCESS_WITH_SIZE into IL).  
>> 
>> The major reason is: some users might want to ignore all the “counted_by” 
>> attribute added in the source code,
>> We need to provide them a way to disable this feature.
>
> -D'counted_by(x)='
> and/or
> -D'__counted_by__(x)='
> ?

The insertion of .ACCESS_WITH_SIZE collides with the BPF CO-RE
preserve_access_index implementation.

I don't think this will be a problem in practice (the BPF program can
define counted_by to the empty string as Jakub suggests) but we ought to
at least detect when a data structure featuring a counted_by FMA is
accessed with access index preservation (either attribute or builtin)
and either error out or warning out and try to accomodate by turning the
.ACCESS_WTIH_INDEX back to plain accesses.  We can do either with BPF
specific backend code.


Re: __hardcfr_check_fail and BPF

2023-11-07 Thread Jose E. Marchesi


> Hi,
>
> On Oct 31, 2023, "Jose E. Marchesi"  wrote:
>
>> As you may know, in BPF we have to live (for now) with the constant pain
>> from being limited to functions whose arguments can be compiled to get
>> their arguments in five or less registers.
>
> Ugh.  I had no idea.
>
>> The recently introduced __hardcfr_check_fail in the run-time component
>> of hardcfr breaks the bpf-unknown-none build:
>
>>   ../../../libgcc/hardcfr.c: In function ‘__hardcfr_check_fail’:
>>   ../../../libgcc/hardcfr.c:210:1: error: too many function arguments for 
>> eBPF
>> 210 | __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
>> | ^~~~
>
> Would it by any chance be enough to make it always_inline on bpf?
>
> Failing that, the alternative I see is to pack some (or all) of the
> arguments into a struct, and pass it by reference.  That would be plenty
> of overhead for a slow path, and it could be made conditional for
> targets that require it.
>
>> It seems to me that __hardcfr_check_fail is only called from
>> __hardcfr_check, and compiled code is not instrumentalized with direct
>> calls to it.
>
> Yeah, it's static, it's not even supposed to be visible.
>
> I envisioned making it visible and forcing it out-of-line, so that one
> could set a breakpoint on it in case of failures, but I haven't done
> that (yet?).
>
> I'm afraid dropping any of the arguments is not viable for it to do its
> job, but calls to it could conceivably be replaced with a goto, if the
> code is moved (manually inlined) into __hardcfr_check.

Marking the function as always_inline would work with BPF.

I didn't thought of that because of that comment "When the verbose mode
is enabled, it also forces __hardcfr_debug_cfg (above) to be compiled
into an out-of-line function, that could be called from a debugger." but
now I realize it refers to __hardcfr_debug_cfg and not
__hardcfr_check_fail :)

Thank you.


__hardcfr_check_fail and BPF

2023-10-31 Thread Jose E. Marchesi


Hi Alex.

As you may know, in BPF we have to live (for now) with the constant pain
from being limited to functions whose arguments can be compiled to get
their arguments in five or less registers.

The recently introduced __hardcfr_check_fail in the run-time component
of hardcfr breaks the bpf-unknown-none build:

  ../../../libgcc/hardcfr.c: In function ‘__hardcfr_check_fail’:
  ../../../libgcc/hardcfr.c:210:1: error: too many function arguments for eBPF
210 | __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
| ^~~~

It seems to me that __hardcfr_check_fail is only called from
__hardcfr_check, and compiled code is not instrumentalized with direct
calls to it.

If so, would it be possible to modify that function so it gets one less
argument? :)

Alternatively, we would need to disable the hardcfr from the BPF backend
and being able to define something in tm.h to inhibit building the
corresponding runtime in libgcc.  Would you be ok with having an #ifndef
DISABLE_LIBGCC_HARDCFR wrapping the stuff in that file?

Thanks.


Re: [PATCH] gcov-io.h: fix comment regarding length of records

2023-10-24 Thread Jose E. Marchesi


> On 10/24/23 06:41, Jose E. Marchesi wrote:
>> The length of gcov records is stored as a signed 32-bit number of
>> bytes.
>> Ok?
> OK.

Pushed.  Thanks.


[PATCH] gcov-io.h: fix comment regarding length of records

2023-10-24 Thread Jose E. Marchesi


The length of gcov records is stored as a signed 32-bit number of bytes.
Ok?

diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index bfe4439d02d..e6f33e32652 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -101,7 +101,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
Records are not nested, but there is a record hierarchy.  Tag
numbers reflect this hierarchy.  Tags are unique across note and
data files.  Some record types have a varying amount of data.  The
-   LENGTH is the number of 4bytes that follow and is usually used to
+   LENGTH is the number of bytes that follow and is usually used to
determine how much data.  The tag value is split into 4 8-bit
fields, one for each of four possible levels.  The most significant
is allocated first.  Unused levels are zero.  Active levels are


Re: [PATCH V2] Emit funcall external declarations only if actually used.

2023-10-12 Thread Jose E. Marchesi


> "Jose E. Marchesi"  writes:
>> Hi Richard.
>> Thanks for looking at this! :)
>>
>>
>>> "Jose E. Marchesi"  writes:
>>>> ping
>>>
>>> I don't know this code very well, and have AFAIR haven't worked
>>> with an assembler that requires external declarations, but since
>>> it's at a second ping :)
>>>
>>>>
>>>>> ping
>>>>>
>>>>>> [Differences from V1:
>>>>>> - Prototype for call_from_call_insn moved before comment block.
>>>>>> - Reuse the `call' flag for SYMBOL_REF_LIBCALL.
>>>>>> - Fallback to check REG_CALL_DECL in non-direct calls.
>>>>>> - New test to check correct behavior for non-direct calls.]
>>>>>>
>>>>>> There are many places in GCC where alternative local sequences are
>>>>>> tried in order to determine what is the cheapest or best alternative
>>>>>> to use in the current target.  When any of these sequences involve a
>>>>>> libcall, the current implementation of emit_library_call_value_1
>>>>>> introduce a side-effect consisting on emitting an external declaration
>>>>>> for the funcall (such as __divdi3) which is thus emitted even if the
>>>>>> sequence that does the libcall is not retained.
>>>>>>
>>>>>> This is problematic in targets such as BPF, because the kernel loader
>>>>>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>>>>>> object unloadable.  Note that BPF objects are not linked before being
>>>>>> loaded.
>>>>>>
>>>>>> This patch changes emit_library_call_value_1 to mark the target
>>>>>> SYMBOL_REF as a libcall.  Then, the emission of the external
>>>>>> declaration is done in the first loop of final.cc:shorten_branches.
>>>>>> This happens only if the corresponding sequence has been kept.
>>>>>>
>>>>>> Regtested in x86_64-linux-gnu.
>>>>>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>>>
>>> I'm not sure that shorten_branches is a natural place to do this.
>>> It isn't something that would normally emit asm text.
>>
>> Well, that was the approach suggested by another reviewer (Jakub) once
>> my initial approach (in the V1) got rejected.  He explicitly suggested
>> to use shorten_branches.
>>
>>> Would it be OK to emit the declaration at the same point as for decls,
>>> which IIUC is process_pending_assemble_externals?  If so, how about
>>> making assemble_external_libcall add the symbol to a list when
>>> !SYMBOL_REF_USED, instead of calling targetm.asm_out.external_libcall
>>> directly?  assemble_external_libcall could then also call get_identifier
>>> on the name (perhaps after calling strip_name_encoding -- can't
>>> remember whether assemble_external_libcall sees the encoded or
>>> unencoded name).
>>>
>>> All being well, the call to get_identifier should cause
>>> assemble_name_resolve to record when the name is used, via
>>> TREE_SYMBOL_REFERENCED.  Then process_pending_assemble_externals could
>>> go through the list of libcalls recorded by assemble_external_libcall
>>> and check whether TREE_SYMBOL_REFERENCED is set on the get_identifier.
>>>
>>> Not super elegant, but it seems to fit within the existing scheme.
>>> And I don't there should be any problem with using get_identifier
>>> for libcalls, since it isn't valid to use libcall names for other
>>> types of symbol.
>>
>> This sounds way more complicated to me than the approach in V2, which
>> seems to work and is thus a clear improvement compared to the current
>> situation in the trunk.  The approach in V2 may be ugly, but it is
>> simple and easy to understand.  Is the proposed more convoluted
>> alternative really worth the extra complexity, given it is "not super
>> elegant"?
>
> Is it really that much more convoluted?  I was thinking of something
> like the attached, which seems a bit shorter than V2, and does seem
> to fix the bpf tests.

o_O
Ok I clearly misunderstood what you was proposing.  This is way simpler!

How does the magic of TREE_SYMBOL_REFERENCED work?  How is it set to
`true' only if the RTL containing the call is retained in the final
chain?

> I think most (all?) libcalls already have an associated decl due to
> optabs-libfuncs.cc, so a

Re: [PATCH V2] Emit funcall external declarations only if actually used.

2023-10-12 Thread Jose E. Marchesi


Hi Richard.
Thanks for looking at this! :)


> "Jose E. Marchesi"  writes:
>> ping
>
> I don't know this code very well, and have AFAIR haven't worked
> with an assembler that requires external declarations, but since
> it's at a second ping :)
>
>>
>>> ping
>>>
>>>> [Differences from V1:
>>>> - Prototype for call_from_call_insn moved before comment block.
>>>> - Reuse the `call' flag for SYMBOL_REF_LIBCALL.
>>>> - Fallback to check REG_CALL_DECL in non-direct calls.
>>>> - New test to check correct behavior for non-direct calls.]
>>>>
>>>> There are many places in GCC where alternative local sequences are
>>>> tried in order to determine what is the cheapest or best alternative
>>>> to use in the current target.  When any of these sequences involve a
>>>> libcall, the current implementation of emit_library_call_value_1
>>>> introduce a side-effect consisting on emitting an external declaration
>>>> for the funcall (such as __divdi3) which is thus emitted even if the
>>>> sequence that does the libcall is not retained.
>>>>
>>>> This is problematic in targets such as BPF, because the kernel loader
>>>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>>>> object unloadable.  Note that BPF objects are not linked before being
>>>> loaded.
>>>>
>>>> This patch changes emit_library_call_value_1 to mark the target
>>>> SYMBOL_REF as a libcall.  Then, the emission of the external
>>>> declaration is done in the first loop of final.cc:shorten_branches.
>>>> This happens only if the corresponding sequence has been kept.
>>>>
>>>> Regtested in x86_64-linux-gnu.
>>>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>
> I'm not sure that shorten_branches is a natural place to do this.
> It isn't something that would normally emit asm text.

Well, that was the approach suggested by another reviewer (Jakub) once
my initial approach (in the V1) got rejected.  He explicitly suggested
to use shorten_branches.

> Would it be OK to emit the declaration at the same point as for decls,
> which IIUC is process_pending_assemble_externals?  If so, how about
> making assemble_external_libcall add the symbol to a list when
> !SYMBOL_REF_USED, instead of calling targetm.asm_out.external_libcall
> directly?  assemble_external_libcall could then also call get_identifier
> on the name (perhaps after calling strip_name_encoding -- can't
> remember whether assemble_external_libcall sees the encoded or
> unencoded name).
>
> All being well, the call to get_identifier should cause
> assemble_name_resolve to record when the name is used, via
> TREE_SYMBOL_REFERENCED.  Then process_pending_assemble_externals could
> go through the list of libcalls recorded by assemble_external_libcall
> and check whether TREE_SYMBOL_REFERENCED is set on the get_identifier.
>
> Not super elegant, but it seems to fit within the existing scheme.
> And I don't there should be any problem with using get_identifier
> for libcalls, since it isn't valid to use libcall names for other
> types of symbol.

This sounds way more complicated to me than the approach in V2, which
seems to work and is thus a clear improvement compared to the current
situation in the trunk.  The approach in V2 may be ugly, but it is
simple and easy to understand.  Is the proposed more convoluted
alternative really worth the extra complexity, given it is "not super
elegant"?

I am willing to give it a try if you insist on it, but I wouldn't want a
V3 series based on that approach to be deflected again on the basis of a
yet another more potentially elegant solution... that wont' converge,
and I need this fixed for the BPF backend..

>
> Thanks,
> Richard
>
>>>>
>>>> gcc/ChangeLog
>>>>
>>>>* rtl.h (SYMBOL_REF_LIBCALL): Define.
>>>>* calls.cc (emit_library_call_value_1): Do not emit external
>>>>libcall declaration here.
>>>>* final.cc (shorten_branches): Do it here.
>>>>
>>>> gcc/testsuite/ChangeLog
>>>>
>>>>* gcc.target/bpf/divmod-libcall-1.c: New test.
>>>>* gcc.target/bpf/divmod-libcall-2.c: Likewise.
>>>>* gcc.c-torture/compile/libcall-2.c: Likewise.
>>>> ---
>>>>  gcc/calls.cc  |  9 +++---
>>>>  gcc/final.cc  | 30 +++
>>>>  gcc/rtl.h |  5 
>>>&g

Re: [PATCH V2] Emit funcall external declarations only if actually used.

2023-10-03 Thread Jose E. Marchesi


ping

> ping
>
>> [Differences from V1:
>> - Prototype for call_from_call_insn moved before comment block.
>> - Reuse the `call' flag for SYMBOL_REF_LIBCALL.
>> - Fallback to check REG_CALL_DECL in non-direct calls.
>> - New test to check correct behavior for non-direct calls.]
>>
>> There are many places in GCC where alternative local sequences are
>> tried in order to determine what is the cheapest or best alternative
>> to use in the current target.  When any of these sequences involve a
>> libcall, the current implementation of emit_library_call_value_1
>> introduce a side-effect consisting on emitting an external declaration
>> for the funcall (such as __divdi3) which is thus emitted even if the
>> sequence that does the libcall is not retained.
>>
>> This is problematic in targets such as BPF, because the kernel loader
>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>> object unloadable.  Note that BPF objects are not linked before being
>> loaded.
>>
>> This patch changes emit_library_call_value_1 to mark the target
>> SYMBOL_REF as a libcall.  Then, the emission of the external
>> declaration is done in the first loop of final.cc:shorten_branches.
>> This happens only if the corresponding sequence has been kept.
>>
>> Regtested in x86_64-linux-gnu.
>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>>
>> gcc/ChangeLog
>>
>>  * rtl.h (SYMBOL_REF_LIBCALL): Define.
>>  * calls.cc (emit_library_call_value_1): Do not emit external
>>  libcall declaration here.
>>  * final.cc (shorten_branches): Do it here.
>>
>> gcc/testsuite/ChangeLog
>>
>>  * gcc.target/bpf/divmod-libcall-1.c: New test.
>>  * gcc.target/bpf/divmod-libcall-2.c: Likewise.
>>  * gcc.c-torture/compile/libcall-2.c: Likewise.
>> ---
>>  gcc/calls.cc  |  9 +++---
>>  gcc/final.cc  | 30 +++
>>  gcc/rtl.h |  5 
>>  .../gcc.c-torture/compile/libcall-2.c |  8 +
>>  .../gcc.target/bpf/divmod-libcall-1.c | 19 
>>  .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
>>  6 files changed, 83 insertions(+), 4 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>>
>> diff --git a/gcc/calls.cc b/gcc/calls.cc
>> index 1f3a6d5c450..219ea599b16 100644
>> --- a/gcc/calls.cc
>> +++ b/gcc/calls.cc
>> @@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, 
>> rtx value,
>>  || argvec[i].partial != 0)
>>update_stack_alignment_for_call ([i].locate);
>>  
>> -  /* If this machine requires an external definition for library
>> - functions, write one out.  */
>> -  assemble_external_libcall (fun);
>> +  /* Mark the emitted target as a libcall.  This will be used by final
>> + in order to emit an external symbol declaration if the libcall is
>> + ever used.  */
>> +  SYMBOL_REF_LIBCALL (fun) = 1;
>>  
>>original_args_size = args_size;
>>args_size.constant = (aligned_upper_bound (args_size.constant
>> @@ -4735,7 +4736,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
>> value,
>> valreg,
>> old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
>>  
>> -  if (flag_ipa_ra)
>> +  if (flag_ipa_ra || SYMBOL_REF_LIBCALL (orgfun))
>>  {
>>rtx datum = orgfun;
>>gcc_assert (GET_CODE (datum) == SYMBOL_REF);
>> diff --git a/gcc/final.cc b/gcc/final.cc
>> index dd3e22547ac..2041e43fdd1 100644
>> --- a/gcc/final.cc
>> +++ b/gcc/final.cc
>> @@ -804,6 +804,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
>>  }
>>  
>>  
>> +static rtx call_from_call_insn (rtx_call_insn *insn);
>> +
>>  /* Make a pass over all insns and compute their actual lengths by shortening
>> any branches of variable length if possible.  */
>>  
>> @@ -850,6 +852,34 @@ shorten_branches (rtx_insn *first)
>>for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
>>  {
>>INSN_SHUID (insn) = i++;
>> +
>> +  /* If this is a `call' instruction implementing a libcall, and
>> + this machine requires an external definition for library
>> + functions, write one out.  */
>> +  if (CALL_P (insn))
>> +{
>> +  rtx x;
>> +
>> +  if ((x = call_from_call_insn (dyn_cast  (insn)))
>> +  && (x = XEXP (x, 0))
>> +  && MEM_P (x)
>> +  && (x = XEXP (x, 0))
>> +  && SYMBOL_REF_P (x)
>> +  && SYMBOL_REF_LIBCALL (x))
>> +{
>> +  /* Direct call.  */
>> +  assemble_external_libcall (x);
>> +}
>> +  else if ((x = find_reg_note (insn, REG_CALL_DECL, NULL_RTX))
>> +   && (x = XEXP (x, 0)))
>> +{
>> +   

Re: [PATCH V2] Emit funcall external declarations only if actually used.

2023-09-05 Thread Jose E. Marchesi via Gcc-patches


ping^

> ping
>
>> [Differences from V1:
>> - Prototype for call_from_call_insn moved before comment block.
>> - Reuse the `call' flag for SYMBOL_REF_LIBCALL.
>> - Fallback to check REG_CALL_DECL in non-direct calls.
>> - New test to check correct behavior for non-direct calls.]
>>
>> There are many places in GCC where alternative local sequences are
>> tried in order to determine what is the cheapest or best alternative
>> to use in the current target.  When any of these sequences involve a
>> libcall, the current implementation of emit_library_call_value_1
>> introduce a side-effect consisting on emitting an external declaration
>> for the funcall (such as __divdi3) which is thus emitted even if the
>> sequence that does the libcall is not retained.
>>
>> This is problematic in targets such as BPF, because the kernel loader
>> chokes on the spurious symbol __divdi3 and makes the resulting BPF
>> object unloadable.  Note that BPF objects are not linked before being
>> loaded.
>>
>> This patch changes emit_library_call_value_1 to mark the target
>> SYMBOL_REF as a libcall.  Then, the emission of the external
>> declaration is done in the first loop of final.cc:shorten_branches.
>> This happens only if the corresponding sequence has been kept.
>>
>> Regtested in x86_64-linux-gnu.
>> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>>
>> gcc/ChangeLog
>>
>>  * rtl.h (SYMBOL_REF_LIBCALL): Define.
>>  * calls.cc (emit_library_call_value_1): Do not emit external
>>  libcall declaration here.
>>  * final.cc (shorten_branches): Do it here.
>>
>> gcc/testsuite/ChangeLog
>>
>>  * gcc.target/bpf/divmod-libcall-1.c: New test.
>>  * gcc.target/bpf/divmod-libcall-2.c: Likewise.
>>  * gcc.c-torture/compile/libcall-2.c: Likewise.
>> ---
>>  gcc/calls.cc  |  9 +++---
>>  gcc/final.cc  | 30 +++
>>  gcc/rtl.h |  5 
>>  .../gcc.c-torture/compile/libcall-2.c |  8 +
>>  .../gcc.target/bpf/divmod-libcall-1.c | 19 
>>  .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
>>  6 files changed, 83 insertions(+), 4 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>>
>> diff --git a/gcc/calls.cc b/gcc/calls.cc
>> index 1f3a6d5c450..219ea599b16 100644
>> --- a/gcc/calls.cc
>> +++ b/gcc/calls.cc
>> @@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, 
>> rtx value,
>>  || argvec[i].partial != 0)
>>update_stack_alignment_for_call ([i].locate);
>>  
>> -  /* If this machine requires an external definition for library
>> - functions, write one out.  */
>> -  assemble_external_libcall (fun);
>> +  /* Mark the emitted target as a libcall.  This will be used by final
>> + in order to emit an external symbol declaration if the libcall is
>> + ever used.  */
>> +  SYMBOL_REF_LIBCALL (fun) = 1;
>>  
>>original_args_size = args_size;
>>args_size.constant = (aligned_upper_bound (args_size.constant
>> @@ -4735,7 +4736,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
>> value,
>> valreg,
>> old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
>>  
>> -  if (flag_ipa_ra)
>> +  if (flag_ipa_ra || SYMBOL_REF_LIBCALL (orgfun))
>>  {
>>rtx datum = orgfun;
>>gcc_assert (GET_CODE (datum) == SYMBOL_REF);
>> diff --git a/gcc/final.cc b/gcc/final.cc
>> index dd3e22547ac..2041e43fdd1 100644
>> --- a/gcc/final.cc
>> +++ b/gcc/final.cc
>> @@ -804,6 +804,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
>>  }
>>  
>>  
>> +static rtx call_from_call_insn (rtx_call_insn *insn);
>> +
>>  /* Make a pass over all insns and compute their actual lengths by shortening
>> any branches of variable length if possible.  */
>>  
>> @@ -850,6 +852,34 @@ shorten_branches (rtx_insn *first)
>>for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
>>  {
>>INSN_SHUID (insn) = i++;
>> +
>> +  /* If this is a `call' instruction implementing a libcall, and
>> + this machine requires an external definition for library
>> + functions, write one out.  */
>> +  if (CALL_P (insn))
>> +{
>> +  rtx x;
>> +
>> +  if ((x = call_from_call_insn (dyn_cast  (insn)))
>> +  && (x = XEXP (x, 0))
>> +  && MEM_P (x)
>> +  && (x = XEXP (x, 0))
>> +  && SYMBOL_REF_P (x)
>> +  && SYMBOL_REF_LIBCALL (x))
>> +{
>> +  /* Direct call.  */
>> +  assemble_external_libcall (x);
>> +}
>> +  else if ((x = find_reg_note (insn, REG_CALL_DECL, NULL_RTX))
>> +   && (x = XEXP (x, 0)))
>> +{
>> +  

Re: [PATCH V2] Emit funcall external declarations only if actually used.

2023-08-30 Thread Jose E. Marchesi via Gcc-patches


ping

> [Differences from V1:
> - Prototype for call_from_call_insn moved before comment block.
> - Reuse the `call' flag for SYMBOL_REF_LIBCALL.
> - Fallback to check REG_CALL_DECL in non-direct calls.
> - New test to check correct behavior for non-direct calls.]
>
> There are many places in GCC where alternative local sequences are
> tried in order to determine what is the cheapest or best alternative
> to use in the current target.  When any of these sequences involve a
> libcall, the current implementation of emit_library_call_value_1
> introduce a side-effect consisting on emitting an external declaration
> for the funcall (such as __divdi3) which is thus emitted even if the
> sequence that does the libcall is not retained.
>
> This is problematic in targets such as BPF, because the kernel loader
> chokes on the spurious symbol __divdi3 and makes the resulting BPF
> object unloadable.  Note that BPF objects are not linked before being
> loaded.
>
> This patch changes emit_library_call_value_1 to mark the target
> SYMBOL_REF as a libcall.  Then, the emission of the external
> declaration is done in the first loop of final.cc:shorten_branches.
> This happens only if the corresponding sequence has been kept.
>
> Regtested in x86_64-linux-gnu.
> Tested with host x86_64-linux-gnu with target bpf-unknown-none.
>
> gcc/ChangeLog
>
>   * rtl.h (SYMBOL_REF_LIBCALL): Define.
>   * calls.cc (emit_library_call_value_1): Do not emit external
>   libcall declaration here.
>   * final.cc (shorten_branches): Do it here.
>
> gcc/testsuite/ChangeLog
>
>   * gcc.target/bpf/divmod-libcall-1.c: New test.
>   * gcc.target/bpf/divmod-libcall-2.c: Likewise.
>   * gcc.c-torture/compile/libcall-2.c: Likewise.
> ---
>  gcc/calls.cc  |  9 +++---
>  gcc/final.cc  | 30 +++
>  gcc/rtl.h |  5 
>  .../gcc.c-torture/compile/libcall-2.c |  8 +
>  .../gcc.target/bpf/divmod-libcall-1.c | 19 
>  .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
>  6 files changed, 83 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c
>
> diff --git a/gcc/calls.cc b/gcc/calls.cc
> index 1f3a6d5c450..219ea599b16 100644
> --- a/gcc/calls.cc
> +++ b/gcc/calls.cc
> @@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
> value,
>   || argvec[i].partial != 0)
>update_stack_alignment_for_call ([i].locate);
>  
> -  /* If this machine requires an external definition for library
> - functions, write one out.  */
> -  assemble_external_libcall (fun);
> +  /* Mark the emitted target as a libcall.  This will be used by final
> + in order to emit an external symbol declaration if the libcall is
> + ever used.  */
> +  SYMBOL_REF_LIBCALL (fun) = 1;
>  
>original_args_size = args_size;
>args_size.constant = (aligned_upper_bound (args_size.constant
> @@ -4735,7 +4736,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
> value,
>  valreg,
>  old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
>  
> -  if (flag_ipa_ra)
> +  if (flag_ipa_ra || SYMBOL_REF_LIBCALL (orgfun))
>  {
>rtx datum = orgfun;
>gcc_assert (GET_CODE (datum) == SYMBOL_REF);
> diff --git a/gcc/final.cc b/gcc/final.cc
> index dd3e22547ac..2041e43fdd1 100644
> --- a/gcc/final.cc
> +++ b/gcc/final.cc
> @@ -804,6 +804,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
>  }
>  
>  
> +static rtx call_from_call_insn (rtx_call_insn *insn);
> +
>  /* Make a pass over all insns and compute their actual lengths by shortening
> any branches of variable length if possible.  */
>  
> @@ -850,6 +852,34 @@ shorten_branches (rtx_insn *first)
>for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
>  {
>INSN_SHUID (insn) = i++;
> +
> +  /* If this is a `call' instruction implementing a libcall, and
> + this machine requires an external definition for library
> + functions, write one out.  */
> +  if (CALL_P (insn))
> +{
> +  rtx x;
> +
> +  if ((x = call_from_call_insn (dyn_cast  (insn)))
> +  && (x = XEXP (x, 0))
> +  && MEM_P (x)
> +  && (x = XEXP (x, 0))
> +  && SYMBOL_REF_P (x)
> +  && SYMBOL_REF_LIBCALL (x))
> +{
> +  /* Direct call.  */
> +  assemble_external_libcall (x);
> +}
> +  else if ((x = find_reg_note (insn, REG_CALL_DECL, NULL_RTX))
> +   && (x = XEXP (x, 0)))
> +{
> +  /* Indirect call with REG_CALL_DECL note.  */
> +  gcc_assert (SYMBOL_REF_P (x));
> +  if 

Re: [PATCH V4] Add warning options -W[no-]compare-distinct-pointer-types

2023-08-24 Thread Jose E. Marchesi via Gcc-patches


Hi Marek.

> On Thu, Aug 17, 2023 at 05:37:03PM +0200, Jose E. Marchesi via Gcc-patches 
> wrote:
>> 
>> > On Thu, 17 Aug 2023, Jose E. Marchesi via Gcc-patches wrote:
>> >
>> >> +@opindex Wcompare-distinct-pointer-types
>> >> +@item -Wcompare-distinct-pointer-types
>> >
>> > This @item should say @r{(C and Objective-C only)}, since the option isn't 
>> > implemented for C++.  OK with that change.
>> 
>> Pushed with that change.
>> Thanks for the prompt review!
>
> I see the following failures:
>
> FAIL: gcc.c-torture/compile/pr106537-1.c   -Os   (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-1.c   -Os   (test for warnings, line 30)
> FAIL: gcc.c-torture/compile/pr106537-1.c -O2 -flto
> -fno-use-linker-plugin -flto-partition=none (test for warnings, line
> 28)
> FAIL: gcc.c-torture/compile/pr106537-1.c -O2 -flto
> -fno-use-linker-plugin -flto-partition=none (test for warnings, line
> 30)
> FAIL: gcc.c-torture/compile/pr106537-1.c -O2 -flto -fuse-linker-plugin
> -fno-fat-lto-objects (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-1.c -O2 -flto -fuse-linker-plugin
> -fno-fat-lto-objects (test for warnings, line 30)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O0   (test for warnings, line 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O0   (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O1   (test for warnings, line 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O1   (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O2   (test for warnings, line 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O2   (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O3 -g   (test for warnings, line 
> 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -O3 -g   (test for warnings, line 
> 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -Os   (test for warnings, line 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c   -Os   (test for warnings, line 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c -O2 -flto
> -fno-use-linker-plugin -flto-partition=none (test for warnings, line
> 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c -O2 -flto
> -fno-use-linker-plugin -flto-partition=none (test for warnings, line
> 28)
> FAIL: gcc.c-torture/compile/pr106537-2.c -O2 -flto -fuse-linker-plugin
> -fno-fat-lto-objects (test for warnings, line 26)
> FAIL: gcc.c-torture/compile/pr106537-2.c -O2 -flto -fuse-linker-plugin
> -fno-fat-lto-objects (test for warnings, line 28)
>
> The problem is that for ==/!=, when one of the types is void*,
> build_binary_op goes to the branch attempting to warn about
> comparing void* with a function pointer, and never gets to the 
> -Wcompare-distinct-pointer-types warning.

Oof I wonder what happened with my regtesting.

I just pushed the patch below as obvious, which adjusts the tests to
conform to GCC's behavior of not emitting that pedwarn for
equality/inequality of void pointers with non-function pointers.

Sorry about this.  And thanks for reporting.

>From 721f7e2c4e5eed645593258624dd91e6c39f3bd2 Mon Sep 17 00:00:00 2001
From: "Jose E. Marchesi" 
Date: Thu, 24 Aug 2023 17:10:52 +0200
Subject: [PATCH] Fix tests for PR 106537.

This patch fixes the tests for PR 106537 (support for
-W[no]-compare-distinct-pointer-types) which were expecting the
warning when checking for equality/inequality of void pointers with
non-function pointers.

gcc/testsuite/ChangeLog:

PR c/106537
* gcc.c-torture/compile/pr106537-1.c: Comparing void pointers to
non-function pointers is legit.
* gcc.c-torture/compile/pr106537-2.c: Likewise.
---
 gcc/testsuite/gcc.c-torture/compile/pr106537-1.c | 6 --
 gcc/testsuite/gcc.c-torture/compile/pr106537-2.c | 6 --
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c 
b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
index 3f3b06577d5..b67b6090dc3 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
@@ -25,9 +25,11 @@ int xdp_context (struct xdp_md *xdp)
 return 3;
   if (metadata + 1 <= data) /* { dg-warning "comparison of distinct pointer 
types" } */
 return 4;
-  if (metadata + 1 == data) /* { dg-warning "comparison of distinct pointer 
types" } */
+  /* Note that it is ok to check for equality or inequality betewen void
+ pointers and any other non-function pointers.  */
+  if ((int*) (metadata + 1) == (long*) data) /* { dg-warning "comparison of 
distinct pointer types" } */
 return 5;
-  if (metadata + 1 != data) /* { dg-warning "comparison of distinct pointer 
types" } */
+  if ((int*) metadata + 1 != (long*) d

Re: [PATCH] bpf: neg instruction does not accept an immediate

2023-08-21 Thread Jose E. Marchesi via Gcc-patches


> The BPF virtual machine does not support neg nor neg32 instructions with
> an immediate.
>
> The erroneous instructions were removed from binutils:
> https://sourceware.org/pipermail/binutils/2023-August/129135.html
>
> Change the define_insn so that an immediate cannot be accepted.
>
> From testing, a neg-immediate was probably never chosen over a
> mov-immediate anyway.

OK.
Thanks!

>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/
>
>   * config/bpf/bpf.md (neg): Second operand must be a register.
> ---
>  gcc/config/bpf/bpf.md | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index a64de1095ed..e87d72182bb 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -163,8 +163,8 @@ (define_insn "sub3"
>  
>  ;;; Negation
>  (define_insn "neg2"
> -  [(set (match_operand:AM 0 "register_operand"   "=r,r")
> -(neg:AM (match_operand:AM 1 "reg_or_imm_operand" " 0,I")))]
> +  [(set (match_operand:AM 0 "register_operand" "=r")
> +(neg:AM (match_operand:AM 1 "register_operand" " 0")))]
>""
>"{neg\t%0|%w0 = -%w1}"
>[(set_attr "type" "")])


[PATCH V2] Emit funcall external declarations only if actually used.

2023-08-21 Thread Jose E. Marchesi via Gcc-patches
[Differences from V1:
- Prototype for call_from_call_insn moved before comment block.
- Reuse the `call' flag for SYMBOL_REF_LIBCALL.
- Fallback to check REG_CALL_DECL in non-direct calls.
- New test to check correct behavior for non-direct calls.]

There are many places in GCC where alternative local sequences are
tried in order to determine what is the cheapest or best alternative
to use in the current target.  When any of these sequences involve a
libcall, the current implementation of emit_library_call_value_1
introduce a side-effect consisting on emitting an external declaration
for the funcall (such as __divdi3) which is thus emitted even if the
sequence that does the libcall is not retained.

This is problematic in targets such as BPF, because the kernel loader
chokes on the spurious symbol __divdi3 and makes the resulting BPF
object unloadable.  Note that BPF objects are not linked before being
loaded.

This patch changes emit_library_call_value_1 to mark the target
SYMBOL_REF as a libcall.  Then, the emission of the external
declaration is done in the first loop of final.cc:shorten_branches.
This happens only if the corresponding sequence has been kept.

Regtested in x86_64-linux-gnu.
Tested with host x86_64-linux-gnu with target bpf-unknown-none.

gcc/ChangeLog

* rtl.h (SYMBOL_REF_LIBCALL): Define.
* calls.cc (emit_library_call_value_1): Do not emit external
libcall declaration here.
* final.cc (shorten_branches): Do it here.

gcc/testsuite/ChangeLog

* gcc.target/bpf/divmod-libcall-1.c: New test.
* gcc.target/bpf/divmod-libcall-2.c: Likewise.
* gcc.c-torture/compile/libcall-2.c: Likewise.
---
 gcc/calls.cc  |  9 +++---
 gcc/final.cc  | 30 +++
 gcc/rtl.h |  5 
 .../gcc.c-torture/compile/libcall-2.c |  8 +
 .../gcc.target/bpf/divmod-libcall-1.c | 19 
 .../gcc.target/bpf/divmod-libcall-2.c | 16 ++
 6 files changed, 83 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/libcall-2.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 1f3a6d5c450..219ea599b16 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
value,
|| argvec[i].partial != 0)
   update_stack_alignment_for_call ([i].locate);
 
-  /* If this machine requires an external definition for library
- functions, write one out.  */
-  assemble_external_libcall (fun);
+  /* Mark the emitted target as a libcall.  This will be used by final
+ in order to emit an external symbol declaration if the libcall is
+ ever used.  */
+  SYMBOL_REF_LIBCALL (fun) = 1;
 
   original_args_size = args_size;
   args_size.constant = (aligned_upper_bound (args_size.constant
@@ -4735,7 +4736,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
value,
   valreg,
   old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
 
-  if (flag_ipa_ra)
+  if (flag_ipa_ra || SYMBOL_REF_LIBCALL (orgfun))
 {
   rtx datum = orgfun;
   gcc_assert (GET_CODE (datum) == SYMBOL_REF);
diff --git a/gcc/final.cc b/gcc/final.cc
index dd3e22547ac..2041e43fdd1 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -804,6 +804,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
 }
 
 
+static rtx call_from_call_insn (rtx_call_insn *insn);
+
 /* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible.  */
 
@@ -850,6 +852,34 @@ shorten_branches (rtx_insn *first)
   for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
 {
   INSN_SHUID (insn) = i++;
+
+  /* If this is a `call' instruction implementing a libcall, and
+ this machine requires an external definition for library
+ functions, write one out.  */
+  if (CALL_P (insn))
+{
+  rtx x;
+
+  if ((x = call_from_call_insn (dyn_cast  (insn)))
+  && (x = XEXP (x, 0))
+  && MEM_P (x)
+  && (x = XEXP (x, 0))
+  && SYMBOL_REF_P (x)
+  && SYMBOL_REF_LIBCALL (x))
+{
+  /* Direct call.  */
+  assemble_external_libcall (x);
+}
+  else if ((x = find_reg_note (insn, REG_CALL_DECL, NULL_RTX))
+   && (x = XEXP (x, 0)))
+{
+  /* Indirect call with REG_CALL_DECL note.  */
+  gcc_assert (SYMBOL_REF_P (x));
+  if (SYMBOL_REF_LIBCALL (x))
+assemble_external_libcall (x);
+}
+}
+
   if (INSN_P (insn))
continue;
 
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e1c51156f90..28be708a55f 100644

Re: [PATCH] Emit funcall external declarations only if actually used.

2023-08-18 Thread Jose E. Marchesi via Gcc-patches


Hi Jakub.
Thanks for the review.

> On Fri, Aug 18, 2023 at 03:53:51PM +0200, Jose E. Marchesi via Gcc-patches 
> wrote:
>> --- a/gcc/final.cc
>> +++ b/gcc/final.cc
>> @@ -815,6 +815,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
>> reorg.cc, since the branch splitting exposes new instructions with delay
>> slots.  */
>>  
>> +static rtx call_from_call_insn (rtx_call_insn *insn);
>> +
>
> I'd say the forward declaration should go before the function comment, so
> that it is clear the function comment talks about shorten_branches.

Will do.

>
>>  void
>>  shorten_branches (rtx_insn *first)
>>  {
>> @@ -850,6 +852,20 @@ shorten_branches (rtx_insn *first)
>>for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
>>  {
>>INSN_SHUID (insn) = i++;
>> +
>> +  /* If this is a `call' instruction implementing a libcall,
>> + and this machine requires an external definition for library
>> + functions, write one out.  */
>> +  if (CALL_P (insn))
>> +{
>> +  rtx x = call_from_call_insn (dyn_cast  (insn));
>> +  x = XEXP (x, 0);
>> +  if (x && MEM_P (x)
>
> When all conditions don't fit on one line, each && condition should be on
> its own line.

Will fix.

>
>> +  && SYMBOL_REF_P (XEXP (x, 0))
>> +  && SYMBOL_REF_LIBCALL (XEXP (x, 0)))
>> +assemble_external_libcall (XEXP (x, 0));
>> +}
>
> This won't work if target can't use a direct call instruction.
> Consider
> __int128 a, b; void foo () { a = a / b; }
> on x86_64-linux.  With just -O2, the above works fine, with
> -O2 -mcmodel=large it will not, the call is indirect, but at least one has
> REG_CALL_DECL note that could be used as fallback to the above.
> And with -O0 -mcmodel=large because flag_ipa_ra is false REG_CALL_DECL isn't
> emitted at all.
> So, perhaps you could emit the REG_CALL_DECL note even if !flag_ipa_ra
> when SYMBOL_REF_LIBCALL is set?

Hmm something like this?

(I am aware that as things stand in emit_library_call_value_1 that
 conditional will be always true, but I think it is good to keep the
 conditional as documentation and in case emit_library_call_value_1
 changes in the future.  Note also that `fun' is known to be `orgfun'
 when the bit it set.  That may change later as per
 prepare_call_address.)

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 1f3a6d5c450..219ea599b16 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
value,
|| argvec[i].partial != 0)
   update_stack_alignment_for_call ([i].locate);
 
-  /* If this machine requires an external definition for library
- functions, write one out.  */
-  assemble_external_libcall (fun);
+  /* Mark the emitted target as a libcall.  This will be used by final
+ in order to emit an external symbol declaration if the libcall is
+ ever used.  */
+  SYMBOL_REF_LIBCALL (fun) = 1;
 
   original_args_size = args_size;
   args_size.constant = (aligned_upper_bound (args_size.constant
@@ -4735,7 +4736,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
value,
   valreg,
   old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
 
-  if (flag_ipa_ra)
+  if (flag_ipa_ra || SYMBOL_REF_LIBCALL (orgfun))
 {
   rtx datum = orgfun;
   gcc_assert (GET_CODE (datum) == SYMBOL_REF);
diff --git a/gcc/final.cc b/gcc/final.cc
index dd3e22547ac..53f5d890809 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -804,6 +804,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
 }
 
 
+static rtx call_from_call_insn (rtx_call_insn *insn);
+
 /* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible.  */
 
@@ -850,6 +852,19 @@ shorten_branches (rtx_insn *first)
   for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
 {
   INSN_SHUID (insn) = i++;
+
+  /* If this is a `call' instruction or implementing a libcall,
+ and this machine requires an external definition for library
+ functions, write one out.  */
+  if (CALL_P (insn))
+{
+  rtx x = call_from_call_insn (dyn_cast  (insn));
+
+  if ((x = XEXP (x, 0)) && MEM_P (x) && SYMBOL_REF_P (XEXP (x, 0))
+  || (x = find_reg_note (insn, REG_CALL_DECL, NULL_RTX)))
+assemble_external_libcall (XEXP (x, 0));
+}
+
   if (INSN_P (insn))
continue;
 
>> diff --git a/gcc/rtl.h b/gcc/rtl.h
>> index e1c51156f90..945e3267a34 100644
>> --- a/gcc/rtl.h
>> +++ b/gcc/rtl.h
>> @@ -402,6 +402,8 @@ struct GTY((desc("0"), tag(&q

[PATCH] Emit funcall external declarations only if actually used.

2023-08-18 Thread Jose E. Marchesi via Gcc-patches
[Previous thread:
 https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608162.html]

There are many places in GCC where alternative local sequences are
tried in order to determine what is the cheapest or best alternative
to use in the current target.  When any of these sequences involve a
libcall, the current implementation of emit_library_call_value_1
introduce a side-effect consisting on emitting an external declaration
for the funcall (such as __divdi3) which is thus emitted even if the
sequence that does the libcall is not retained.

This is problematic in targets such as BPF, because the kernel loader
chokes on the spurious symbol __divdi3 and makes the resulting BPF
object unloadable.  Note that BPF objects are not linked before being
loaded.

This patch changes emit_library_call_value_1 to mark the target
SYMBOL_REF as a libcall.  Then, the emission of the external
declaration is done in the first loop of final.cc:shorten_branches.
This happens only if the corresponding sequence has been kept.

Regtested in x86_64-linux-gnu.
Tested with host x86_64-linux-gnu with target bpf-unknown-none.

gcc/ChangeLog

* rtl.h: New flag is_libcall.
(SYMBOL_REF_LIBCALL): Define.
* calls.cc (emit_library_call_value_1): Do not emit external
libcall declaration here.
* final.cc (shorten_branches): Do it here.

gcc/testsuite/ChangeLog

* gcc.target/bpf/divmod-libcall-1.c: New test.
* gcc.target/bpf/divmod-libcall-2.c: Likewise.
---
 gcc/calls.cc  |  7 ---
 gcc/final.cc  | 16 
 gcc/rtl.h |  6 ++
 .../gcc.target/bpf/divmod-libcall-1.c | 19 +++
 .../gcc.target/bpf/divmod-libcall-2.c | 16 
 5 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/divmod-libcall-2.c

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 1f3a6d5c450..e0ddda42442 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -4388,9 +4388,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx 
value,
|| argvec[i].partial != 0)
   update_stack_alignment_for_call ([i].locate);
 
-  /* If this machine requires an external definition for library
- functions, write one out.  */
-  assemble_external_libcall (fun);
+  /* Mark the emitted target as a libcall.  This will be used by final
+ in order to emit an external symbol declaration if the libcall is
+ ever used.  */
+  SYMBOL_REF_LIBCALL (fun) = 1;
 
   original_args_size = args_size;
   args_size.constant = (aligned_upper_bound (args_size.constant
diff --git a/gcc/final.cc b/gcc/final.cc
index dd3e22547ac..80c112b91f7 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -815,6 +815,8 @@ make_pass_compute_alignments (gcc::context *ctxt)
reorg.cc, since the branch splitting exposes new instructions with delay
slots.  */
 
+static rtx call_from_call_insn (rtx_call_insn *insn);
+
 void
 shorten_branches (rtx_insn *first)
 {
@@ -850,6 +852,20 @@ shorten_branches (rtx_insn *first)
   for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
 {
   INSN_SHUID (insn) = i++;
+
+  /* If this is a `call' instruction implementing a libcall,
+ and this machine requires an external definition for library
+ functions, write one out.  */
+  if (CALL_P (insn))
+{
+  rtx x = call_from_call_insn (dyn_cast  (insn));
+  x = XEXP (x, 0);
+  if (x && MEM_P (x)
+  && SYMBOL_REF_P (XEXP (x, 0))
+  && SYMBOL_REF_LIBCALL (XEXP (x, 0)))
+assemble_external_libcall (XEXP (x, 0));
+}
+
   if (INSN_P (insn))
continue;
 
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e1c51156f90..945e3267a34 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -402,6 +402,8 @@ struct GTY((desc("0"), tag("0"),
  1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.cc.
  Dumped as "/i" in RTL dumps.  */
   unsigned return_val : 1;
+  /* 1 in a SYMBOL_REF if it is the target of a libcall.  */
+  unsigned is_libcall : 1;
 
   union {
 /* The final union field is aligned to 64 bits on LP64 hosts,
@@ -2734,6 +2736,10 @@ do { 
\
 #define SYMBOL_REF_USED(RTX)   \
   (RTL_FLAG_CHECK1 ("SYMBOL_REF_USED", (RTX), SYMBOL_REF)->used)
 
+/* 1 if RTX is a symbol_ref that represents a libcall target.  */
+#define SYMBOL_REF_LIBCALL(RTX) \
+  (RTL_FLAG_CHECK1 ("SYMBOL_REF_LIBCALL", (RTX), SYMBOL_REF)->is_libcall)
+
 /* 1 if RTX is a symbol_ref for a weak symbol.  */
 #define SYMBOL_REF_WEAK(RTX)   \
   (RTL_FLAG_CHECK1 ("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->return_val)
diff --git 

[COMMITTED] bpf: bump maximum frame size limit to 32767 bytes

2023-08-18 Thread Jose E. Marchesi via Gcc-patches
This commit bumps the maximum stack frame size allowed for BPF
functions to the maximum possible value.

Tested in x86_64-linux-gnu host and target bpf-unknown-none.

gcc/ChangeLog

* config/bpf/bpf.opt (mframe-limit): Set default to 32767.

gcc/testsuite/ChangeLog

* gcc.target/bpf/frame-limit-1.c: New test.
* gcc.target/bpf/frame-limit-2.c: Likewise.
---
 gcc/config/bpf/bpf.opt   |  2 +-
 gcc/testsuite/gcc.target/bpf/frame-limit-1.c | 18 ++
 gcc/testsuite/gcc.target/bpf/frame-limit-2.c | 16 
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/frame-limit-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/frame-limit-2.c

diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index 8e240d397e4..efa0380ee3f 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -38,7 +38,7 @@ Target RejectNegative InverseMask(BIG_ENDIAN)
 Generate little-endian eBPF.
 
 mframe-limit=
-Target Joined RejectNegative UInteger IntegerRange(0, 32767) 
Var(bpf_frame_limit) Init(512)
+Target Joined RejectNegative UInteger IntegerRange(0, 32767) 
Var(bpf_frame_limit) Init(32767)
 Set a hard limit for the size of each stack frame, in bytes.
 
 mco-re
diff --git a/gcc/testsuite/gcc.target/bpf/frame-limit-1.c 
b/gcc/testsuite/gcc.target/bpf/frame-limit-1.c
new file mode 100644
index 000..7843e04b5ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/frame-limit-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+/* The stack frame size is limited to 32767 bytes.  */
+
+int
+foo ()
+{
+  long data[4095];
+  return 0;
+}
+
+int
+bar ()
+{
+  long data[4096];
+  return 0;
+} /* { dg-error "stack limit" } */
diff --git a/gcc/testsuite/gcc.target/bpf/frame-limit-2.c 
b/gcc/testsuite/gcc.target/bpf/frame-limit-2.c
new file mode 100644
index 000..57f82e00567
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/frame-limit-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mframe-limit=256" } */
+
+int
+foo ()
+{
+  long data[32];
+  return 0;
+}
+
+int
+bar ()
+{
+  long data[33];
+  return 0;
+} /* { dg-error "stack limit" } */
-- 
2.30.2



Re: [PATCH V4] Add warning options -W[no-]compare-distinct-pointer-types

2023-08-17 Thread Jose E. Marchesi via Gcc-patches


> On Thu, 17 Aug 2023, Jose E. Marchesi via Gcc-patches wrote:
>
>> +@opindex Wcompare-distinct-pointer-types
>> +@item -Wcompare-distinct-pointer-types
>
> This @item should say @r{(C and Objective-C only)}, since the option isn't 
> implemented for C++.  OK with that change.

Pushed with that change.
Thanks for the prompt review!


[PATCH V4] Add warning options -W[no-]compare-distinct-pointer-types

2023-08-17 Thread Jose E. Marchesi via Gcc-patches
[Changes from V3:
- Previous thread:
  https://gcc.gnu.org/pipermail/gcc-patches/2022-August/600625.html
- The tests have been augmented to check all six relational
  operators.  In particular it covers both code paths impacted
  by the patch: the equality/inequality and the relational ops.]

GCC emits pedwarns unconditionally when comparing pointers of
different types, for example:

  int xdp_context (struct xdp_md *xdp)
{
void *data = (void *)(long)xdp->data;
__u32 *metadata = (void *)(long)xdp->data_meta;
__u32 ret;

if (metadata + 1 > data)
  return 0;
return 1;
   }

  /home/jemarch/foo.c: In function ‘xdp_context’:
  /home/jemarch/foo.c:15:20: warning: comparison of distinct pointer types 
lacks a cast
 15 |   if (metadata + 1 > data)
 |^

LLVM supports an option -W[no-]compare-distinct-pointer-types that can
be used in order to enable or disable the emission of such warnings.
It is enabled by default.

This patch adds the same options to GCC.

Documentation and testsuite updated included.
Regtested in x86_64-linu-gnu.
No regressions observed.

gcc/ChangeLog:

PR c/106537
* doc/invoke.texi (Option Summary): Mention
-Wcompare-distinct-pointer-types under `Warning Options'.
(Warning Options): Document -Wcompare-distinct-pointer-types.

gcc/c-family/ChangeLog:

PR c/106537
* c.opt (Wcompare-distinct-pointer-types): New option.

gcc/c/ChangeLog:

PR c/106537
* c-typeck.cc (build_binary_op): Warning on comparing distinct
pointer types only when -Wcompare-distinct-pointer-types.

gcc/testsuite/ChangeLog:

PR c/106537
* gcc.c-torture/compile/pr106537-1.c: New test.
* gcc.c-torture/compile/pr106537-2.c: Likewise.
* gcc.c-torture/compile/pr106537-3.c: Likewise.
---
 gcc/c-family/c.opt|  4 +++
 gcc/c/c-typeck.cc |  6 ++--
 gcc/doc/invoke.texi   |  6 
 .../gcc.c-torture/compile/pr106537-1.c| 34 +++
 .../gcc.c-torture/compile/pr106537-2.c| 32 +
 .../gcc.c-torture/compile/pr106537-3.c| 32 +
 6 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-3.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index c7b567ba7ab..2242524cd3e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1935,6 +1935,10 @@ Winvalid-imported-macros
 C++ ObjC++ Var(warn_imported_macros) Warning
 Warn about macros that have conflicting header units definitions.
 
+Wcompare-distinct-pointer-types
+C ObjC Var(warn_compare_distinct_pointer_types) Warning Init(1)
+Warn if pointers of distinct types are compared without a cast.
+
 flang-info-include-translate
 C++ Var(note_include_translate_yes)
 Note #include directives translated to import declarations.
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 6f2fff51683..e6ddf37d412 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -12772,7 +12772,7 @@ build_binary_op (location_t location, enum tree_code 
code,
  else
/* Avoid warning about the volatile ObjC EH puts on decls.  */
if (!objc_ok)
- pedwarn (location, 0,
+ pedwarn (location, OPT_Wcompare_distinct_pointer_types,
   "comparison of distinct pointer types lacks a cast");
 
  if (result_type == NULL_TREE)
@@ -12912,8 +12912,8 @@ build_binary_op (location_t location, enum tree_code 
code,
  int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
  result_type = build_pointer_type
  (build_qualified_type (void_type_node, qual));
- pedwarn (location, 0,
-  "comparison of distinct pointer types lacks a cast");
+  pedwarn (location, OPT_Wcompare_distinct_pointer_types,
+   "comparison of distinct pointer types lacks a cast");
}
}
   else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3380ed8bd6f..28ee6fb62bb 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -345,6 +345,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wcast-align  -Wcast-align=strict  -Wcast-function-type  -Wcast-qual
 -Wchar-subscripts
 -Wclobbered  -Wcomment
+-Wcompare-distinct-pointer-types
 -Wno-complain-wrong-lang
 -Wconversion  -Wno-coverage-mismatch  -Wno-cpp
 -Wdangling-else  -Wdangling-pointer  -Wdangling-pointer=@var{n}
@@ -9106,6 +9107,11 @@ The latter front end diagnoses
 @samp{f951: Warning: command-line option '-fno-rtti' is valid for C++/D/ObjC++ 
but not for Fortran},
 which may be disabled 

[COMMITTED] bpf: support `naked' function attributes in BPF targets

2023-08-17 Thread Jose E. Marchesi via Gcc-patches
The kernel selftests and other BPF programs make extensive use of the
`naked' function attribute with bodies written using basic inline
assembly.  This patch adds support for the attribute to
bpf-unkonwn-none, makes it to inhibit warnings due to lack of explicit
`return' statement, and updates documentation and testsuite
accordingly.

Tested in x86_64-linux-gnu host and bpf-unknown-none target.

gcc/ChangeLog

PR target/111046
* config/bpf/bpf.cc (bpf_attribute_table): Add entry for the
`naked' function attribute.
(bpf_warn_func_return): New function.
(TARGET_WARN_FUNC_RETURN): Define.
(bpf_expand_prologue): Add preventive comment.
(bpf_expand_epilogue): Likewise.
* doc/extend.texi (BPF Function Attributes): Document the `naked'
function attribute.

gcc/testsuite/ChangeLog

* gcc.target/bpf/naked-1.c: New test.
---
 gcc/config/bpf/bpf.cc  | 25 +
 gcc/doc/extend.texi| 11 +++
 gcc/testsuite/gcc.target/bpf/naked-1.c | 12 
 3 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/bpf/naked-1.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 1d0abd7fbb3..437bd652de3 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -154,6 +154,10 @@ static const struct attribute_spec bpf_attribute_table[] =
  { "preserve_access_index", 0, -1, false, true, false, true,
bpf_handle_preserve_access_index_attribute, NULL },
 
+ /* Support for `naked' function attribute.  */
+ { "naked", 0, 1, false, false, false, false,
+   bpf_handle_fndecl_attribute, NULL },
+
  /* The last attribute spec is set to be NULL.  */
  { NULL,   0,  0, false, false, false, false, NULL, NULL }
 };
@@ -335,6 +339,21 @@ bpf_function_value_regno_p (const unsigned int regno)
 #undef TARGET_FUNCTION_VALUE_REGNO_P
 #define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p
 
+
+/* Determine whether to warn about lack of return statement in a
+   function.  */
+
+static bool
+bpf_warn_func_return (tree decl)
+{
+  /* Naked functions are implemented entirely in assembly, including
+ the return instructions.  */
+  return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE;
+}
+
+#undef TARGET_WARN_FUNC_RETURN
+#define TARGET_WARN_FUNC_RETURN bpf_warn_func_return
+
 /* Compute the size of the function's stack frame, including the local
area and the register-save area.  */
 
@@ -388,6 +407,9 @@ bpf_expand_prologue (void)
  dynamically.  This should have been checked already and an error
  emitted.  */
   gcc_assert (!cfun->calls_alloca);
+
+  /* If we ever need to have a proper prologue here, please mind the
+ `naked' function attribute.  */
 }
 
 /* Expand to the instructions in a function epilogue.  This function
@@ -399,6 +421,9 @@ bpf_expand_epilogue (void)
   /* See note in bpf_expand_prologue for an explanation on why we are
  not restoring callee-saved registers in BPF.  */
 
+  /* If we ever need to do anything else than just generating a return
+ instruction here, please mind the `naked' function attribute.  */
+
   emit_jump_insn (gen_exit ());
 }
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b363386df6e..f657032cbef 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -5172,6 +5172,17 @@ attribute.  Example:
 int bpf_probe_read (void *dst, int size, const void *unsafe_ptr)
   __attribute__ ((kernel_helper (4)));
 @end smallexample
+
+@cindex @code{naked} function attribute, BPF
+@item naked
+This attribute allows the compiler to construct the requisite function
+declaration, while allowing the body of the function to be assembly
+code.  The specified function will not have prologue/epilogue
+sequences generated by the compiler.  Only basic @code{asm} statements
+can safely be included in naked functions (@pxref{Basic Asm}).  While
+using extended @code{asm} or a mixture of basic @code{asm} and C code
+may appear to work, they cannot be depended upon to work reliably and
+are not supported.
 @end table
 
 @node C-SKY Function Attributes
diff --git a/gcc/testsuite/gcc.target/bpf/naked-1.c 
b/gcc/testsuite/gcc.target/bpf/naked-1.c
new file mode 100644
index 000..cbbc4c51697
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/naked-1.c
@@ -0,0 +1,12 @@
+/* Verify that __attribute__((naked)) is accepted and
+   produces a naked function.  Also, the compiler must not
+   warn for the lack of return statement.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -Wreturn-type" } */
+
+int __attribute__((naked)) foo()
+{
+  __asm__ volatile ("@ naked");
+}
+/* { dg-final { scan-assembler "\t@ naked" } } */
+/* { dg-final { scan-assembler "\texit\n" } } */
-- 
2.30.2



Re: [PATCH] bpf: fix pseudoc w regs for small modes [PR111029]

2023-08-17 Thread Jose E. Marchesi via Gcc-patches


> On Tue, Aug 15, 2023 at 9:03 PM Jose E. Marchesi via Gcc-patches
>  wrote:
>>
>>
>> Hello David.
>> Thanks for the patch.
>>
>> OK.
>
> Picking a random patch/mail for this question - how do we maintain BPF
> support for the most recent GCC release which is GCC 13?  I see the
> current state in GCC 13 isn't fully able to provide upstream kernel BPF
> support but GCC 14 contains some bugfixes and some new features(?).
> Is it worthwhile to backport at least bugfixes while GCC 14 is still in
> development even if those are not regression fixes?  Or is GCC 13 BPF
> too broken to be used anyway?

Our plan is:

1. Get git GCC and git binutils to compile all the kernel BPF selftests.
   This covers both functionality (builtins, attributes, BTF, CO-RE,
   etc) and consolidation of behavior between the GNU and llvm bpf
   ports.  We are working very hard to achieve this point and we are
   very near: functionality wise we are on-par in all components, but
   there are some bugs we are fixing.  We expect to be done in a couple
   of weeks.

2. Once the above is achieved, we plan to start doing the backports to
   released/maintained versions of both binutils and GCC so distros like
   Debian (that already package gcc-bpf) can use the toolchain.

3. Next step is to make sure the compiler generates code that can
   generally satisfy the many restrictions imposed by the kernel
   verifier, at least to a point that is practical.  This is a difficult
   general problem not specific to GCC and is shared by llvm and other
   optimizing compilers, sort of a moving target, and it is not clear at
   all how to achieve this in a general and practical way.  We have some
   ideas and have submitted a proposal to discuss this topic during this
   year's Cauldron: "The challenge of compiling for verified targets".

> Thanks,
> Richard.
>
>> > In the BPF pseudo-c assembly dialect, registers treated as 32-bits
>> > rather than the full 64 in various instructions ought to be printed as
>> > "wN" rather than "rN".  But bpf_print_register () was only doing this
>> > for specifically SImode registers, meaning smaller modes were printed
>> > incorrectly.
>> >
>> > This caused assembler errors like:
>> >
>> >   Error: unrecognized instruction `w2 =(s8)r1'
>> >
>> > for a 32-bit sign-extending register move instruction, where the source
>> > register is used in QImode.
>> >
>> > Fix bpf_print_register () to print the "w" version of register when
>> > specified by the template for any mode 32-bits or smaller.
>> >
>> > Tested on bpf-unknown-none.
>> >
>> >   PR target/111029
>> >
>> > gcc/
>> >   * config/bpf/bpf.cc (bpf_print_register): Print 'w' registers
>> >   for any mode 32-bits or smaller, not just SImode.
>> >
>> > gcc/testsuite/
>> >
>> >   * gcc.target/bpf/smov-2.c: New test.
>> >   * gcc.target/bpf/smov-pseudoc-2.c: New test.
>> > ---
>> >  gcc/config/bpf/bpf.cc |  2 +-
>> >  gcc/testsuite/gcc.target/bpf/smov-2.c | 15 +++
>> >  gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c | 15 +++
>> >  3 files changed, 31 insertions(+), 1 deletion(-)
>> >  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-2.c
>> >  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c
>> >
>> > diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
>> > index 3516b79bce4..1d0abd7fbb3 100644
>> > --- a/gcc/config/bpf/bpf.cc
>> > +++ b/gcc/config/bpf/bpf.cc
>> > @@ -753,7 +753,7 @@ bpf_print_register (FILE *file, rtx op, int code)
>> >  fprintf (file, "%s", reg_names[REGNO (op)]);
>> >else
>> >  {
>> > -  if (code == 'w' && GET_MODE (op) == SImode)
>> > +  if (code == 'w' && GET_MODE_SIZE (GET_MODE (op)) <= 4)
>> >   {
>> > if (REGNO (op) == BPF_FP)
>> >   fprintf (file, "w10");
>> > diff --git a/gcc/testsuite/gcc.target/bpf/smov-2.c 
>> > b/gcc/testsuite/gcc.target/bpf/smov-2.c
>> > new file mode 100644
>> > index 000..6f3516d2385
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.target/bpf/smov-2.c
>> > @@ -0,0 +1,15 @@
>> > +/* Check signed 32-bit mov instructions.  */
>> > +/* { dg-do compile } */
>> > +/* { dg-options "-mcpu=v4 -O2" } */
>> > +
>> > +int
>> > +foo (unsigned char a, unsigned short b)
>>

Re: [PATCH] bpf: remove useless define_insn for extendsisi2

2023-08-15 Thread Jose E. Marchesi via Gcc-patches


OK.
Thanks!

> This define_insn is never used, since a sign-extend to the same mode is
> just a move, so delete it.
>
> Tested on x86_64-linux-gnu host for bpf-unknown-none target.
>
> gcc/
>
>   * config/bpf/bpf.md (extendsisi2): Delete useless define_insn.
> ---
>  gcc/config/bpf/bpf.md | 7 ---
>  1 file changed, 7 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index e0a42b9f939..a64de1095ed 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -350,13 +350,6 @@ (define_insn "extendqidi2"
> {ldxsb\t%0,%1|%0 = *(s8 *) (%1)}"
>[(set_attr "type" "alu,ldx")])
>  
> -(define_insn "extendsisi2"
> -  [(set (match_operand:SI 0 "register_operand" "=r")
> -(sign_extend:SI (match_operand:SI 1 "register_operand" "r")))]
> -  "bpf_has_smov"
> -  "{movs32\t%0,%1,32|%w0 = (s32) %w1}"
> -  [(set_attr "type" "alu")])
> -
>  (define_insn "extendhisi2"
>[(set (match_operand:SI 0 "register_operand" "=r")
>  (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]


Re: [PATCH] bpf: fix pseudoc w regs for small modes [PR111029]

2023-08-15 Thread Jose E. Marchesi via Gcc-patches


Hello David.
Thanks for the patch.

OK.

> In the BPF pseudo-c assembly dialect, registers treated as 32-bits
> rather than the full 64 in various instructions ought to be printed as
> "wN" rather than "rN".  But bpf_print_register () was only doing this
> for specifically SImode registers, meaning smaller modes were printed
> incorrectly.
>
> This caused assembler errors like:
>
>   Error: unrecognized instruction `w2 =(s8)r1'
>
> for a 32-bit sign-extending register move instruction, where the source
> register is used in QImode.
>
> Fix bpf_print_register () to print the "w" version of register when
> specified by the template for any mode 32-bits or smaller.
>
> Tested on bpf-unknown-none.
>
>   PR target/111029
>
> gcc/
>   * config/bpf/bpf.cc (bpf_print_register): Print 'w' registers
>   for any mode 32-bits or smaller, not just SImode.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/smov-2.c: New test.
>   * gcc.target/bpf/smov-pseudoc-2.c: New test.
> ---
>  gcc/config/bpf/bpf.cc |  2 +-
>  gcc/testsuite/gcc.target/bpf/smov-2.c | 15 +++
>  gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c | 15 +++
>  3 files changed, 31 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 3516b79bce4..1d0abd7fbb3 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -753,7 +753,7 @@ bpf_print_register (FILE *file, rtx op, int code)
>  fprintf (file, "%s", reg_names[REGNO (op)]);
>else
>  {
> -  if (code == 'w' && GET_MODE (op) == SImode)
> +  if (code == 'w' && GET_MODE_SIZE (GET_MODE (op)) <= 4)
>   {
> if (REGNO (op) == BPF_FP)
>   fprintf (file, "w10");
> diff --git a/gcc/testsuite/gcc.target/bpf/smov-2.c 
> b/gcc/testsuite/gcc.target/bpf/smov-2.c
> new file mode 100644
> index 000..6f3516d2385
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/smov-2.c
> @@ -0,0 +1,15 @@
> +/* Check signed 32-bit mov instructions.  */
> +/* { dg-do compile } */
> +/* { dg-options "-mcpu=v4 -O2" } */
> +
> +int
> +foo (unsigned char a, unsigned short b)
> +{
> +  int x = (char) a;
> +  int y = (short) b;
> +
> +  return x + y;
> +}
> +
> +/* { dg-final { scan-assembler {movs32\t%r.,%r.,8\n} } } */
> +/* { dg-final { scan-assembler {movs32\t%r.,%r.,16\n} } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c 
> b/gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c
> new file mode 100644
> index 000..6af6cadf8df
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/smov-pseudoc-2.c
> @@ -0,0 +1,15 @@
> +/* Check signed 32-bit mov instructions (pseudo-C asm dialect).  */
> +/* { dg-do compile } */
> +/* { dg-options "-mcpu=v4 -O2 -masm=pseudoc" } */
> +
> +int
> +foo (unsigned char a, unsigned short b)
> +{
> +  int x = (char) a;
> +  int y = (short) b;
> +
> +  return x + y;
> +}
> +
> +/* { dg-final { scan-assembler {w. = \(s8\) w.\n} } } */
> +/* { dg-final { scan-assembler {w. = \(s16\) w.\n} } } */


[COMMITTED] bpf: liberate R9 for general register allocation

2023-08-11 Thread Jose E. Marchesi via Gcc-patches
We were reserving one of the hard registers in BPF in order to
implement dynamic stack allocation: alloca and VLAs. However, there is
kernel code that has inline assembly that requires all the non-fixed
registers to be available for register allocation.

This patch:

1. Liberates r9 that is now available for register allocation.

2. Adds a check to GCC so it errors out if the user tries to do
   dynamic stack allocation.  A couple of tests are added for this.

3. Changes xbpf so it no longer saves and restores callee-saved
   registers.  A couple of tests for this have been removed.

4. Adds bpf-*-* to the list of targets that do not support alloca in
   target-support.exp.

Tested in host x86_64-linux-gnu and target bpf-unknown-none.

gcc/ChangeLog

* config/bpf/bpf.md (allocate_stack): Define.
* config/bpf/bpf.h (FIRST_PSEUDO_REGISTER): Make room for fake
stack pointer register.
(FIXED_REGISTERS): Adjust accordingly.
(CALL_USED_REGISTERS): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(REGISTER_NAMES): Likewise.
* config/bpf/bpf.cc (bpf_compute_frame_layout): Do not reserve
space for callee-saved registers.
(bpf_expand_prologue): Do not save callee-saved registers in xbpf.
(bpf_expand_epilogue): Do not restore callee-saved registers in
xbpf.

gcc/testsuite/ChangeLog

* lib/target-supports.exp (check_effective_target_alloca): BPF
target does not support alloca.
* gcc.target/bpf/diag-alloca-1.c: New test.
* gcc.target/bpf/diag-alloca-2.c: Likewise.
* gcc.target/bpf/xbpf-callee-saved-regs-1.c: Remove test.
* gcc.target/bpf/xbpf-callee-saved-regs-2.c: Likewise.
* gcc.target/bpf/regs-availability-1.c: Likewise.
---
 gcc/config/bpf/bpf.cc | 128 ++
 gcc/config/bpf/bpf.h  |  23 ++--
 gcc/config/bpf/bpf.md |  13 ++
 gcc/testsuite/gcc.target/bpf/diag-alloca-1.c  |   9 ++
 gcc/testsuite/gcc.target/bpf/diag-alloca-2.c  |   9 ++
 .../gcc.target/bpf/regs-availability-1.c  |  21 +++
 .../gcc.target/bpf/xbpf-callee-saved-regs-1.c |  17 ---
 .../gcc.target/bpf/xbpf-callee-saved-regs-2.c |  17 ---
 gcc/testsuite/lib/target-supports.exp |   3 +
 9 files changed, 82 insertions(+), 158 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/diag-alloca-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/diag-alloca-2.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/regs-availability-1.c
 delete mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-1.c
 delete mode 100644 gcc/testsuite/gcc.target/bpf/xbpf-callee-saved-regs-2.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index d27a971d0af..3516b79bce4 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -76,10 +76,6 @@ struct GTY(()) machine_function
 {
   /* Number of bytes saved on the stack for local variables.  */
   int local_vars_size;
-
-  /* Number of bytes saved on the stack for callee-saved
- registers.  */
-  int callee_saved_reg_size;
 };
 
 /* Handle an attribute requiring a FUNCTION_DECL;
@@ -346,7 +342,7 @@ static void
 bpf_compute_frame_layout (void)
 {
   int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
-  int padding_locals, regno;
+  int padding_locals;
 
   /* Set the space used in the stack by local variables.  This is
  rounded up to respect the minimum stack alignment.  */
@@ -358,23 +354,9 @@ bpf_compute_frame_layout (void)
 
   cfun->machine->local_vars_size += padding_locals;
 
-  if (TARGET_XBPF)
-{
-  /* Set the space used in the stack by callee-saved used
-registers in the current function.  There is no need to round
-up, since the registers are all 8 bytes wide.  */
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-   if ((df_regs_ever_live_p (regno)
-&& !call_used_or_fixed_reg_p (regno))
-   || (cfun->calls_alloca
-   && regno == STACK_POINTER_REGNUM))
- cfun->machine->callee_saved_reg_size += 8;
-}
-
   /* Check that the total size of the frame doesn't exceed the limit
  imposed by eBPF.  */
-  if ((cfun->machine->local_vars_size
-   + cfun->machine->callee_saved_reg_size) > bpf_frame_limit)
+  if (cfun->machine->local_vars_size > bpf_frame_limit)
 {
   static int stack_limit_exceeded = 0;
 
@@ -393,69 +375,19 @@ bpf_compute_frame_layout (void)
 void
 bpf_expand_prologue (void)
 {
-  HOST_WIDE_INT size;
-
-  size = (cfun->machine->local_vars_size
- + cfun->machine->callee_saved_reg_size);
-
   /* The BPF "hardware" provides a fresh new set of registers for each
  called function, some of which are initialized to the values of
  the arguments passed in the first five registers.  In doing so,
- it saves the values of the registers of the caller, and restored
+ it saves the values of the registers of the caller, and 

[COMMITTED] bpf: allow exceeding max num of args in BPF when always_inline

2023-08-11 Thread Jose E. Marchesi via Gcc-patches
BPF currently limits the number of registers used to pass arguments to
functions to five registers.  There is a check for this at function
expansion time.  However, if a function is guaranteed to be always
inlined (and its body never generated) by virtue of the always_inline
attribute, it can "receive" any number of arguments.

Tested in host x86_64-linux-gnu and target bpf-unknown-none.

gcc/ChangeLog

* config/bpf/bpf.cc (bpf_function_arg_advance): Do not complain
about too many arguments if function is always inlined.

gcc/testsuite/ChangeLog

* gcc.target/bpf/diag-funargs-inline-1.c: New test.
* gcc.target/bpf/diag-funargs.c: Adapt test.
---
 gcc/config/bpf/bpf.cc |  9 +++-
 .../gcc.target/bpf/diag-funargs-inline-1.c| 21 +++
 gcc/testsuite/gcc.target/bpf/diag-funargs.c   |  8 ++-
 3 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 33218b3a818..d27a971d0af 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -732,7 +732,14 @@ bpf_function_arg_advance (cumulative_args_t ca,
   unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD);
 
   if (*cum <= 5 && *cum + num_words > 5)
-error ("too many function arguments for eBPF");
+{
+  /* Too many arguments for BPF.  However, if the function is
+ gonna be inline for sure, we let it pass.  Otherwise, issue
+ an error.  */
+  if (!lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (cfun->decl)))
+error ("too many function arguments for eBPF");
+}
 
   *cum += num_words;
 }
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c 
b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c
new file mode 100644
index 000..e917ef1294e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+inline int __attribute__ ((always_inline))
+foo (int a1,
+ int a2,
+ int a3,
+ int a4,
+ int a5,
+ int a6)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6;
+}
+
+int
+bar (int i1, int i2, int i3, int i4, int i5)
+{
+  return foo (i1, i2, i3, i4, i5, 10);
+}
+
+/* { dg-final { scan-assembler-not "call\t.*" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c 
b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
index d4e9c0683f2..42b5f05b67c 100644
--- a/gcc/testsuite/gcc.target/bpf/diag-funargs.c
+++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c
@@ -11,5 +11,11 @@ foo (int a1,  /* { dg-error "too many function arguments" } 
*/
  int a5,
  int a6)
 {
-  return a6;
+  return a1 + a2 + a3 + a4 + a5 + a6;
+}
+
+int
+bar (int i1, int i2, int i3, int i4, int i5)
+{
+  return foo (i1, i2, i3, i4, i5, 10);
 }
-- 
2.30.2



Re: [PATCH] bpf: Fixed GC mistakes in BPF builtins code.

2023-08-08 Thread Jose E. Marchesi via Gcc-patches


Hi Cuper.

OK.  Hopefully all the roots are marked now to avoid these nodes being
collected.

Thanks.

> Hi everyone,
>
> This patch fixes BPF CO-RE builtins support that missed information for
> garbage collector (GC).
>
> The BPF CO-RE implementation defines several data structures that keep
> builtin information throught all of the compilation flow aside from
> code.  This intentionally avoids having the builtin calls arguments
> expressions/enum/types tree nodes within the compiling code in order to
> avoid the compiler to optimize those away, based on information in
> current compilation unit.
> CO-RE builtins are target kernel specific and very little can be infered
> from type inforamtion within the compilation unit.
>
> Fault was triggered when attempting to compile some BPF kernel big
> examples that revealed the lack of GC information.
>
> Patch also removes some spurious includes of header files.
>
> Best regards,
> Cupertino
>
>
>
> commit c71b5c604189d04664c5b5ee155326fa4b79808b
> Author: Cupertino Miranda 
> Date:   Tue Aug 8 11:12:00 2023 +0100
>
> bpf: Fixed GC mistakes in BPF builtins code.
> 
> This patches fixes problems with GC within the CO-RE builtins
> implementation.
> List of included headers was also reviseD.
> 
> gcc/ChangeLog:
> 
> * config/bpf/core-builtins.cc: Cleaned include headers.
> (struct cr_builtins): Added GTY.
> (cr_builtins_ref): Created.
> (builtins_data) Changed to GC root.
> (allocate_builtin_data): Changed.
> Included gt-core-builtins.h.
> * config/bpf/coreout.cc: (bpf_core_extra) Added GTY.
> (bpf_core_extra_ref): Created.
> (bpf_comment_info): Changed to GC root.
> (bpf_core_reloc_add, output_btfext_header, btf_ext_init): Changed.
>
> diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
> index 575e63d8ea77..c3222b4c7804 100644
> --- a/gcc/config/bpf/core-builtins.cc
> +++ b/gcc/config/bpf/core-builtins.cc
> @@ -22,52 +22,23 @@ along with GCC; see the file COPYING3.  If not see
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> -#include "tm.h"
> +#include "target.h"
>  #include "rtl.h"
> -#include "regs.h"
> -#include "insn-config.h"
> -#include "insn-attr.h"
> -#include "recog.h"
>  #include "output.h"
> -#include "alias.h"
>  #include "tree.h"
>  #include "stringpool.h"
>  #include "attribs.h"
> -#include "varasm.h"
> -#include "stor-layout.h"
> -#include "calls.h"
>  #include "function.h"
> -#include "explow.h"
>  #include "memmodel.h"
>  #include "emit-rtl.h"
> -#include "reload.h"
> -#include "tm_p.h"
> -#include "target.h"
> -#include "basic-block.h"
>  #include "expr.h"
> -#include "optabs.h"
> -#include "bitmap.h"
> -#include "df.h"
> -#include "c-family/c-common.h"
>  #include "diagnostic.h"
> -#include "builtins.h"
> -#include "predict.h"
>  #include "langhooks.h"
> -#include "flags.h"
> -
> -#include "cfg.h"
> +#include "basic-block.h"
>  #include "gimple.h"
>  #include "gimple-iterator.h"
>  #include "gimple-walk.h"
>  #include "tree-pass.h"
> -#include "tree-iterator.h"
> -
> -#include "context.h"
> -#include "pass_manager.h"
> -
> -#include "gimplify.h"
> -#include "gimplify-me.h"
> -
>  #include "plugin.h"
>  
>  #include "ctfc.h"
> @@ -159,37 +130,41 @@ along with GCC; see the file COPYING3.  If not see
>  as a builtin.  */
>  
>  
> -struct cr_builtins
> +struct GTY(()) cr_builtins
>  {
>tree type;
>tree expr;
>tree default_value;
>rtx rtx_default_value;
> -  enum btf_core_reloc_kind kind; /* Recovered from proper argument.  */
> +  enum btf_core_reloc_kind kind;
>enum bpf_builtins orig_builtin_code;
>tree orig_arg_expr;
>  };
> +typedef struct cr_builtins *cr_builtins_ref;
>  
>  #define CORE_BUILTINS_DATA_EMPTY \
>{ NULL_TREE, NULL_TREE, NULL_TREE, NULL_RTX, BPF_RELO_INVALID, \
>  BPF_BUILTIN_UNUSED, NULL }
>  
>  /* Vector definition and its access function.  */
> -vec builtins_data;
> +static GTY(()) vec *builtins_data = NULL;
>  
>  static inline int
>  allocate_builtin_data ()
>  {
> -  struct cr_builtins data = CORE_BUILTINS_DATA_EMPTY;
> -  int ret = builtins_data.length ();
> -  builtins_data.safe_push (data);
> +  if (builtins_data == NULL)
> +vec_alloc (builtins_data, 1);
> +
> +  cr_builtins_ref data = ggc_cleared_alloc ();
> +  int ret = builtins_data->length ();
> +  vec_safe_push (builtins_data, data);
>return ret;
>  }
>  
>  static inline struct cr_builtins *
>  get_builtin_data (int index)
>  {
> -  return _data[index];
> +  return (*builtins_data)[index];
>  }
>  
>  typedef bool
> @@ -200,11 +175,12 @@ search_builtin_data (builtin_local_data_compare_fn 
> callback,
>struct cr_builtins *elem)
>  {
>unsigned int i;
> -  for (i = 0; i < builtins_data.length (); i++)
> -if ((callback != NULL && (callback) (elem, _data[i]))
> -   || (callback == NULL
> - 

Re: [v2 PATCH 2/2] bpf: CO-RE builtins support tests.

2023-08-03 Thread Jose E. Marchesi via Gcc-patches


OK.
Thanks.

> Hi,
>
> Resending this patch since I have noticed I had a testcase added in
> previous patch. Makes more sense here.
>
> Thanks,
> Cupertino
>
> From 334e9ae0f428f6573f2a5e8a3067a4d181b8b9c5 Mon Sep 17 00:00:00 2001
> From: Cupertino Miranda 
> Date: Thu, 27 Jul 2023 18:05:22 +0100
> Subject: [PATCH v2 2/2] bpf: CO-RE builtins support tests.
>
> This patch adds tests for the following builtins:
>   __builtin_preserve_enum_value
>   __builtin_btf_type_id
>   __builtin_preserve_type_info
> ---
>  .../gcc.target/bpf/core-builtin-enumvalue.c   |  52 +
>  .../bpf/core-builtin-enumvalue_errors.c   |  22 
>  .../bpf/core-builtin-enumvalue_opt.c  |  35 ++
>  ...core-builtin-fieldinfo-const-elimination.c |  29 +
>  .../bpf/core-builtin-fieldinfo-errors-1.c |   2 +-
>  .../bpf/core-builtin-fieldinfo-errors-2.c |   2 +-
>  .../gcc.target/bpf/core-builtin-type-based.c  |  58 ++
>  .../gcc.target/bpf/core-builtin-type-id.c |  40 +++
>  gcc/testsuite/gcc.target/bpf/core-support.h   | 109 ++
>  9 files changed, 347 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
>  create mode 100644 
> gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_opt.c
>  create mode 100644 
> gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-type-based.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-builtin-type-id.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/core-support.h
>
> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c 
> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
> new file mode 100644
> index ..3e3334dc089a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue.c
> @@ -0,0 +1,52 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */
> +
> +#include "core-support.h"
> +
> +extern int *v;
> +
> +int foo(void *data)
> +{
> + int i = 0;
> + enum named_ue64 named_unsigned64 = 0;
> + enum named_se64 named_signed64 = 0;
> + enum named_ue named_unsigned = 0;
> + enum named_se named_signed = 0;
> +
> + v[i++] = bpf_core_enum_value_exists (named_unsigned64, UE64_VAL1);
> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL2);
> + v[i++] = bpf_core_enum_value_exists (enum named_ue64, UE64_VAL3);
> + v[i++] = bpf_core_enum_value_exists (named_signed64, SE64_VAL1);
> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL2);
> + v[i++] = bpf_core_enum_value_exists (enum named_se64, SE64_VAL3);
> +
> + v[i++] = bpf_core_enum_value (named_unsigned64, UE64_VAL1);
> + v[i++] = bpf_core_enum_value (named_unsigned64, UE64_VAL2);
> + v[i++] = bpf_core_enum_value (named_signed64, SE64_VAL1);
> + v[i++] = bpf_core_enum_value (named_signed64, SE64_VAL2);
> +
> + v[i++] = bpf_core_enum_value_exists (named_unsigned, UE_VAL1);
> + v[i++] = bpf_core_enum_value_exists (enum named_ue, UE_VAL2);
> + v[i++] = bpf_core_enum_value_exists (enum named_ue, UE_VAL3);
> + v[i++] = bpf_core_enum_value_exists (named_signed, SE_VAL1);
> + v[i++] = bpf_core_enum_value_exists (enum named_se, SE_VAL2);
> + v[i++] = bpf_core_enum_value_exists (enum named_se, SE_VAL3);
> +
> + v[i++] = bpf_core_enum_value (named_unsigned, UE_VAL1);
> + v[i++] = bpf_core_enum_value (named_unsigned, UE_VAL2);
> + v[i++] = bpf_core_enum_value (named_signed, SE_VAL1);
> + v[i++] = bpf_core_enum_value (named_signed, SE_VAL2);
> +
> + return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times "\t.4byte\t0x8\t; bpfcr_type 
> \\(named_ue64\\)" 5 } } */
> +/* { dg-final { scan-assembler-times "\t.4byte\t0x9\t; bpfcr_type 
> \\(named_se64\\)" 5} } */
> +/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_type 
> \\(named_ue\\)" 5 } } */
> +/* { dg-final { scan-assembler-times "\t.4byte\t0xc\t; bpfcr_type 
> \\(named_se\\)" 5} } */
> +/* { dg-final { scan-assembler-times "\t.4byte\t0xa\t; bpfcr_kind" 12 } } 
> BPF_ENUMVAL_EXISTS */
> +/* { dg-final { scan-assembler-times "\t.4byte\t0xb\t; bpfcr_kind" 8 } } 
> BPF_ENUMVAL_VALUE */
> +
> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"0\"\\)" 8 } } */
> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"1\"\\)" 8 } } */
> +/* { dg-final { scan-assembler-times "bpfcr_astr_off \\(\"2\"\\)" 4 } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c 
> b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c
> new file mode 100644
> index ..138e99895160
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/core-builtin-enumvalue_errors.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -dA -gbtf -mco-re" } */
> +
> +#include "core-support.h"
> +
> +extern int *v;
> +
> +unsigned long foo(void *data)
> +{
> +  int i = 0;
> +  enum named_ue64 

Re: [v2 PATCH 1/2] bpf: Implementation of BPF CO-RE builtins

2023-08-03 Thread Jose E. Marchesi via Gcc-patches


Ok.
Thanks!

> From fda9603ded735205b6e20fc5b65a04f8d15685e6 Mon Sep 17 00:00:00 2001
> From: Cupertino Miranda 
> Date: Thu, 6 Apr 2023 15:22:48 +0100
> Subject: [PATCH v2 1/2] bpf: Implementation of BPF CO-RE builtins
>
> This patch updates the support for the BPF CO-RE builtins
> __builtin_preserve_access_index and __builtin_preserve_field_info,
> and adds support for the CO-RE builtins __builtin_btf_type_id,
> __builtin_preserve_type_info and __builtin_preserve_enum_value.
>
> These CO-RE relocations are now converted to __builtin_core_reloc which
> abstracts all of the original builtins in a polymorphic relocation
> specific builtin.
>
> The builtin processing is now split in 2 stages, the first (pack) is
> executed right after the front-end and the second (process) right before
> the asm output.
>
> In expand pass the __builtin_core_reloc is converted to a
> unspec:UNSPEC_CORE_RELOC rtx entry.
>
> The data required to process the builtin is now collected in the packing
> stage (after front-end), not allowing the compiler to optimize any of
> the relevant information required to compose the relocation when
> necessary.
> At expansion, that information is recovered and CTF/BTF is queried to
> construct the information that will be used in the relocation.
> At this point the relocation is added to specific section and the
> builtin is expanded to the expected default value for the builtin.
>
> In order to process __builtin_preserve_enum_value, it was necessary to
> hook the front-end to collect the original enum value reference.
> This is needed since the parser folds all the enum values to its
> integer_cst representation.
>
> More details can be found within the core-builtins.cc.
>
> Regtested in host x86_64-linux-gnu and target bpf-unknown-none.
> ---
>  gcc/config.gcc  |4 +-
>  gcc/config/bpf/bpf-passes.def   |   20 -
>  gcc/config/bpf/bpf-protos.h |4 +-
>  gcc/config/bpf/bpf.cc   |  806 ++
>  gcc/config/bpf/bpf.md   |   17 +
>  gcc/config/bpf/core-builtins.cc | 1394 +++
>  gcc/config/bpf/core-builtins.h  |   35 +
>  gcc/config/bpf/coreout.cc   |   50 +-
>  gcc/config/bpf/coreout.h|   13 +-
>  gcc/config/bpf/t-bpf|6 +-
>  gcc/doc/extend.texi |   51 ++
>  11 files changed, 1595 insertions(+), 805 deletions(-)
>  delete mode 100644 gcc/config/bpf/bpf-passes.def
>  create mode 100644 gcc/config/bpf/core-builtins.cc
>  create mode 100644 gcc/config/bpf/core-builtins.h
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index eba69a463be0..c521669e78b1 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -1597,8 +1597,8 @@ bpf-*-*)
>  use_collect2=no
>  extra_headers="bpf-helpers.h"
>  use_gcc_stdint=provide
> -extra_objs="coreout.o"
> -target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc"
> +extra_objs="coreout.o core-builtins.o"
> +target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc 
> \$(srcdir)/config/bpf/core-builtins.cc"
>  ;;
>  cris-*-elf | cris-*-none)
>   tm_file="elfos.h newlib-stdint.h ${tm_file}"
> diff --git a/gcc/config/bpf/bpf-passes.def b/gcc/config/bpf/bpf-passes.def
> deleted file mode 100644
> index deeaee988a01..
> --- a/gcc/config/bpf/bpf-passes.def
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* Declaration of target-specific passes for eBPF.
> -   Copyright (C) 2021-2023 Free Software Foundation, Inc.
> -
> -   This file is part of GCC.
> -
> -   GCC is free software; you can redistribute it and/or modify it
> -   under the terms of the GNU General Public License as published by
> -   the Free Software Foundation; either version 3, or (at your option)
> -   any later version.
> -
> -   GCC is distributed in the hope that it will be useful, but
> -   WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   General Public License for more details.
> -
> -   You should have received a copy of the GNU General Public License
> -   along with GCC; see the file COPYING3.  If not see
> -   .  */
> -
> -INSERT_PASS_AFTER (pass_df_initialize_opt, 1, pass_bpf_core_attr);
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index b484310e8cbf..fbe0d8a0213f 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -30,7 +30,7 @@ extern void bpf_print_operand_address (FILE *, rtx);
>  extern void bpf_expand_prologue (void);
>  extern void bpf_expand_epilogue (void);
>  extern void bpf_expand_cbranch (machine_mode, rtx *);
> -
> -rtl_opt_pass * make_pass_bpf_core_attr (gcc::context *);
> +const char *bpf_add_core_reloc (rtx *operands, const char *templ);
> +void bpf_replace_core_move_operands (rtx *operands);
>  
>  #endif /* ! GCC_BPF_PROTOS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> 

Re: [PATCH 1/2] bpf: Implementation of BPF CO-RE builtins

2023-08-03 Thread Jose E. Marchesi via Gcc-patches


> Jose E. Marchesi writes:
>
>>> This patch updates the support for the BPF CO-RE builtins
>>> __builtin_preserve_access_index and __builtin_preserve_field_info,
>>> and adds support for the CO-RE builtins __builtin_btf_type_id,
>>> __builtin_preserve_type_info and __builtin_preserve_enum_value.
>>>
>>> These CO-RE relocations are now converted to __builtin_core_reloc which
>>> abstracts all of the original builtins in a polymorphic relocation
>>> specific builtin.
>>>
>>> The builtin processing is now split in 2 stages, the first (pack) is
>>> executed right after the front-end and the second (process) right before
>>> the asm output.
>>>
>>> In expand pass the __builtin_core_reloc is converted to a
>>> unspec:UNSPEC_CORE_RELOC rtx entry.
>>>
>>> The data required to process the builtin is now collected in the packing
>>> stage (after front-end), not allowing the compiler to optimize any of
>>> the relevant information required to compose the relocation when
>>> necessary.
>>> At expansion, that information is recovered and CTF/BTF is queried to
>>> construct the information that will be used in the relocation.
>>> At this point the relocation is added to specific section and the
>>> builtin is expanded to the expected default value for the builtin.
>>>
>>> In order to process __builtin_preserve_enum_value, it was necessary to
>>> hook the front-end to collect the original enum value reference.
>>> This is needed since the parser folds all the enum values to its
>>> integer_cst representation.
>>>
>>> More details can be found within the core-builtins.cc.
>>>
>>> Regtested in host x86_64-linux-gnu and target bpf-unknown-none.
>>> ---
>>>  gcc/config.gcc|4 +-
>>>  gcc/config/bpf/bpf-passes.def |   20 -
>>>  gcc/config/bpf/bpf-protos.h   |4 +-
>>>  gcc/config/bpf/bpf.cc |  817 +-
>>>  gcc/config/bpf/bpf.md |   17 +
>>>  gcc/config/bpf/core-builtins.cc   | 1397 +
>>>  gcc/config/bpf/core-builtins.h|   36 +
>>>  gcc/config/bpf/coreout.cc |   50 +-
>>>  gcc/config/bpf/coreout.h  |   13 +-
>>>  gcc/config/bpf/t-bpf  |6 +-
>>>  gcc/doc/extend.texi   |   51 +
>>>  ...core-builtin-fieldinfo-const-elimination.c |   29 +
>>>  12 files changed, 1639 insertions(+), 805 deletions(-)
>>>  delete mode 100644 gcc/config/bpf/bpf-passes.def
>>>  create mode 100644 gcc/config/bpf/core-builtins.cc
>>>  create mode 100644 gcc/config/bpf/core-builtins.h
>>>  create mode 100644 
>>> gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c
>>>
>>> diff --git a/gcc/config.gcc b/gcc/config.gcc
>>> index eba69a463be0..c521669e78b1 100644
>>> --- a/gcc/config.gcc
>>> +++ b/gcc/config.gcc
>>> @@ -1597,8 +1597,8 @@ bpf-*-*)
>>>  use_collect2=no
>>>  extra_headers="bpf-helpers.h"
>>>  use_gcc_stdint=provide
>>> -extra_objs="coreout.o"
>>> -target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc"
>>> +extra_objs="coreout.o core-builtins.o"
>>> +target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc 
>>> \$(srcdir)/config/bpf/core-builtins.cc"
>>>  ;;
>>>  cris-*-elf | cris-*-none)
>>> tm_file="elfos.h newlib-stdint.h ${tm_file}"
>>> diff --git a/gcc/config/bpf/bpf-passes.def b/gcc/config/bpf/bpf-passes.def
>>> deleted file mode 100644
>>> index deeaee988a01..
>>> --- a/gcc/config/bpf/bpf-passes.def
>>> +++ /dev/null
>>> @@ -1,20 +0,0 @@
>>> -/* Declaration of target-specific passes for eBPF.
>>> -   Copyright (C) 2021-2023 Free Software Foundation, Inc.
>>> -
>>> -   This file is part of GCC.
>>> -
>>> -   GCC is free software; you can redistribute it and/or modify it
>>> -   under the terms of the GNU General Public License as published by
>>> -   the Free Software Foundation; either version 3, or (at your option)
>>> -   any later version.
>>> -
>>> -   GCC is distributed in the hope that it will be useful, but
>>> -   WITHOUT 

Re: [PATCH 1/2] bpf: Implementation of BPF CO-RE builtins

2023-08-03 Thread Jose E. Marchesi via Gcc-patches


> This patch updates the support for the BPF CO-RE builtins
> __builtin_preserve_access_index and __builtin_preserve_field_info,
> and adds support for the CO-RE builtins __builtin_btf_type_id,
> __builtin_preserve_type_info and __builtin_preserve_enum_value.
>
> These CO-RE relocations are now converted to __builtin_core_reloc which
> abstracts all of the original builtins in a polymorphic relocation
> specific builtin.
>
> The builtin processing is now split in 2 stages, the first (pack) is
> executed right after the front-end and the second (process) right before
> the asm output.
>
> In expand pass the __builtin_core_reloc is converted to a
> unspec:UNSPEC_CORE_RELOC rtx entry.
>
> The data required to process the builtin is now collected in the packing
> stage (after front-end), not allowing the compiler to optimize any of
> the relevant information required to compose the relocation when
> necessary.
> At expansion, that information is recovered and CTF/BTF is queried to
> construct the information that will be used in the relocation.
> At this point the relocation is added to specific section and the
> builtin is expanded to the expected default value for the builtin.
>
> In order to process __builtin_preserve_enum_value, it was necessary to
> hook the front-end to collect the original enum value reference.
> This is needed since the parser folds all the enum values to its
> integer_cst representation.
>
> More details can be found within the core-builtins.cc.
>
> Regtested in host x86_64-linux-gnu and target bpf-unknown-none.
> ---
>  gcc/config.gcc|4 +-
>  gcc/config/bpf/bpf-passes.def |   20 -
>  gcc/config/bpf/bpf-protos.h   |4 +-
>  gcc/config/bpf/bpf.cc |  817 +-
>  gcc/config/bpf/bpf.md |   17 +
>  gcc/config/bpf/core-builtins.cc   | 1397 +
>  gcc/config/bpf/core-builtins.h|   36 +
>  gcc/config/bpf/coreout.cc |   50 +-
>  gcc/config/bpf/coreout.h  |   13 +-
>  gcc/config/bpf/t-bpf  |6 +-
>  gcc/doc/extend.texi   |   51 +
>  ...core-builtin-fieldinfo-const-elimination.c |   29 +
>  12 files changed, 1639 insertions(+), 805 deletions(-)
>  delete mode 100644 gcc/config/bpf/bpf-passes.def
>  create mode 100644 gcc/config/bpf/core-builtins.cc
>  create mode 100644 gcc/config/bpf/core-builtins.h
>  create mode 100644 
> gcc/testsuite/gcc.target/bpf/core-builtin-fieldinfo-const-elimination.c
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index eba69a463be0..c521669e78b1 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -1597,8 +1597,8 @@ bpf-*-*)
>  use_collect2=no
>  extra_headers="bpf-helpers.h"
>  use_gcc_stdint=provide
> -extra_objs="coreout.o"
> -target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc"
> +extra_objs="coreout.o core-builtins.o"
> +target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc 
> \$(srcdir)/config/bpf/core-builtins.cc"
>  ;;
>  cris-*-elf | cris-*-none)
>   tm_file="elfos.h newlib-stdint.h ${tm_file}"
> diff --git a/gcc/config/bpf/bpf-passes.def b/gcc/config/bpf/bpf-passes.def
> deleted file mode 100644
> index deeaee988a01..
> --- a/gcc/config/bpf/bpf-passes.def
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* Declaration of target-specific passes for eBPF.
> -   Copyright (C) 2021-2023 Free Software Foundation, Inc.
> -
> -   This file is part of GCC.
> -
> -   GCC is free software; you can redistribute it and/or modify it
> -   under the terms of the GNU General Public License as published by
> -   the Free Software Foundation; either version 3, or (at your option)
> -   any later version.
> -
> -   GCC is distributed in the hope that it will be useful, but
> -   WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   General Public License for more details.
> -
> -   You should have received a copy of the GNU General Public License
> -   along with GCC; see the file COPYING3.  If not see
> -   .  */
> -
> -INSERT_PASS_AFTER (pass_df_initialize_opt, 1, pass_bpf_core_attr);
> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
> index b484310e8cbf..fbcf5111eb21 100644
> --- a/gcc/config/bpf/bpf-protos.h
> +++ b/gcc/config/bpf/bpf-protos.h
> @@ -30,7 +30,7 @@ extern void bpf_print_operand_address (FILE *, rtx);
>  extern void bpf_expand_prologue (void);
>  extern void bpf_expand_epilogue (void);
>  extern void bpf_expand_cbranch (machine_mode, rtx *);
> -
> -rtl_opt_pass * make_pass_bpf_core_attr (gcc::context *);
> +const char *bpf_add_core_reloc (rtx *operands, const char *templ);
> +void bpf_process_move_operands (rtx *operands);
>  
>  #endif /* ! GCC_BPF_PROTOS_H */
> diff 

[COMMITTED] bpf: disable tail call optimization in BPF targets

2023-07-28 Thread Jose E. Marchesi via Gcc-patches
clang disables tail call optimizations in BPF targets.  Do the same in
GCC.

gcc/ChangeLog:

* config/bpf/bpf.cc (bpf_option_override): Disable tail-call
optimizations in BPF target.
---
 gcc/config/bpf/bpf.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index b5b5674edbb..57817cdf2f8 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -273,6 +273,9 @@ bpf_option_override (void)
  "on this architecture");
   flag_stack_protect = 0;
 }
+
+  /* The BPF target does not support tail call optimization.  */
+  flag_optimize_sibling_calls = 0;
 }
 
 #undef TARGET_OPTION_OVERRIDE
-- 
2.30.2



Re: [PATCH] bpf: ISA V4 sign-extending move and load insns [PR110782,PR110784]

2023-07-27 Thread Jose E. Marchesi via Gcc-patches


Hi David.
Thanks for the patch.

> BPF ISA V4 introduces sign-extending move and load operations.  This
> patch makes the BPF backend generate those instructions, when enabled
> and useful.
>
> A new option, -m[no-]smov gates generation of these instructions, and is
> enabled by default for -mcpu=v4 and above.  Tests for the new
> instructions and documentation for the new options are included.
>
> Tested on bpf-unknown-none.
> OK?
>
> gcc/
>
>   * config/bpf/bpf.opt (msmov): New option.
>   * config/bpf/bpf.cc (bpf_option_override): Handle it here.
>   * config/bpf/bpf.md (*extendsidi2): New.
>   (extendhidi2): New.
>   (extendqidi2): New.
>   (extendsisi2): New.
>   (extendhisi2): New.
>   (extendqisi2): New.
>   * doc/invoke.texi (Option Summary): Add -msmov eBPF option.
>   (eBPF Options): Add -m[no-]smov.  Document that -mcpu=v4
>   also enables -msmov.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/sload-1.c: New test.
>   * gcc.target/bpf/sload-pseudoc-1.c: New test.
>   * gcc.target/bpf/smov-1.c: New test.
>   * gcc.target/bpf/smov-pseudoc-1.c: New test.

Looks like you forgot to mention the bugzilla PR in the changelog
entries.  Would be nice to have them there so automatic updates happen
in the bugzillas.

Other than that, OK.
Thanks!

> ---
>  gcc/config/bpf/bpf.cc |  3 ++
>  gcc/config/bpf/bpf.md | 50 +++
>  gcc/config/bpf/bpf.opt|  4 ++
>  gcc/doc/invoke.texi   |  9 +++-
>  gcc/testsuite/gcc.target/bpf/sload-1.c| 16 ++
>  .../gcc.target/bpf/sload-pseudoc-1.c  | 16 ++
>  gcc/testsuite/gcc.target/bpf/smov-1.c | 18 +++
>  gcc/testsuite/gcc.target/bpf/smov-pseudoc-1.c | 18 +++
>  8 files changed, 133 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/sload-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/sload-pseudoc-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/smov-pseudoc-1.c
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 0e07b416add..b5b5674edbb 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -262,6 +262,9 @@ bpf_option_override (void)
>if (bpf_has_sdiv == -1)
>  bpf_has_sdiv = (bpf_isa >= ISA_V4);
>  
> +  if (bpf_has_smov == -1)
> +bpf_has_smov = (bpf_isa >= ISA_V4);
> +
>/* Disable -fstack-protector as it is not supported in BPF.  */
>if (flag_stack_protect)
>  {
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 66436397bb7..a69a239b9d6 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -307,6 +307,56 @@ (define_expand "extendsidi2"
>DONE;
>  })
>  
> +;; ISA V4 introduces sign-extending move and load operations.
> +
> +(define_insn "*extendsidi2"
> +  [(set (match_operand:DI 0 "register_operand" "=r,r")
> +(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,q")))]
> +  "bpf_has_smov"
> +  "@
> +   {movs\t%0,%1,32|%0 = (s32) %1}
> +   {ldxsw\t%0,%1|%0 = *(s32 *) (%1)}"
> +  [(set_attr "type" "alu,ldx")])
> +
> +(define_insn "extendhidi2"
> +  [(set (match_operand:DI 0 "register_operand" "=r,r")
> +(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,q")))]
> +  "bpf_has_smov"
> +  "@
> +   {movs\t%0,%1,16|%0 = (s16) %1}
> +   {ldxsh\t%0,%1|%0 = *(s16 *) (%1)}"
> +  [(set_attr "type" "alu,ldx")])
> +
> +(define_insn "extendqidi2"
> +  [(set (match_operand:DI 0 "register_operand" "=r,r")
> +(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,q")))]
> +  "bpf_has_smov"
> +  "@
> +   {movs\t%0,%1,8|%0 = (s8) %1}
> +   {ldxsb\t%0,%1|%0 = *(s8 *) (%1)}"
> +  [(set_attr "type" "alu,ldx")])
> +
> +(define_insn "extendsisi2"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +(sign_extend:SI (match_operand:SI 1 "register_operand" "r")))]
> +  "bpf_has_smov"
> +  "{movs32\t%0,%1,32|%w0 = (s32) %w1}"
> +  [(set_attr "type" "alu")])
> +
> +(define_insn "extendhisi2"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
> +  "bpf_has_smov"
> +  "{movs32\t%0,%1,16|%w0 = (s16) %w1}"
> +  [(set_attr "type" "alu")])
> +
> +(define_insn "extendqisi2"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
> +  "bpf_has_smov"
> +  "{movs32\t%0,%1,8|%w0 = (s8) %w1}"
> +  [(set_attr "type" "alu")])
> +
>   Data movement
>  
>  (define_mode_iterator MM [QI HI SI DI SF DF])
> diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
> index b21cfcab9ea..8e240d397e4 100644
> --- a/gcc/config/bpf/bpf.opt
> +++ b/gcc/config/bpf/bpf.opt
> @@ -71,6 +71,10 @@ msdiv
>  Target Var(bpf_has_sdiv) Init(-1)
>  Enable signed division and modulus instructions.
>  
> +msmov
> +Target 

Re: [PATCH] bpf: minor doc cleanup for command-line options

2023-07-27 Thread Jose E. Marchesi via Gcc-patches


Hi David, thanks for the patch.
OK.


> This patch makes some minor cleanups to eBPF options documented in
> invoke.texi:
>  - Delete some vestigal docs for removed -mkernel option
>  - Add -mbswap and -msdiv to the option summary
>  - Note the negative versions of several options
>  - Note that -mcpu=v4 also enables -msdiv.
>
> gcc/
>
>   * doc/invoke.texi (Option Summary): Remove -mkernel eBPF option.
>   Add -mbswap and -msdiv eBPF options.
>   (eBPF Options): Remove -mkernel.  Add -mno-{jmpext, jmp32,
>   alu32, v3-atomics, bswap, sdiv}.  Document that -mcpu=v4 also
>   enables -msdiv.
> ---
>  gcc/doc/invoke.texi | 48 ++---
>  1 file changed, 23 insertions(+), 25 deletions(-)
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index e0fd7bd5b72..91113dd5821 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -945,9 +945,10 @@ Objective-C and Objective-C++ Dialects}.
>  -mmemory-latency=@var{time}}
>  
>  @emph{eBPF Options}
> -@gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version}
> +@gccoptlist{-mbig-endian -mlittle-endian
>  -mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
> --mjmp32 -malu32 -mv3-atomics -mcpu=@var{version} -masm=@var{dialect}}
> +-mjmp32 -malu32 -mv3-atomics -mbswap -msdiv -mcpu=@var{version}
> +-masm=@var{dialect}}
>  
>  @emph{FR30 Options}
>  @gccoptlist{-msmall-model  -mno-lsim}
> @@ -24674,18 +24675,6 @@ the value that can be specified should be less than 
> or equal to
>  @samp{32767}.  Defaults to whatever limit is imposed by the version of
>  the Linux kernel targeted.
>  
> -@opindex mkernel
> -@item -mkernel=@var{version}
> -This specifies the minimum version of the kernel that will run the
> -compiled program.  GCC uses this version to determine which
> -instructions to use, what kernel helpers to allow, etc.  Currently,
> -@var{version} can be one of @samp{4.0}, @samp{4.1}, @samp{4.2},
> -@samp{4.3}, @samp{4.4}, @samp{4.5}, @samp{4.6}, @samp{4.7},
> -@samp{4.8}, @samp{4.9}, @samp{4.10}, @samp{4.11}, @samp{4.12},
> -@samp{4.13}, @samp{4.14}, @samp{4.15}, @samp{4.16}, @samp{4.17},
> -@samp{4.18}, @samp{4.19}, @samp{4.20}, @samp{5.0}, @samp{5.1},
> -@samp{5.2}, @samp{latest} and @samp{native}.
> -
>  @opindex mbig-endian
>  @item -mbig-endian
>  Generate code for a big-endian target.
> @@ -24696,30 +24685,38 @@ Generate code for a little-endian target.  This is 
> the default.
>  
>  @opindex mjmpext
>  @item -mjmpext
> -Enable generation of extra conditional-branch instructions.
> +@itemx -mno-jmpext
> +Enable or disable generation of extra conditional-branch instructions.
>  Enabled for CPU v2 and above.
>  
>  @opindex mjmp32
>  @item -mjmp32
> -Enable 32-bit jump instructions. Enabled for CPU v3 and above.
> +@itemx -mno-jmp32
> +Enable or disable generation of 32-bit jump instructions.
> +Enabled for CPU v3 and above.
>  
>  @opindex malu32
>  @item -malu32
> -Enable 32-bit ALU instructions. Enabled for CPU v3 and above.
> +@itemx -mno-alu32
> +Enable or disable generation of 32-bit ALU instructions.
> +Enabled for CPU v3 and above.
> +
> +@opindex mv3-atomics
> +@item -mv3-atomics
> +@itemx -mno-v3-atomics
> +Enable or disable instructions for general atomic operations introduced
> +in CPU v3.  Enabled for CPU v3 and above.
>  
>  @opindex mbswap
>  @item -mbswap
> -Enable byte swap instructions.  Enabled for CPU v4 and above.
> +@itemx -mno-bswap
> +Enable or disable byte swap instructions.  Enabled for CPU v4 and above.
>  
>  @opindex msdiv
>  @item -msdiv
> -Enable signed division and modulus instructions.  Enabled for CPU v4
> -and above.
> -
> -@opindex mv3-atomics
> -@item -mv3-atomics
> -Enable instructions for general atomic operations introduced in CPU v3.
> -Enabled for CPU v3 and above.
> +@itemx -mno-sdiv
> +Enable or disable signed division and modulus instructions.  Enabled for
> +CPU v4 and above.
>  
>  @opindex mcpu
>  @item -mcpu=@var{version}
> @@ -24747,6 +24744,7 @@ All features of v2, plus:
>  All features of v3, plus:
>  @itemize @minus
>  @item Byte swap instructions, as in @option{-mbswap}
> +@item Signed division and modulus instructions, as in @option{-msdiv}
>  @end itemize
>  @end table


Re: [PATCH] bpf: correct pseudo-C template for add3 and sub3

2023-07-27 Thread Jose E. Marchesi via Gcc-patches


> The pseudo-C output templates for these instructions were incorrectly
> using operand 1 rather than operand 2 on the RHS, which led to some
> very incorrect assembly generation with -masm=pseudoc.
>
> Tested on bpf-unknown-none.
> OK?

OK.  Thanks for spotting and fixing this!

>
> gcc/
>
>   * config/bpf/bpf.md (add3): Use %w2 instead of %w1
>   in pseudo-C dialect output template.
>   (sub3): Likewise.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/alu-2.c: New test.
>   * gcc.target/bpf/alu-pseudoc-2.c: Likewise.
> ---
>  gcc/config/bpf/bpf.md|  4 ++--
>  gcc/testsuite/gcc.target/bpf/alu-2.c | 12 
>  gcc/testsuite/gcc.target/bpf/alu-pseudoc-2.c | 13 +
>  3 files changed, 27 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/alu-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/alu-pseudoc-2.c
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 2ffc4ebd17e..66436397bb7 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -131,7 +131,7 @@ (define_insn "add3"
>  (plus:AM (match_operand:AM 1 "register_operand"   " 0,0")
>   (match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
>"1"
> -  "{add\t%0,%2|%w0 += %w1}"
> +  "{add\t%0,%2|%w0 += %w2}"
>[(set_attr "type" "")])
>  
>  ;;; Subtraction
> @@ -144,7 +144,7 @@ (define_insn "sub3"
>  (minus:AM (match_operand:AM 1 "register_operand" " 0")
>(match_operand:AM 2 "register_operand" " r")))]
>""
> -  "{sub\t%0,%2|%w0 -= %w1}"
> +  "{sub\t%0,%2|%w0 -= %w2}"
>[(set_attr "type" "")])
>  
>  ;;; Negation
> diff --git a/gcc/testsuite/gcc.target/bpf/alu-2.c 
> b/gcc/testsuite/gcc.target/bpf/alu-2.c
> new file mode 100644
> index 000..0444a9bc68a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/alu-2.c
> @@ -0,0 +1,12 @@
> +/* Check add and sub instructions.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +long foo (long x, long y)
> +{
> +  return y - x + 4;
> +}
> +
> +/* { dg-final { scan-assembler-not {sub\t(%r.),\1\n} } } */
> +/* { dg-final { scan-assembler {sub\t(\%r.),(\%r.)\n} } } */
> +/* { dg-final { scan-assembler {add\t(\%r.),4\n} } } */
> diff --git a/gcc/testsuite/gcc.target/bpf/alu-pseudoc-2.c 
> b/gcc/testsuite/gcc.target/bpf/alu-pseudoc-2.c
> new file mode 100644
> index 000..751db2477c0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/alu-pseudoc-2.c
> @@ -0,0 +1,13 @@
> +/* Check add and sub instructions (pseudoc asm dialect).  */
> +/* { dg-do compile } */
> +/* { dg-options "-masm=pseudoc" } */
> +
> +long foo (long x, long y)
> +{
> +  return y - x + 4;
> +}
> +
> +/* { dg-final { scan-assembler-not {\t(r.) -= \1\n} } } */
> +/* { dg-final { scan-assembler {\t(r.) -= (r.)\n} } } */
> +/* { dg-final { scan-assembler {\t(r.) \+= 4\n} } } */
> +


Re: [PATCH v2 2/2] bpf: add v3 atomic instructions

2023-07-26 Thread Jose E. Marchesi via Gcc-patches


OK.
Thanks!

> [Changes from v1: fix merge issue in invoke.texi]
>
> This patch adds support for the general atomic operations introduced in
> eBPF v3. In addition to the existing atomic add instruction, this adds:
>  - Atomic and, or, xor
>  - Fetching versions of these operations (including add)
>  - Atomic exchange
>  - Atomic compare-and-exchange
>
> To control emission of these instructions, a new target option
> -m[no-]v3-atomics is added. This option is enabled by -mcpu=v3
> and above.
>
> Support for these instructions was recently added in binutils.
>
> gcc/
>
>   * config/bpf/bpf.opt (mv3-atomics): New option.
>   * config/bpf/bpf.cc (bpf_option_override): Handle it here.
>   * config/bpf/bpf.h (enum_reg_class): Add R0 class.
>   (REG_CLASS_NAMES): Likewise.
>   (REG_CLASS_CONTENTS): Likewise.
>   (REGNO_REG_CLASS): Handle R0.
>   * config/bpf/bpf.md (UNSPEC_XADD): Rename to UNSPEC_AADD.
>   (UNSPEC_AAND): New unspec.
>   (UNSPEC_AOR): Likewise.
>   (UNSPEC_AXOR): Likewise.
>   (UNSPEC_AFADD): Likewise.
>   (UNSPEC_AFAND): Likewise.
>   (UNSPEC_AFOR): Likewise.
>   (UNSPEC_AFXOR): Likewise.
>   (UNSPEC_AXCHG): Likewise.
>   (UNSPEC_ACMPX): Likewise.
>   (atomic_add): Use UNSPEC_AADD and atomic type attribute.
>   Move to...
>   * config/bpf/atomic.md: ...Here. New file.
>   * config/bpf/constraints.md (t): New constraint for R0.
>   * doc/invoke.texi (eBPF Options): Document -mv3-atomics.
>
> gcc/testsuite/
>
>   * gcc.target/bpf/atomic-cmpxchg-1.c: New test.
>   * gcc.target/bpf/atomic-cmpxchg-2.c: New test.
>   * gcc.target/bpf/atomic-fetch-op-1.c: New test.
>   * gcc.target/bpf/atomic-fetch-op-2.c: New test.
>   * gcc.target/bpf/atomic-fetch-op-3.c: New test.
>   * gcc.target/bpf/atomic-op-1.c: New test.
>   * gcc.target/bpf/atomic-op-2.c: New test.
>   * gcc.target/bpf/atomic-op-3.c: New test.
>   * gcc.target/bpf/atomic-xchg-1.c: New test.
>   * gcc.target/bpf/atomic-xchg-2.c: New test.
> ---
>  gcc/config/bpf/atomic.md  | 185 ++
>  gcc/config/bpf/bpf.cc |   3 +
>  gcc/config/bpf/bpf.h  |   6 +-
>  gcc/config/bpf/bpf.md |  29 ++-
>  gcc/config/bpf/bpf.opt|   4 +
>  gcc/config/bpf/constraints.md |   3 +
>  gcc/doc/invoke.texi   |   8 +-
>  .../gcc.target/bpf/atomic-cmpxchg-1.c |  19 ++
>  .../gcc.target/bpf/atomic-cmpxchg-2.c |  19 ++
>  .../gcc.target/bpf/atomic-fetch-op-1.c|  50 +
>  .../gcc.target/bpf/atomic-fetch-op-2.c|  50 +
>  .../gcc.target/bpf/atomic-fetch-op-3.c|  49 +
>  gcc/testsuite/gcc.target/bpf/atomic-op-1.c|  49 +
>  gcc/testsuite/gcc.target/bpf/atomic-op-2.c|  49 +
>  gcc/testsuite/gcc.target/bpf/atomic-op-3.c|  49 +
>  gcc/testsuite/gcc.target/bpf/atomic-xchg-1.c  |  20 ++
>  gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c  |  20 ++
>  17 files changed, 593 insertions(+), 19 deletions(-)
>  create mode 100644 gcc/config/bpf/atomic.md
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-cmpxchg-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-fetch-op-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-fetch-op-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-fetch-op-3.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-op-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-op-2.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-op-3.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-xchg-1.c
>  create mode 100644 gcc/testsuite/gcc.target/bpf/atomic-xchg-2.c
>
> diff --git a/gcc/config/bpf/atomic.md b/gcc/config/bpf/atomic.md
> new file mode 100644
> index 000..caf8cc15cd4
> --- /dev/null
> +++ b/gcc/config/bpf/atomic.md
> @@ -0,0 +1,185 @@
> +;; Machine description for eBPF.
> +;; Copyright (C) 2023 Free Software Foundation, Inc.
> +
> +;; This file is part of GCC.
> +
> +;; GCC is free software; you can redistribute it and/or modify
> +;; it under the terms of the GNU General Public License as published by
> +;; the Free Software Foundation; either version 3, or (at your option)
> +;; any later version.
> +
> +;; GCC is distributed in the hope that it will be useful,
> +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
> +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +;; GNU General Public License for more details.
> +
> +;; You should have received a copy of the GNU General Public License
> +;; along with GCC; see the file COPYING3.  If not see
> +;; .
> +
> +
> +(define_mode_iterator AMO [SI DI])
> +
> +;;; Plain atomic modify operations.
> +
> +;; Non-fetching atomic add predates all 

[COMMITTED] bpf: fix generation of neg and neg32 BPF instructions

2023-07-26 Thread Jose E. Marchesi via Gcc-patches
This patch fixes GCC to generate correct neg and neg32 instructions,
which do not take a source register operand.  A couple of new tests
are added.

Tested in bpf-unknown-none.

gcc/ChangeLog

2023-07-26  Jose E. Marchesi  

* config/bpf/bpf.md: Fix neg{SI,DI}2 insn.

gcc/testsuite/ChangeLog

2023-07-26  Jose E. Marchesi  

* gcc.target/bpf/neg-1.c: New test.
* gcc.target/bpf/neg-pseudoc-1.c: Likewise.
---
 gcc/config/bpf/bpf.md|  4 ++--
 gcc/testsuite/gcc.target/bpf/neg-1.c | 14 ++
 gcc/testsuite/gcc.target/bpf/neg-pseudoc-1.c | 14 ++
 3 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/neg-1.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/neg-pseudoc-1.c

diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 579a8213b09..1b5e1900d4f 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -142,9 +142,9 @@ (define_insn "sub3"
 ;;; Negation
 (define_insn "neg2"
   [(set (match_operand:AM 0 "register_operand"   "=r,r")
-(neg:AM (match_operand:AM 1 "reg_or_imm_operand" " r,I")))]
+(neg:AM (match_operand:AM 1 "reg_or_imm_operand" " 0,I")))]
   ""
-  "{neg\t%0,%1|%w0 = -%w1}"
+  "{neg\t%0|%w0 = -%w1}"
   [(set_attr "type" "")])
 
 ;;; Multiplication
diff --git a/gcc/testsuite/gcc.target/bpf/neg-1.c 
b/gcc/testsuite/gcc.target/bpf/neg-1.c
new file mode 100644
index 000..9ffb956859d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/neg-1.c
@@ -0,0 +1,14 @@
+/* Check negr and negr32 instructions.  */
+
+/* { dg-do compile } */
+/* { dg-options "-malu32" } */
+
+long foo (long a, long b, int x, int y)
+{
+  a = -b;
+  x = -y;
+  return a + x;
+}
+
+/* { dg-final { scan-assembler "neg\t%r.\n" } } */
+/* { dg-final { scan-assembler "neg32\t%r.\n" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/neg-pseudoc-1.c 
b/gcc/testsuite/gcc.target/bpf/neg-pseudoc-1.c
new file mode 100644
index 000..a4fb687f04a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/neg-pseudoc-1.c
@@ -0,0 +1,14 @@
+/* Check negr and negr32 instructions (pseudoc asm dialect.)  */
+
+/* { dg-do compile } */
+/* { dg-options "-malu32 -masm=pseudoc" } */
+
+long foo (long a, long b, int x, int y)
+{
+  a = -b;
+  x = -y;
+  return a + x;
+}
+
+/* { dg-final { scan-assembler {\t(r.) = -\1\n} } } */
+/* { dg-final { scan-assembler {\t(w.) = -\1\n} } } */
-- 
2.30.2



Re: [PATCH 2/2] bpf: add v3 atomic instructions

2023-07-25 Thread Jose E. Marchesi via Gcc-patches


Hi David.

> +<<< HEAD

There is a merge problem there.

>  @opindex mbswap
>  @item -mbswap
>  Enable byte swap instructions.  Enabled for CPU v4 and above.
> @@ -24715,6 +24716,12 @@ Enable byte swap instructions.  Enabled for CPU v4 
> and above.
>  @item -msdiv
>  Enable signed division and modulus instructions.  Enabled for CPU v4
>  and above.
> +===
> +@opindex mv3-atomics
> +@item -mv3-atomics
> +Enable instructions for general atomic operations introduced in CPU v3.
> +Enabled for CPU v3 and above.
> +>>> 6de76bd11b6 (bpf: add v3 atomic instructions)


Re: [PATCH 1/2] bpf: don't print () in bpf_print_operand_address

2023-07-25 Thread Jose E. Marchesi via Gcc-patches


Hi David.

> Unfortunately, the pseudo-C dialect syntax used for some of the v3
> atomic instructions clashes with unconditionally printing the
> surrounding parentheses in bpf_print_operand_address.
>
> Instead, place the parentheses in the output templates where needed.
>
> Tested in bpf-unknown-none.
> OK?
>
> gcc/
>
>   * config/bpf/bpf.cc (bpf_print_operand_address): Don't print
>   enclosing parentheses for pseudo-C dialect.
>   * config/bpf/bpf.md (zero_exdendhidi2): Add parentheses around
>   operands of pseudo-C dialect output templates where needed.
>   (zero_extendqidi2): Likewise.
>   (zero_extendsidi2): Likewise.
>   (*mov): Likewise.
> ---
>  gcc/config/bpf/bpf.cc |  8 
>  gcc/config/bpf/bpf.md | 12 ++--
>  2 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 55b6927a62f..2c077ea834e 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -933,9 +933,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
>switch (GET_CODE (addr))
>  {
>  case REG:
> -  fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "");

We can save the call to fprintf there with a conditional.

>bpf_print_register (file, addr, 0);
> -  fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0");
>break;
>  case PLUS:
>{
> @@ -944,11 +944,11 @@ bpf_print_operand_address (FILE *file, rtx addr)
>  
>   if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT)
> {
> - fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "");

Likewise.

>   bpf_print_register (file, op0, 0);
>   fprintf (file, "+");
>   output_addr_const (file, op1);
> - fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")");
> + fprintf (file, asm_dialect == ASM_NORMAL ? "]" : "");
> }
>   else
> fatal_insn ("invalid address in operand", addr);
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 64342ea1de2..579a8213b09 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -260,7 +260,7 @@ (define_insn "zero_extendhidi2"
>"@
> {and\t%0,0x|%0 &= 0x}
> {mov\t%0,%1\;and\t%0,0x|%0 = %1;%0 &= 0x}
> -   {ldxh\t%0,%1|%0 = *(u16 *) %1}"
> +   {ldxh\t%0,%1|%0 = *(u16 *) (%1)}"
>[(set_attr "type" "alu,alu,ldx")])
>  
>  (define_insn "zero_extendqidi2"
> @@ -270,7 +270,7 @@ (define_insn "zero_extendqidi2"
>"@
> {and\t%0,0xff|%0 &= 0xff}
> {mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff}
> -   {ldxh\t%0,%1|%0 = *(u8 *) %1}"
> +   {ldxh\t%0,%1|%0 = *(u8 *) (%1)}"
>[(set_attr "type" "alu,alu,ldx")])
>  
>  (define_insn "zero_extendsidi2"
> @@ -280,7 +280,7 @@ (define_insn "zero_extendsidi2"
>""
>"@
> * return bpf_has_alu32 ? \"{mov32\t%0,%1|%0 = %1}\" : 
> \"{mov\t%0,%1\;and\t%0,0x|%0 = %1;%0 &= 0x}\";
> -   {ldxw\t%0,%1|%0 = *(u32 *) %1}"
> +   {ldxw\t%0,%1|%0 = *(u32 *) (%1)}"
>[(set_attr "type" "alu,ldx")])
>  
>  ;;; Sign-extension
> @@ -319,11 +319,11 @@ (define_insn "*mov"
>  (match_operand:MM 1 "mov_src_operand"  " q,rI,B,r,I"))]
>""
>"@
> -   {ldx\t%0,%1|%0 = *( *) %1}
> +   {ldx\t%0,%1|%0 = *( *) (%1)}
> {mov\t%0,%1|%0 = %1}
> {lddw\t%0,%1|%0 = %1 ll}
> -   {stx\t%0,%1|*( *) %0 = %1}
> -   {st\t%0,%1|*( *) %0 = %1}"
> +   {stx\t%0,%1|*( *) (%0) = %1}
> +   {st\t%0,%1|*( *) (%0) = %1}"
>  [(set_attr "type" "ldx,alu,alu,stx,st")])
>  
>   Shifts

Otherwise, LGTM.
OK.

Thanks!


Re: [COMMITTED] bpf: add pseudo-c asm dialect for "nop"

2023-07-25 Thread Jose E. Marchesi via Gcc-patches


> The define_insn "nop" was missing a template for the pseudo-c dialect,
> so the normal syntax was unconditionally emitted.

Thank you.

> Tested on bpf-unknown-none, committed as obvious.
>
> gcc/
>
>   * config/bpf/bpf.md (nop): Add pseudo-c asm dialect template.
> ---
>  gcc/config/bpf/bpf.md | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 3e2d760fbe4..64342ea1de2 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -103,7 +103,7 @@ (define_mode_attr msuffix [(SI "32") (DI "")])
>  (define_insn "nop"
>[(const_int 0)]
>""
> -  "ja\t0"
> +  "{ja\t0|goto 0}"
>[(set_attr "type" "alu")])
>  
>   Arithmetic/Logical


[COMMITTED] bpf: sdiv/smod are now part of BPF V4

2023-07-24 Thread Jose E. Marchesi via Gcc-patches
We used to support signed division and signed modulus instructions in
the XBPF GCC-specific extensions to BPF.  However, BPF catched up by
adding these instructions in the V4 of the ISA.

This patch changes GCC in order to use sdiv/smod instructions when
-mcpu=v4 or higher.  The testsuite and the manual have been updated
accordingly.

Tested in bpf-unknown-none.

gcc/ChangeLog

PR target/110783
* config/bpf/bpf.opt: New command-line option -msdiv.
* config/bpf/bpf.md: Conditionalize sdiv/smod on bpf_has_sdiv.
* config/bpf/bpf.cc (bpf_option_override): Initialize
bpf_has_sdiv.
* doc/invoke.texi (eBPF Options): Document -msdiv.

gcc/testsuite/ChangeLog

PR target/110783
* gcc.target/bpf/xbpf-sdiv-1.c: Renamed to sdiv-1.c
* gcc.target/bpf/xbpf-smod-1.c: Renamed to smod-1.c
* gcc.target/bpf/sdiv-1.c: Renamed from xbpf-sdiv-1.c, use -mcpu=v4.
* gcc.target/bpf/smod-1.c: Renamed from xbpf-smod-1.c, use -mcpu=v4.
* gcc.target/bpf/diag-sdiv.c: Use -mcpu=v3.
* gcc.target/bpf/diag-smod.c: Likewise.
---
 gcc/config/bpf/bpf.cc|  3 +++
 gcc/config/bpf/bpf.md| 16 
 gcc/config/bpf/bpf.opt   |  4 
 gcc/doc/invoke.texi  |  5 +
 gcc/testsuite/gcc.target/bpf/diag-sdiv.c |  2 +-
 gcc/testsuite/gcc.target/bpf/diag-smod.c |  2 +-
 .../gcc.target/bpf/{xbpf-sdiv-1.c => sdiv-1.c}   |  2 +-
 .../gcc.target/bpf/{xbpf-smod-1.c => smod-1.c}   |  2 +-
 8 files changed, 24 insertions(+), 12 deletions(-)
 rename gcc/testsuite/gcc.target/bpf/{xbpf-sdiv-1.c => sdiv-1.c} (86%)
 rename gcc/testsuite/gcc.target/bpf/{xbpf-smod-1.c => smod-1.c} (86%)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 18d3b5f14d6..55b6927a62f 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -256,6 +256,9 @@ bpf_option_override (void)
   if (bpf_has_bswap == -1)
 bpf_has_bswap = (bpf_isa >= ISA_V4);
 
+  if (bpf_has_sdiv == -1)
+bpf_has_sdiv = (bpf_isa >= ISA_V4);
+
   /* Disable -fstack-protector as it is not supported in BPF.  */
   if (flag_stack_protect)
 {
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 81e2268c400..3e2d760fbe4 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -167,8 +167,8 @@ (define_insn "*mulsidi3_zeroextend"
 
 ;;; Division
 
-;; Note that eBPF doesn't provide instructions for signed integer
-;; division.
+;; Note that eBPF <= V3 doesn't provide instructions for signed
+;; integer division.
 
 (define_insn "udiv3"
   [(set (match_operand:AM 0 "register_operand" "=r,r")
@@ -178,20 +178,20 @@ (define_insn "udiv3"
   "{div\t%0,%2|%w0 /= %w2}"
   [(set_attr "type" "")])
 
-;; However, xBPF does provide a signed division operator, sdiv.
+;; However, BPF V4 does provide a signed division operator, sdiv.
 
 (define_insn "div3"
   [(set (match_operand:AM 0 "register_operand" "=r,r")
 (div:AM (match_operand:AM 1 "register_operand" " 0,0")
 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
-  "TARGET_XBPF"
+  "bpf_has_sdiv"
   "{sdiv\t%0,%2|%w0 s/= %w2}"
   [(set_attr "type" "")])
 
 ;;; Modulus
 
-;; Note that eBPF doesn't provide instructions for signed integer
-;; remainder.
+;; Note that eBPF <= V3 doesn't provide instructions for signed
+;; integer remainder.
 
 (define_insn "umod3"
   [(set (match_operand:AM 0 "register_operand" "=r,r")
@@ -201,13 +201,13 @@ (define_insn "umod3"
   "{mod\t%0,%2|%w0 %%= %w2}"
   [(set_attr "type" "")])
 
-;; Again, xBPF provides a signed version, smod.
+;; However, BPF V4 does provide a signed modulus operator, smod.
 
 (define_insn "mod3"
   [(set (match_operand:AM 0 "register_operand" "=r,r")
 (mod:AM (match_operand:AM 1 "register_operand" " 0,0")
 (match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
-  "TARGET_XBPF"
+  "bpf_has_sdiv"
   "{smod\t%0,%2|%w0 s%%= %w2}"
   [(set_attr "type" "")])
 
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index 3bf9033279b..bd35f8dbd0c 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -63,6 +63,10 @@ mbswap
 Target Var(bpf_has_bswap) Init(-1)
 Enable byte swap instructions.
 
+msdiv
+Target Var(bpf_has_sdiv) Init(-1)
+Enable signed division and modulus instructions.
+
 mcpu=
 Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a977a34db42..fa765d5a0dd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -24711,6 +24711,11 @@ Enable 32-bit ALU instructions. Enabled for CPU v3 and 
above.
 @item -mbswap
 Enable byte swap instructions.  Enabled for CPU v4 and above.
 
+@opindex msdiv
+@item -msdiv
+Enable signed division and modulus instructions.  Enabled for CPU v4
+and above.
+
 @opindex mcpu
 @item -mcpu=@var{version}
 This specifies which version of the eBPF ISA to target. Newer 

[COMMITTED] bpf: remove -mkernel option and BPF_KERNEL_VERSION_CODE

2023-07-24 Thread Jose E. Marchesi via Gcc-patches
Having the ability of specifying a target kernel version when building
a BPF program is one of these things that sound pretty good in theory,
but simply don't work in practice: kernels in practice contain
backports, etc.  Also, the addition of CO-RE to BPF has made this
uneccessary.

This patch removes the -mkernel command line option and also the
associated BPF_KERNEL_VERSION_CODE pre-processor constant.

Tested in bpf-unknown-none.

gcc/ChangeLog

* config/bpf/bpf-opts.h (enum bpf_kernel_version): Remove enum.
* config/bpf/bpf.opt (mkernel): Remove option.
* config/bpf/bpf.cc (bpf_target_macros): Do not define
BPF_KERNEL_VERSION_CODE.
---
 gcc/config/bpf/bpf-opts.h | 33 ---
 gcc/config/bpf/bpf.cc | 40 --
 gcc/config/bpf/bpf.opt| 87 ---
 3 files changed, 160 deletions(-)

diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
index e0be591b479..5c9441ccb28 100644
--- a/gcc/config/bpf/bpf-opts.h
+++ b/gcc/config/bpf/bpf-opts.h
@@ -20,39 +20,6 @@
 #ifndef BPF_OPTS_H
 #define BPF_OPTS_H
 
-/* Supported versions of the Linux kernel.  */
-enum bpf_kernel_version
-{
-  /* Linux 4.x */
-  LINUX_V4_0,
-  LINUX_V4_1,
-  LINUX_V4_2,
-  LINUX_V4_3,
-  LINUX_V4_4,
-  LINUX_V4_5,
-  LINUX_V4_6,
-  LINUX_V4_7,
-  LINUX_V4_8,
-  LINUX_V4_9,
-  LINUX_V4_10,
-  LINUX_V4_11,
-  LINUX_V4_12,
-  LINUX_V4_13,
-  LINUX_V4_14,
-  LINUX_V4_15,
-  LINUX_V4_16,
-  LINUX_V4_17,
-  LINUX_V4_18,
-  LINUX_V4_19,
-  LINUX_V4_20,
-  /* Linux 5.x  */
-  LINUX_V5_0,
-  LINUX_V5_1,
-  LINUX_V5_2,
-  LINUX_LATEST = LINUX_V5_2,
-  LINUX_NATIVE,
-};
-
 enum bpf_isa_version
 {
   ISA_V1,
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 6bc715429dc..18d3b5f14d6 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -308,46 +308,6 @@ bpf_target_macros (cpp_reader *pfile)
 builtin_define ("__BPF_BIG_ENDIAN__");
   else
 builtin_define ("__BPF_LITTLE_ENDIAN__");
-
-  /* Define BPF_KERNEL_VERSION_CODE */
-  {
-const char *version_code;
-char *kernel_version_code;
-
-switch (bpf_kernel)
-  {
-  case LINUX_V4_0: version_code = "0x4"; break;
-  case LINUX_V4_1: version_code = "0x40100"; break;
-  case LINUX_V4_2: version_code = "0x40200"; break;
-  case LINUX_V4_3: version_code = "0x40300"; break;
-  case LINUX_V4_4: version_code = "0x40400"; break;
-  case LINUX_V4_5: version_code = "0x40500"; break;
-  case LINUX_V4_6: version_code = "0x40600"; break;
-  case LINUX_V4_7: version_code = "0x40700"; break;
-  case LINUX_V4_8: version_code = "0x40800"; break;
-  case LINUX_V4_9: version_code = "0x40900"; break;
-  case LINUX_V4_10: version_code = "0x40a00"; break;
-  case LINUX_V4_11: version_code = "0x40b00"; break;
-  case LINUX_V4_12: version_code = "0x40c00"; break;
-  case LINUX_V4_13: version_code = "0x40d00"; break;
-  case LINUX_V4_14: version_code = "0x40e00"; break;
-  case LINUX_V4_15: version_code = "0x40f00"; break;
-  case LINUX_V4_16: version_code = "0x41000"; break;
-  case LINUX_V4_17: version_code = "0x42000"; break;
-  case LINUX_V4_18: version_code = "0x43000"; break;
-  case LINUX_V4_19: version_code = "0x44000"; break;
-  case LINUX_V4_20: version_code = "0x45000"; break;
-  case LINUX_V5_0: version_code = "0x5"; break;
-  case LINUX_V5_1: version_code = "0x50100"; break;
-  case LINUX_V5_2: version_code = "0x50200"; break;
-  default:
-   gcc_unreachable ();
-  }
-
-kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=",
-   version_code, NULL));
-builtin_define (kernel_version_code);
-  }
 }
 
 /* Return an RTX representing the place where a function returns or
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index 1e4dcc871d7..3bf9033279b 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -21,93 +21,6 @@
 HeaderInclude
 config/bpf/bpf-opts.h
 
-; Selecting the kind of kernel the eBPF will be running on.
-
-mkernel=
-Target RejectNegative Joined Var(bpf_kernel) Enum(bpf_kernel) 
Init(LINUX_LATEST)
-Generate eBPF for the given Linux kernel version.
-
-Enum
-Name(bpf_kernel) Type(enum bpf_kernel_version)
-
-EnumValue
-Enum(bpf_kernel) String(native) Value(LINUX_NATIVE) DriverOnly
-
-EnumValue
-Enum(bpf_kernel) String(latest) Value(LINUX_LATEST) DriverOnly
-
-EnumValue
-Enum(bpf_kernel) String(4.0) Value(LINUX_V4_0)
-
-EnumValue
-Enum(bpf_kernel) String(4.1) Value(LINUX_V4_1)
-
-EnumValue
-Enum(bpf_kernel) String(4.2) Value(LINUX_V4_2)
-
-EnumValue
-Enum(bpf_kernel) String(4.3) Value(LINUX_V4_3)
-
-EnumValue
-Enum(bpf_kernel) String(4.4) Value(LINUX_V4_4)
-
-EnumValue
-Enum(bpf_kernel) String(4.5) Value(LINUX_V4_5)
-
-EnumValue
-Enum(bpf_kernel) String(4.6) Value(LINUX_V4_6)
-
-EnumValue
-Enum(bpf_kernel) String(4.7) Value(LINUX_V4_7)
-
-EnumValue
-Enum(bpf_kernel) String(4.8) 

[COMMITTED] bpf: make use of the bswap{16,32,64} V4 BPF instruction

2023-07-24 Thread Jose E. Marchesi via Gcc-patches
This patch makes the BPF backend to use the new V4 bswap{16,32,64}
instructions in order to implement the __builtin_bswap{16,32,64}
built-ins.  It also adds support for -mcpu=v4 and -m[no]bswap
command-line options.  Tests and doc updates are includes.

Tested in bpf-unknown-none.

gcc/ChangeLog

PR target/110786
* config/bpf/bpf.opt (mcpu): Add ISA_V4 and make it the default.
(mbswap): New option.
* config/bpf/bpf-opts.h (enum bpf_isa_version): New value ISA_V4.
* config/bpf/bpf.cc (bpf_option_override): Set bpf_has_bswap.
* config/bpf/bpf.md: Use bswap instructions if available for
bswap* insn, and fix constraint.
* doc/invoke.texi (eBPF Options): Document -mcpu=v4 and -mbswap.

gcc/testsuite/ChangeLog

PR target/110786
* gcc.target/bpf/bswap-1.c: Pass -mcpu=v3 to build test.
* gcc.target/bpf/bswap-2.c: New test.
---
 gcc/config/bpf/bpf-opts.h  |  1 +
 gcc/config/bpf/bpf.cc  |  3 +++
 gcc/config/bpf/bpf.md  | 17 +++--
 gcc/config/bpf/bpf.opt |  9 -
 gcc/doc/invoke.texi| 11 ++-
 gcc/testsuite/gcc.target/bpf/bswap-1.c |  2 +-
 gcc/testsuite/gcc.target/bpf/bswap-2.c | 23 +++
 7 files changed, 57 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/bswap-2.c

diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
index 92db01ec4d5..e0be591b479 100644
--- a/gcc/config/bpf/bpf-opts.h
+++ b/gcc/config/bpf/bpf-opts.h
@@ -58,6 +58,7 @@ enum bpf_isa_version
   ISA_V1,
   ISA_V2,
   ISA_V3,
+  ISA_V4
 };
 
 enum bpf_asm_dialect
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 1d3936871d6..6bc715429dc 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -253,6 +253,9 @@ bpf_option_override (void)
   if (bpf_has_jmp32 == -1)
 bpf_has_jmp32 = (bpf_isa >= ISA_V3);
 
+  if (bpf_has_bswap == -1)
+bpf_has_bswap = (bpf_isa >= ISA_V4);
+
   /* Disable -fstack-protector as it is not supported in BPF.  */
   if (flag_stack_protect)
 {
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 80220f2ef37..81e2268c400 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -60,7 +60,7 @@ (define_constants
 ;; Instruction classes.
 ;; alu 64-bit arithmetic.
 ;; alu32   32-bit arithmetic.
-;; end endianness conversion instructions.
+;; end endianness conversion or byte swap instructions.
 ;; ld  load instructions.
 ;; lddxload 64-bit immediate instruction.
 ;; ldx generic load instructions.
@@ -354,20 +354,25 @@ (define_insn "lshr3"
   "{rsh\t%0,%2|%w0 >>= %w2}"
   [(set_attr "type" "")])
 
- Endianness conversion
+ Byte swapping
 
 (define_mode_iterator BSM [HI SI DI])
 (define_mode_attr endmode [(HI "16") (SI "32") (DI "64")])
 
 (define_insn "bswap2"
   [(set (match_operand:BSM 0 "register_operand""=r")
-(bswap:BSM (match_operand:BSM 1 "register_operand" " r")))]
+(bswap:BSM (match_operand:BSM 1 "register_operand" " 0")))]
   ""
 {
-  if (TARGET_BIG_ENDIAN)
-return "{endle\t%0, |%0 = le %0}";
+  if (bpf_has_bswap)
+return "{bswap\t%0, |%0 = bswap %1}";
   else
-return "{endbe\t%0, |%0 = be %0}";
+{
+  if (TARGET_BIG_ENDIAN)
+return "{endle\t%0, |%0 = le %1}";
+  else
+return "{endbe\t%0, |%0 = be %1}";
+}
 }
   [(set_attr "type" "end")])
 
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index ff805f9e083..1e4dcc871d7 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -146,8 +146,12 @@ mjmp32
 Target Var(bpf_has_jmp32) Init(-1)
 Enable 32-bit jump instructions.
 
+mbswap
+Target Var(bpf_has_bswap) Init(-1)
+Enable byte swap instructions.
+
 mcpu=
-Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V3)
+Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4)
 
 Enum
 Name(bpf_isa) Type(enum bpf_isa_version)
@@ -161,6 +165,9 @@ Enum(bpf_isa) String(v2) Value(ISA_V2)
 EnumValue
 Enum(bpf_isa) String(v3) Value(ISA_V3)
 
+EnumValue
+Enum(bpf_isa) String(v4) Value(ISA_V4)
+
 masm=
 Target RejectNegative Joined Var(asm_dialect) Enum(asm_dialect) 
Init(ASM_NORMAL)
 Use given assembler dialect.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index efd356e7ef6..a977a34db42 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -24707,10 +24707,14 @@ Enable 32-bit jump instructions. Enabled for CPU v3 
and above.
 @item -malu32
 Enable 32-bit ALU instructions. Enabled for CPU v3 and above.
 
+@opindex mbswap
+@item -mbswap
+Enable byte swap instructions.  Enabled for CPU v4 and above.
+
 @opindex mcpu
 @item -mcpu=@var{version}
 This specifies which version of the eBPF ISA to target. Newer versions
-may not be supported by all kernels. The default is @samp{v3}.
+may not be supported by all kernels. The default is @samp{v4}.
 

Re: [PATCH v4] bpf: fixed template for neg (added second operand)

2023-07-21 Thread Jose E. Marchesi via Gcc-patches


Better with the commit message.
OK.  Thanks.

> This patch fixes define_insn for "neg" to support 2 operands.
> Initial implementation assumed the format "neg %0" while the instruction
> allows both a destination and source operands. The second operand can
> either be a register or an immediate value.
>
> gcc/ChangeLog:
>
>   * config/bpf/bpf.md: fixed template for neg instruction.
> ---
>  gcc/config/bpf/bpf.md | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 329f62f55c33..adf11e151df1 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -139,10 +139,10 @@
>  
>  ;;; Negation
>  (define_insn "neg2"
> -  [(set (match_operand:AM 0 "register_operand" "=r")
> -(neg:AM (match_operand:AM 1 "register_operand" " 0")))]
> +  [(set (match_operand:AM 0 "register_operand" "=r,r")
> +(neg:AM (match_operand:AM 1 "register_operand" " r,I")))]
>""
> -  "neg\t%0"
> +  "neg\t%0,%1"
>[(set_attr "type" "")])
>  
>  ;;; Multiplication


Re: [PATCH v3] bpf: fixed template for neg (added second operand)

2023-07-21 Thread Jose E. Marchesi via Gcc-patches


Hi Cuper.
OK.  Thanks!

> From 7756a4becd1934e55d6d14ac4a9fd6d408a4797b Mon Sep 17 00:00:00 2001
> From: Cupertino Miranda 
> Date: Fri, 21 Jul 2023 17:40:07 +0100
> Subject: [PATCH v3] bpf: fixed template for neg (added second operand)
>
> gcc/ChangeLog:
>
>   * config/bpf/bpf.md: fixed template for neg instruction.
> ---
>  gcc/config/bpf/bpf.md | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index 329f62f55c33..adf11e151df1 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -139,10 +139,10 @@
>  
>  ;;; Negation
>  (define_insn "neg2"
> -  [(set (match_operand:AM 0 "register_operand" "=r")
> -(neg:AM (match_operand:AM 1 "register_operand" " 0")))]
> +  [(set (match_operand:AM 0 "register_operand" "=r,r")
> +(neg:AM (match_operand:AM 1 "register_operand" " r,I")))]
>""
> -  "neg\t%0"
> +  "neg\t%0,%1"
>[(set_attr "type" "")])
>  
>  ;;; Multiplication


Re: [PATCH v3] bpf: pseudo-c assembly dialect support

2023-07-21 Thread Jose E. Marchesi via Gcc-patches


> Thanks for the suggestions/fixes in changelog.
> Inlined new patch.
>
> Cupertino
>
>>> gcc/ChangeLog:
>>>
>>> * config/bpf/bpf.opt: Added option -masm=.
>>> * config/bpf/bpf-opts.h: Likewize.
>>> * config/bpf/bpf.cc: Changed it to conform with new pseudoc
>>>   dialect support.
>>> * config/bpf/bpf.h: Likewise.
>>> * config/bpf/bpf.md: Added pseudo-c templates.
>>> * doc/invoke.texi: (-masm=DIALECT) New eBPF option item.
>>
>> I think the ChangeLog could be made more useful, and the syntax of the
>> last entry is not entirely right.  I suggest something like:
>>
>>  * config/bpf/bpf.opt: Added option -masm=.
>>  * config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type.
>>  * config/bpf/bpf.cc (bpf_print_register): New function.
>>  (bpf_print_register): Support pseudo-c syntax for registers.
>>  (bpf_print_operand_address): Likewise.
>>  * config/bpf/bpf.h (ASM_SPEC): handle -msasm.
>>  (ASSEMBLER_DIALECT): Define.
>>  * config/bpf/bpf.md: Added pseudo-c templates.
>>  * doc/invoke.texi (-masm=DIALECT): New eBPF option item.
>>
>> Please make sure to run the contrib/gcc-changelog/git_check-commit.py
>> script.
>>
>
> From 6ebe3229a59b32ffb2ed24b3a2cf8c360a807c31 Mon Sep 17 00:00:00 2001
> From: Cupertino Miranda 
> Date: Mon, 17 Jul 2023 17:42:42 +0100
> Subject: [PATCH v3] bpf: pseudo-c assembly dialect support
>
> New pseudo-c BPF assembly dialect already supported by clang and widely
> used in the linux kernel.
>
> gcc/ChangeLog:
>
>   * config/bpf/bpf.opt: Added option -masm=.
>   * config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type.
>   * config/bpf/bpf.cc (bpf_print_register): New function.
>   (bpf_print_register): Support pseudo-c syntax for registers.
>   (bpf_print_operand_address): Likewise.
>   * config/bpf/bpf.h (ASM_SPEC): handle -msasm.
>   (ASSEMBLER_DIALECT): Define.
>   * config/bpf/bpf.md: Added pseudo-c templates.
>   * doc/invoke.texi (-masm=): New eBPF option item.
> ---
>  gcc/config/bpf/bpf-opts.h |  6 +++
>  gcc/config/bpf/bpf.cc | 46 ---
>  gcc/config/bpf/bpf.h  |  5 +-
>  gcc/config/bpf/bpf.md | 97 ---
>  gcc/config/bpf/bpf.opt| 14 ++
>  gcc/doc/invoke.texi   | 21 -
>  6 files changed, 133 insertions(+), 56 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
> index 8282351cf045..92db01ec4d54 100644
> --- a/gcc/config/bpf/bpf-opts.h
> +++ b/gcc/config/bpf/bpf-opts.h
> @@ -60,4 +60,10 @@ enum bpf_isa_version
>ISA_V3,
>  };
>  
> +enum bpf_asm_dialect
> +{
> +  ASM_NORMAL,
> +  ASM_PSEUDOC
> +};
> +
>  #endif /* ! BPF_OPTS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index e0324e1e0e08..1d3936871d60 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -873,16 +873,47 @@ bpf_output_call (rtx target)
>return "";
>  }
>  
> +/* Print register name according to assembly dialect.
> +   In normal syntax registers are printed like %rN where N is the
> +   register number.
> +   In pseudoc syntax, the register names do not feature a '%' prefix.
> +   Additionally, the code 'w' denotes that the register should be printed
> +   as wN instead of rN, where N is the register number, but only when the
> +   value stored in the operand OP is 32-bit wide.  */
> +static void
> +bpf_print_register (FILE *file, rtx op, int code)
> +{
> +  if(asm_dialect == ASM_NORMAL)
> +fprintf (file, "%s", reg_names[REGNO (op)]);
> +  else
> +{
> +  if (code == 'w' && GET_MODE (op) == SImode)
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "w10");
> +   else
> + fprintf (file, "w%s", reg_names[REGNO (op)]+2);
> + }
> +  else
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "r10");
> +   else
> + fprintf (file, "%s", reg_names[REGNO (op)]+1);
> + }
> +}
> +}
> +
>  /* Print an instruction operand.  This function is called in the macro
> PRINT_OPERAND defined in bpf.h */
>  
>  void
> -bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED)
> +bpf_print_operand (FILE *file, rtx op, int code)
>  {
>switch (GET_CODE (op))
>  {
>  case REG:
> -  fprintf (file, "%s", reg_names[REGNO (op)]);
> +  bpf_print_register (file, op, code);
>break;
>  case MEM:
>output_address (GET_MODE (op), XEXP (op, 0));
> @@ -936,7 +967,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
>switch (GET_CODE (addr))
>  {
>  case REG:
> -  fprintf (file, "[%s+0]", reg_names[REGNO (addr)]);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> +  bpf_print_register (file, addr, 0);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
>break;
>  case PLUS:
>{
> @@ -945,9 +978,11 @@ bpf_print_operand_address (FILE *file, rtx addr)
>  
>   if (GET_CODE 

Re: [PATCH v2] bpf: pseudo-c assembly dialect support

2023-07-21 Thread Jose E. Marchesi via Gcc-patches


> gcc/ChangeLog:
>
>   * config/bpf/bpf.opt: Added option -masm=.
>   * config/bpf/bpf-opts.h: Likewize.
>   * config/bpf/bpf.cc: Changed it to conform with new pseudoc
> dialect support.
>   * config/bpf/bpf.h: Likewise.
>   * config/bpf/bpf.md: Added pseudo-c templates.
>   * doc/invoke.texi: (-masm=DIALECT) New eBPF option item.

I think the ChangeLog could be made more useful, and the syntax of the
last entry is not entirely right.  I suggest something like:

* config/bpf/bpf.opt: Added option -masm=.
* config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type.
* config/bpf/bpf.cc (bpf_print_register): New function.
(bpf_print_register): Support pseudo-c syntax for registers.
(bpf_print_operand_address): Likewise.
* config/bpf/bpf.h (ASM_SPEC): handle -msasm.
(ASSEMBLER_DIALECT): Define.
* config/bpf/bpf.md: Added pseudo-c templates.
* doc/invoke.texi (-masm=DIALECT): New eBPF option item.

Please make sure to run the contrib/gcc-changelog/git_check-commit.py
script.

> ---
>  gcc/config/bpf/bpf-opts.h |  6 +++
>  gcc/config/bpf/bpf.cc | 46 ---
>  gcc/config/bpf/bpf.h  |  5 +-
>  gcc/config/bpf/bpf.md | 97 ---
>  gcc/config/bpf/bpf.opt| 14 ++
>  gcc/doc/invoke.texi   | 21 -
>  6 files changed, 133 insertions(+), 56 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
> index 8282351cf045..92db01ec4d54 100644
> --- a/gcc/config/bpf/bpf-opts.h
> +++ b/gcc/config/bpf/bpf-opts.h
> @@ -60,4 +60,10 @@ enum bpf_isa_version
>ISA_V3,
>  };
>  
> +enum bpf_asm_dialect
> +{
> +  ASM_NORMAL,
> +  ASM_PSEUDOC
> +};
> +
>  #endif /* ! BPF_OPTS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index e0324e1e0e08..1d3936871d60 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -873,16 +873,47 @@ bpf_output_call (rtx target)
>return "";
>  }
>  
> +/* Print register name according to assembly dialect.
> +   In normal syntax registers are printed like %rN where N is the
> +   register number.
> +   In pseudoc syntax, the register names do not feature a '%' prefix.
> +   Additionally, the code 'w' denotes that the register should be printed
> +   as wN instead of rN, where N is the register number, but only when the
> +   value stored in the operand OP is 32-bit wide.  */
> +static void
> +bpf_print_register (FILE *file, rtx op, int code)
> +{
> +  if(asm_dialect == ASM_NORMAL)
> +fprintf (file, "%s", reg_names[REGNO (op)]);
> +  else
> +{
> +  if (code == 'w' && GET_MODE (op) == SImode)
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "w10");
> +   else
> + fprintf (file, "w%s", reg_names[REGNO (op)]+2);
> + }
> +  else
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "r10");
> +   else
> + fprintf (file, "%s", reg_names[REGNO (op)]+1);
> + }
> +}
> +}
> +
>  /* Print an instruction operand.  This function is called in the macro
> PRINT_OPERAND defined in bpf.h */
>  
>  void
> -bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED)
> +bpf_print_operand (FILE *file, rtx op, int code)
>  {
>switch (GET_CODE (op))
>  {
>  case REG:
> -  fprintf (file, "%s", reg_names[REGNO (op)]);
> +  bpf_print_register (file, op, code);
>break;
>  case MEM:
>output_address (GET_MODE (op), XEXP (op, 0));
> @@ -936,7 +967,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
>switch (GET_CODE (addr))
>  {
>  case REG:
> -  fprintf (file, "[%s+0]", reg_names[REGNO (addr)]);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> +  bpf_print_register (file, addr, 0);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
>break;
>  case PLUS:
>{
> @@ -945,9 +978,11 @@ bpf_print_operand_address (FILE *file, rtx addr)
>  
>   if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT)
> {
> - fprintf (file, "[%s+", reg_names[REGNO (op0)]);
> + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> + bpf_print_register (file, op0, 0);
> + fprintf (file, "+");
>   output_addr_const (file, op1);
> - fputs ("]", file);
> + fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")");
> }
>   else
> fatal_insn ("invalid address in operand", addr);
> @@ -1816,7 +1851,6 @@ handle_attr_preserve (function *fn)
>  }
>  }
>  
> -
>  /* This pass finds accesses to structures marked with the BPF target 
> attribute
> __attribute__((preserve_access_index)). For every such access, a CO-RE
> relocation record is generated, to be output in the .BTF.ext section.  */
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index 344aca02d1bb..9561bf59b800 100644
> --- a/gcc/config/bpf/bpf.h

Re: [PATCH] bpf: pseudo-c assembly dialect support

2023-07-21 Thread Jose E. Marchesi via Gcc-patches


Hello Cuper.

Thanks for the patch.

We will need an update for the "eBPF Options" section in the GCC manual,
documenting -masm=@var{dialect} and the supported values.  Can you
please add it and re-submit?


> Hi everyone,
>
> Looking forward to all your reviews.
>
> Best regards,
> Cupertino
>
> New pseudo-c BPF assembly dialect already supported by clang and widely
> used in the linux kernel.
>
> gcc/ChangeLog:
>
>   * config/bpf/bpf.opt: Added option -masm=.
>   * config/bpf/bpf-opts.h: Likewize.
>   * config/bpf/bpf.cc: Changed it to conform with new pseudoc
> dialect support.
>   * config/bpf/bpf.h: Likewise.
>   * config/bpf/bpf.md: Added pseudo-c templates.
> ---
>  gcc/config/bpf/bpf-opts.h |  6 +++
>  gcc/config/bpf/bpf.cc | 46 ---
>  gcc/config/bpf/bpf.h  |  5 +-
>  gcc/config/bpf/bpf.md | 97 ---
>  gcc/config/bpf/bpf.opt| 14 ++
>  5 files changed, 114 insertions(+), 54 deletions(-)
>
> diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
> index 8282351cf045..92db01ec4d54 100644
> --- a/gcc/config/bpf/bpf-opts.h
> +++ b/gcc/config/bpf/bpf-opts.h
> @@ -60,4 +60,10 @@ enum bpf_isa_version
>ISA_V3,
>  };
>  
> +enum bpf_asm_dialect
> +{
> +  ASM_NORMAL,
> +  ASM_PSEUDOC
> +};
> +
>  #endif /* ! BPF_OPTS_H */
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index e0324e1e0e08..1d3936871d60 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -873,16 +873,47 @@ bpf_output_call (rtx target)
>return "";
>  }
>  
> +/* Print register name according to assembly dialect.
> +   In normal syntax registers are printed like %rN where N is the
> +   register number.
> +   In pseudoc syntax, the register names do not feature a '%' prefix.
> +   Additionally, the code 'w' denotes that the register should be printed
> +   as wN instead of rN, where N is the register number, but only when the
> +   value stored in the operand OP is 32-bit wide.  */
> +static void
> +bpf_print_register (FILE *file, rtx op, int code)
> +{
> +  if(asm_dialect == ASM_NORMAL)
> +fprintf (file, "%s", reg_names[REGNO (op)]);
> +  else
> +{
> +  if (code == 'w' && GET_MODE (op) == SImode)
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "w10");
> +   else
> + fprintf (file, "w%s", reg_names[REGNO (op)]+2);
> + }
> +  else
> + {
> +   if (REGNO (op) == BPF_FP)
> + fprintf (file, "r10");
> +   else
> + fprintf (file, "%s", reg_names[REGNO (op)]+1);
> + }
> +}
> +}
> +
>  /* Print an instruction operand.  This function is called in the macro
> PRINT_OPERAND defined in bpf.h */
>  
>  void
> -bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED)
> +bpf_print_operand (FILE *file, rtx op, int code)
>  {
>switch (GET_CODE (op))
>  {
>  case REG:
> -  fprintf (file, "%s", reg_names[REGNO (op)]);
> +  bpf_print_register (file, op, code);
>break;
>  case MEM:
>output_address (GET_MODE (op), XEXP (op, 0));
> @@ -936,7 +967,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
>switch (GET_CODE (addr))
>  {
>  case REG:
> -  fprintf (file, "[%s+0]", reg_names[REGNO (addr)]);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> +  bpf_print_register (file, addr, 0);
> +  fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
>break;
>  case PLUS:
>{
> @@ -945,9 +978,11 @@ bpf_print_operand_address (FILE *file, rtx addr)
>  
>   if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT)
> {
> - fprintf (file, "[%s+", reg_names[REGNO (op0)]);
> + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
> + bpf_print_register (file, op0, 0);
> + fprintf (file, "+");
>   output_addr_const (file, op1);
> - fputs ("]", file);
> + fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")");
> }
>   else
> fatal_insn ("invalid address in operand", addr);
> @@ -1816,7 +1851,6 @@ handle_attr_preserve (function *fn)
>  }
>  }
>  
> -
>  /* This pass finds accesses to structures marked with the BPF target 
> attribute
> __attribute__((preserve_access_index)). For every such access, a CO-RE
> relocation record is generated, to be output in the .BTF.ext section.  */
> diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
> index 344aca02d1bb..9561bf59b800 100644
> --- a/gcc/config/bpf/bpf.h
> +++ b/gcc/config/bpf/bpf.h
> @@ -22,7 +22,8 @@
>  
>  / Controlling the Compilation Driver.  */
>  
> -#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf}"
> +#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf} " \
> +  "%{masm=pseudoc:-mdialect=pseudoc}"
>  #define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}"
>  #define LIB_SPEC ""
>  #define STARTFILE_SPEC ""
> @@ -503,4 

[COMMITTED] bpf: enable instruction scheduling

2023-07-14 Thread Jose E. Marchesi via Gcc-patches


commit 53d12ecd624ec901d8449cfa1917f6f90e910927 (HEAD -> master, origin/master, 
origin/HEAD)
Author: Jose E. Marchesi 
Date:   Fri Jul 14 13:54:06 2023 +0200

bpf: enable instruction scheduling

This patch adds a dummy FSM to bpf.md in order to get INSN_SCHEDULING
defined.  If the later is not defined, the `combine' pass generates
paradoxical subregs of mems, which seems to then be mishandled by LRA,
resulting in invalid code.

Tested in bpf-unknown-none.

gcc/ChangeLog:

2023-07-14  Jose E. Marchesi  

PR target/110657
* config/bpf/bpf.md: Enable instruction scheduling.

diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index f6be0a21234..329f62f55c3 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -20,6 +20,17 @@
 (include "predicates.md")
 (include "constraints.md")
 
+ Instruction Scheduler FSM
+
+;; This is just to get INSN_SCHEDULING defined, so that combine does
+;; not make paradoxical subregs of memory.  These subregs seems to
+;; confuse LRA that ends generating wrong instructions.
+
+(define_automaton "frob")
+(define_cpu_unit "frob_unit" "frob")
+(define_insn_reservation "frobnicator" 814
+  (const_int 0) "frob_unit")
+
  Unspecs
 
 (define_c_enum "unspec" [


Re: [PATCH 0/9] Add btf_decl_tag C attribute

2023-07-12 Thread Jose E. Marchesi via Gcc-patches


> On Wed, Jul 12, 2023 at 2:44 PM Jose E. Marchesi
>  wrote:
>>
>>
>> [Added Eduard Zingerman in CC, who is implementing this same feature in
>>  clang/llvm and also the consumer component in the kernel (pahole).]
>>
>> Hi Richard.
>>
>> > On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
>> >  wrote:
>> >>
>> >> Hello,
>> >>
>> >> This series adds support for a new attribute, "btf_decl_tag" in GCC.
>> >> The same attribute is already supported in clang, and is used by various
>> >> components of the BPF ecosystem.
>> >>
>> >> The purpose of the attribute is to allow to associate (to "tag")
>> >> declarations with arbitrary string annotations, which are emitted into
>> >> debugging information (DWARF and/or BTF) to facilitate post-compilation
>> >> analysis (the motivating use case being the Linux kernel BPF verifier).
>> >> Multiple tags are allowed on the same declaration.
>> >>
>> >> These strings are not interpreted by the compiler, and the attribute
>> >> itself has no effect on generated code, other than to produce additional
>> >> DWARF DIEs and/or BTF records conveying the annotations.
>> >>
>> >> This entails:
>> >>
>> >> - A new C-language-level attribute which allows to associate (to "tag")
>> >>   particular declarations with arbitrary strings.
>> >>
>> >> - The conveyance of that information in DWARF in the form of a new DIE,
>> >>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>> >>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>> >>   the same purpose. These DIEs are already supported by BPF tooling,
>> >>   such as pahole.
>> >>
>> >> - The conveyance of that information in BTF debug info in the form of
>> >>   BTF_KIND_DECL_TAG records. These records are already supported by
>> >>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>> >>   eBPF verifier.
>> >>
>> >>
>> >> Background
>> >> ==
>> >>
>> >> The purpose of these tags is to convey additional semantic information
>> >> to post-compilation consumers, in particular the Linux kernel eBPF
>> >> verifier. The verifier can make use of that information while analyzing
>> >> a BPF program to aid in determining whether to allow or reject the
>> >> program to be run. More background on these tags can be found in the
>> >> early support for them in the kernel here [1] and [2].
>> >>
>> >> The "btf_decl_tag" attribute is half the story; the other half is a
>> >> sibling attribute "btf_type_tag" which serves the same purpose but
>> >> applies to types. Support for btf_type_tag will come in a separate
>> >> patch series, since it is impaced by GCC bug 110439 which needs to be
>> >> addressed first.
>> >>
>> >> I submitted an initial version of this work (including btf_type_tag)
>> >> last spring [3], however at the time there were some open questions
>> >> about the behavior of the btf_type_tag attribute and issues with its
>> >> implementation. Since then we have clarified these details and agreed
>> >> to solutions with the BPF community and LLVM BPF folks.
>> >>
>> >> The main motivation for emitting the tags in DWARF is that the Linux
>> >> kernel generates its BTF information via pahole, using DWARF as a source:
>> >>
>> >> ++  BTF  BTF   +--+
>> >> | pahole |---> vmlinux.btf --->| verifier |
>> >> ++ +--+
>> >> ^^
>> >> ||
>> >>   DWARF |BTF |
>> >> ||
>> >>   vmlinux  +-+
>> >>   module1.ko   | BPF program |
>> >>   module2.ko   +-+
>> >> ...
>> >>
>> >> This is because:
>> >>
>> >> a)  pahole adds additional kernel-specific information into the
>> >>

Re: [PATCH 0/9] Add btf_decl_tag C attribute

2023-07-12 Thread Jose E. Marchesi via Gcc-patches


[Added Eduard Zingerman in CC, who is implementing this same feature in
 clang/llvm and also the consumer component in the kernel (pahole).]

Hi Richard.

> On Tue, Jul 11, 2023 at 11:58 PM David Faust via Gcc-patches
>  wrote:
>>
>> Hello,
>>
>> This series adds support for a new attribute, "btf_decl_tag" in GCC.
>> The same attribute is already supported in clang, and is used by various
>> components of the BPF ecosystem.
>>
>> The purpose of the attribute is to allow to associate (to "tag")
>> declarations with arbitrary string annotations, which are emitted into
>> debugging information (DWARF and/or BTF) to facilitate post-compilation
>> analysis (the motivating use case being the Linux kernel BPF verifier).
>> Multiple tags are allowed on the same declaration.
>>
>> These strings are not interpreted by the compiler, and the attribute
>> itself has no effect on generated code, other than to produce additional
>> DWARF DIEs and/or BTF records conveying the annotations.
>>
>> This entails:
>>
>> - A new C-language-level attribute which allows to associate (to "tag")
>>   particular declarations with arbitrary strings.
>>
>> - The conveyance of that information in DWARF in the form of a new DIE,
>>   DW_TAG_GNU_annotation, with tag number (0x6000) and format matching
>>   that of the DW_TAG_LLVM_annotation extension supported in LLVM for
>>   the same purpose. These DIEs are already supported by BPF tooling,
>>   such as pahole.
>>
>> - The conveyance of that information in BTF debug info in the form of
>>   BTF_KIND_DECL_TAG records. These records are already supported by
>>   LLVM and other tools in the eBPF ecosystem, such as the Linux kernel
>>   eBPF verifier.
>>
>>
>> Background
>> ==
>>
>> The purpose of these tags is to convey additional semantic information
>> to post-compilation consumers, in particular the Linux kernel eBPF
>> verifier. The verifier can make use of that information while analyzing
>> a BPF program to aid in determining whether to allow or reject the
>> program to be run. More background on these tags can be found in the
>> early support for them in the kernel here [1] and [2].
>>
>> The "btf_decl_tag" attribute is half the story; the other half is a
>> sibling attribute "btf_type_tag" which serves the same purpose but
>> applies to types. Support for btf_type_tag will come in a separate
>> patch series, since it is impaced by GCC bug 110439 which needs to be
>> addressed first.
>>
>> I submitted an initial version of this work (including btf_type_tag)
>> last spring [3], however at the time there were some open questions
>> about the behavior of the btf_type_tag attribute and issues with its
>> implementation. Since then we have clarified these details and agreed
>> to solutions with the BPF community and LLVM BPF folks.
>>
>> The main motivation for emitting the tags in DWARF is that the Linux
>> kernel generates its BTF information via pahole, using DWARF as a source:
>>
>> ++  BTF  BTF   +--+
>> | pahole |---> vmlinux.btf --->| verifier |
>> ++ +--+
>> ^^
>> ||
>>   DWARF |BTF |
>> ||
>>   vmlinux  +-+
>>   module1.ko   | BPF program |
>>   module2.ko   +-+
>> ...
>>
>> This is because:
>>
>> a)  pahole adds additional kernel-specific information into the
>> produced BTF based on additional analysis of kernel objects.
>>
>> b)  Unlike GCC, LLVM will only generate BTF for BPF programs.
>>
>> b)  GCC can generate BTF for whatever target with -gbtf, but there is no
>> support for linking/deduplicating BTF in the linker.
>>
>> In the scenario above, the verifier needs access to the pointer tags of
>> both the kernel types/declarations (conveyed in the DWARF and translated
>> to BTF by pahole) and those of the BPF program (available directly in BTF).
>>
>>
>> DWARF Representation
>> 
>>
>> As noted above, btf_decl_tag is represented in DWARF via a new DIE
>> DW_TAG_GNU_annotation, with identical format to the LLVM DWARF
>> extension DW_TAG_LLVM_annotation serving the same purpose. The DIE has
>> the following format:
>>
>>   DW_TAG_GNU_annotation (0x6000)
>> DW_AT_name: "btf_decl_tag"
>> DW_AT_const_value: 
>>
>> These DIEs are placed in the DWARF tree as children of the DIE for the
>> appropriate declaration, and one such DIE is created for each occurrence
>> of the btf_decl_tag attribute on a declaration.
>>
>> For example:
>>
>>   const int * c __attribute__((btf_decl_tag ("__c"), btf_decl_tag 
>> ("devicemem")));
>>
>> This declaration produces the following DWARF:
>>
>>  <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
>> <1f>   DW_AT_name  

Re: [committed] Docs: Fix formatting issues in BPF built-ins documentation

2023-03-20 Thread Jose E. Marchesi via Gcc-patches


Hi Sandra.

> This section of the GCC manual had some issues with lines in the
> example overflowing into the right margin of the PDF-format document,
> but as I looked at it more closely I also saw that it was full of
> missing or incorrect Texinfo markup, too.  I've cleaned it up thusly.

Thank you so much for fixing these issues in the manual.
Very much appreciated :)

>
> -Sandra
>
> commit 7ffbc74c8c202a16a5e987134f03c2359c531f0e
> Author: Sandra Loosemore 
> Date:   Thu Mar 16 21:07:18 2023 +
>
> Docs: Fix formatting issues in BPF built-ins documentation.
> 
> gcc/ChangeLog:
> * doc/extend.texi (BPF Built-in Functions): Fix numerous markup
> issues.  Add more line breaks to example so it doesn't overflow
> the margins.
>
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 39d45df8d89..8ecd9611201 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -15715,23 +15715,23 @@ void __builtin_bfin_ssync (void);
>  
>  The following built-in functions are available for eBPF targets.
>  
> -@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_byte 
> (unsigned long long @var{offset})
> +@deftypefn {Built-in Function} {unsigned long long} __builtin_bpf_load_byte 
> (unsigned long long @var{offset})
>  Load a byte from the @code{struct sk_buff} packet data pointed by the 
> register @code{%r6} and return it.
>  @end deftypefn
>  
> -@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_half 
> (unsigned long long @var{offset})
> -Load 16-bits from the @code{struct sk_buff} packet data pointed by the 
> register @code{%r6} and return it.
> +@deftypefn {Built-in Function} {unsigned long long} __builtin_bpf_load_half 
> (unsigned long long @var{offset})
> +Load 16 bits from the @code{struct sk_buff} packet data pointed by the 
> register @code{%r6} and return it.
>  @end deftypefn
>  
> -@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_word 
> (unsigned long long @var{offset})
> -Load 32-bits from the @code{struct sk_buff} packet data pointed by the 
> register @code{%r6} and return it.
> +@deftypefn {Built-in Function} {unsigned long long} __builtin_bpf_load_word 
> (unsigned long long @var{offset})
> +Load 32 bits from the @code{struct sk_buff} packet data pointed by the 
> register @code{%r6} and return it.
>  @end deftypefn
>  
> -@deftypefn {Built-in Function} void * __builtin_preserve_access_index 
> (@var{expr})
> +@deftypefn {Built-in Function} {void *} __builtin_preserve_access_index 
> (@var{expr})
>  BPF Compile Once-Run Everywhere (CO-RE) support. Instruct GCC to generate 
> CO-RE relocation records for any accesses to aggregate data structures 
> (struct, union, array types) in @var{expr}. This builtin is otherwise 
> transparent, the return value is whatever @var{expr} evaluates to. It is also 
> overloaded: @var{expr} may be of any type (not necessarily a pointer), the 
> return type is the same. Has no effect if @code{-mco-re} is not in effect 
> (either specified or implied).
>  @end deftypefn
>  
> -@deftypefn {Built-in Function} unsigned int __builtin_preserve_field_info 
> (@var{expr}, unsigned int @var{kind})
> +@deftypefn {Built-in Function} {unsigned int} __builtin_preserve_field_info 
> (@var{expr}, unsigned int @var{kind})
>  BPF Compile Once-Run Everywhere (CO-RE) support. This builtin is used to
>  extract information to aid in struct/union relocations.  @var{expr} is
>  an access to a field of a struct or union. Depending on @var{kind}, different
> @@ -15739,15 +15739,15 @@ information is returned to the program. A CO-RE 
> relocation for the access in
>  @var{expr} with kind @var{kind} is recorded if @code{-mco-re} is in effect.
>  
>  The following values are supported for @var{kind}:
> -@table @var
> +@table @code
>  @item FIELD_BYTE_OFFSET = 0
>  The returned value is the offset, in bytes, of the field from the
> -beginning of the containing structure. For bitfields, the byte offset
> +beginning of the containing structure. For bit-fields, this is the byte 
> offset
>  of the containing word.
>  
>  @item FIELD_BYTE_SIZE = 1
> -The returned value is the size, in bytes, of the field. For bitfields,
> -the size in bytes of the containing word.
> +The returned value is the size, in bytes, of the field. For bit-fields,
> +this is the size in bytes of the containing word.
>  
>  @item FIELD_EXISTENCE = 2
>  The returned value is 1 if the field exists, 0 otherwise. Always 1 at
> @@ -15759,25 +15759,26 @@ The returned value is 1 if the field is signed, 0 
> otherwise.
>  @item FIELD_LSHIFT_U64 = 4
>  @itemx FIELD_RSHIFT_U64 = 5
>  The returned value is the number of bits of left- or right-shifting
> -respectively needed in order to recover the original value of the field,
> -after it has been loaded by a read of FIELD_BYTE_SIZE bytes into an
> -unsigned 64-bit value. Primarily useful for reading bitfield values
> -from structures which may change between 

Re: [patch] bpf: Fix double whitespace warning

2023-02-15 Thread Jose E. Marchesi via Gcc-patches


> Hi!
>
> Since a recent commit, the BPF target produces a new warning due to
> two consecutive non-quoted spaces in a message. This'll fix it:
>
> gcc/
>   * config/bpf/bpf.cc (bpf_option_override): Fix doubled space.
>
>
> Ok?

OK.  Thanks for the patch.

(Sorry I didn't fix this when you first reported it.  My TODO list is
long atm :/)

> MfG, JBG
>
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index b268801d00c..d8693f8cfbe 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -258,7 +258,7 @@ bpf_option_override (void)
>  {
>inform (input_location,
>"%<-fstack-protector%> does not work "
> -  " on this architecture");
> +   "on this architecture");
>flag_stack_protect = 0;
>  }
>  }


Re: [PATCH] bpf: fix memory constraint of ldx/stx instructions [PR108790]

2023-02-14 Thread Jose E. Marchesi via Gcc-patches


Hi David.

> In some cases where the target memory address for an ldx or stx
> instruction could be reduced to a constant, GCC could emit a malformed
> instruction like:
>
> ldxdw %r0,0
>
> Rather than the expected form:
>
> ldxdw %rX, [%rY + OFFSET]
>
> This is due to the constraint allowing a const_int operand, which the
> output templates do not handle.
>
> Fix it by introducing a new memory constraint for the appropriate
> operands of these instructions, which is identical to 'm' except that
> it does not accept const_int.
>
> Tested with bpf-unknown-none, no known regressions.
> OK?

OK.  Thanks for the patch.

> Thanks.
>
> gcc/
>
>   PR target/108790
>   * config/bpf/constraints.md (q): New memory constraint.
>   * config/bpf/bpf.md (zero_extendhidi2): Use it here.
>   (zero_extendqidi2): Likewise.
>   (zero_extendsidi2): Likewise.
>   (*mov): Likewise.
>
> gcc/testsuite/
>
>   PR target/108790
>   * gcc.target/bpf/ldxdw.c: New test.
> ---
>  gcc/config/bpf/bpf.md| 10 +-
>  gcc/config/bpf/constraints.md| 11 +++
>  gcc/testsuite/gcc.target/bpf/ldxdw.c | 12 
>  3 files changed, 28 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/bpf/ldxdw.c
>
> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
> index d9af98384ef..f6be0a21234 100644
> --- a/gcc/config/bpf/bpf.md
> +++ b/gcc/config/bpf/bpf.md
> @@ -242,7 +242,7 @@ (define_insn "xor3"
>  
>  (define_insn "zero_extendhidi2"
>[(set (match_operand:DI 0 "register_operand" "=r,r,r")
> - (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,m")))]
> + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,q")))]
>""
>"@
> and\t%0,0x
> @@ -252,7 +252,7 @@ (define_insn "zero_extendhidi2"
>  
>  (define_insn "zero_extendqidi2"
>[(set (match_operand:DI 0 "register_operand" "=r,r,r")
> - (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,m")))]
> + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,q")))]
>""
>"@
> and\t%0,0xff
> @@ -263,7 +263,7 @@ (define_insn "zero_extendqidi2"
>  (define_insn "zero_extendsidi2"
>[(set (match_operand:DI 0 "register_operand" "=r,r")
>   (zero_extend:DI
> -   (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
> +   (match_operand:SI 1 "nonimmediate_operand" "r,q")))]
>""
>"@
> * return bpf_has_alu32 ? \"mov32\t%0,%1\" : 
> \"mov\t%0,%1\;and\t%0,0x\";
> @@ -302,8 +302,8 @@ (define_expand "mov"
>  }")
>  
>  (define_insn "*mov"
> -  [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,m,m")
> -(match_operand:MM 1 "mov_src_operand"  " m,rI,B,r,I"))]
> +  [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,q,q")
> +(match_operand:MM 1 "mov_src_operand"  " q,rI,B,r,I"))]
>""
>"@
> ldx\t%0,%1
> diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md
> index c8a65cfcddb..33f9177b8eb 100644
> --- a/gcc/config/bpf/constraints.md
> +++ b/gcc/config/bpf/constraints.md
> @@ -29,3 +29,14 @@ (define_constraint "B"
>  (define_constraint "S"
>"A constant call address."
>(match_code "const,symbol_ref,label_ref,const_int"))
> +
> +;;
> +;; Memory constraints.
> +;;
> +
> +; Just like 'm' but disallows const_int.
> +; Used for ldx[b,h,w,dw] and stx[b,h,w,dw] instructions.
> +(define_memory_constraint "q"
> +  "Memory reference which is not a constant integer."
> +  (and (match_code "mem")
> +   (match_test "GET_CODE(XEXP(op, 0)) != CONST_INT")))
> diff --git a/gcc/testsuite/gcc.target/bpf/ldxdw.c 
> b/gcc/testsuite/gcc.target/bpf/ldxdw.c
> new file mode 100644
> index 000..0985ea3e6ac
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/bpf/ldxdw.c
> @@ -0,0 +1,12 @@
> +/* Verify that we do not generate a malformed ldxdw instruction
> +   with a constant instead of register + offset.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +/* { dg-final { scan-assembler-times "ldxdw\t%r.,\\\[%r.+0\\\]" 1 } } */
> +/* { dg-final { scan-assembler-not "ldxdw\t%r.,\[0-9\]+" } } */
> +
> +unsigned long long test () {
> +  return *((unsigned long long *) 0x4000);
> +}


  1   2   3   4   5   >