[PATCH V2] [RFC]Support vectorization for Complex type.

2022-07-17 Thread liuhongt via Gcc-patches
V2 update:
   Handle VMAT_ELEMENTWISE, VMAT_CONTIGUOUS_PERMUTE, VMAT_STRIDED_SLP,
   VMAT_CONTIGUOUS_REVERSE, VMAT_CONTIGUOUS_DOWN for complex type.

I've run SPECspeed@2017 627.cam4_s, there's some vectorization cases,
but no big performance impact(since this patch only handle load/store).

Any comments?

gcc/ChangeLog:

PR tree-optimization/106010
* tree-vect-data-refs.cc (vect_get_data_access_cost):
Pass complex_p to vect_get_num_copies to avoid ICE.
(vect_analyze_data_refs): Support vectorization for Complex
type with vector scalar types.
(vect_permute_load_chain): Handle Complex type.
* tree-vect-loop.cc (vect_determine_vf_for_stmt_1): VF should
be half of TYPE_VECTOR_SUBPARTS when complex_p.
* tree-vect-slp.cc (vect_record_max_nunits): nunits should be
half of TYPE_VECTOR_SUBPARTS when complex_p.
(vect_optimize_slp): Support permutation for complex type.
(vect_slp_analyze_node_operations_1): Double nunits in
vect_get_num_vectors to get right SLP_TREE_NUMBER_OF_VEC_STMTS
when complex_p.
(vect_slp_analyze_node_operations): Ditto.
(vect_create_constant_vectors): Support CTOR for complex type.
(vect_transform_slp_perm_load): Support permutation for
complex type.
* tree-vect-stmts.cc (vect_init_vector): Support complex type.
(vect_get_vec_defs_for_operand): Get vector type for
complex type.
(vectorizable_store): Get right ncopies/nunits and
elem_type for complex type vector, also return false when
complex_p and !TYPE_VECTOR_SUBPARTS.is_constant ().
(vect_truncate_gather_scatter_offset): Return false for
complex type.
(vectorizable_load): Ditto.
(vect_get_vector_types_for_stmt): Get vector type for
complex type.
(get_group_load_store_type): Hanlde complex type for
nunits.
(perm_mask_for_reverse): New overload.
(get_negative_load_store_type): Handle complex type,
p_offset should be N - 2 beofre addres of DR.
(vect_check_scalar_mask): Return false for complex type.
* tree-vectorizer.h (STMT_VINFO_COMPLEX_P): New macro.
(vect_get_num_copies): New overload.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr106010-1a.c: New test.
* gcc.target/i386/pr106010-1b.c: New test.
* gcc.target/i386/pr106010-1c.c: New test.
* gcc.target/i386/pr106010-2a.c: New test.
* gcc.target/i386/pr106010-2b.c: New test.
* gcc.target/i386/pr106010-2c.c: New test.
* gcc.target/i386/pr106010-3a.c: New test.
* gcc.target/i386/pr106010-3b.c: New test.
* gcc.target/i386/pr106010-3c.c: New test.
* gcc.target/i386/pr106010-4a.c: New test.
* gcc.target/i386/pr106010-4b.c: New test.
* gcc.target/i386/pr106010-4c.c: New test.
* gcc.target/i386/pr106010-5a.c: New test.
* gcc.target/i386/pr106010-5b.c: New test.
* gcc.target/i386/pr106010-5c.c: New test.
* gcc.target/i386/pr106010-6a.c: New test.
* gcc.target/i386/pr106010-6b.c: New test.
* gcc.target/i386/pr106010-6c.c: New test.
* gcc.target/i386/pr106010-7a.c: New test.
* gcc.target/i386/pr106010-7b.c: New test.
* gcc.target/i386/pr106010-7c.c: New test.
* gcc.target/i386/pr106010-8a.c: New test.
* gcc.target/i386/pr106010-8b.c: New test.
* gcc.target/i386/pr106010-8c.c: New test.
* gcc.target/i386/pr106010-9a.c: New test.
* gcc.target/i386/pr106010-9b.c: New test.
* gcc.target/i386/pr106010-9c.c: New test.
* gcc.target/i386/pr106010-9d.c: New test.
---
 gcc/testsuite/gcc.target/i386/pr106010-1a.c |  58 +
 gcc/testsuite/gcc.target/i386/pr106010-1b.c |  63 ++
 gcc/testsuite/gcc.target/i386/pr106010-1c.c |  41 
 gcc/testsuite/gcc.target/i386/pr106010-2a.c |  82 +++
 gcc/testsuite/gcc.target/i386/pr106010-2b.c |  62 ++
 gcc/testsuite/gcc.target/i386/pr106010-2c.c |  47 
 gcc/testsuite/gcc.target/i386/pr106010-3a.c |  80 +++
 gcc/testsuite/gcc.target/i386/pr106010-3b.c | 126 +++
 gcc/testsuite/gcc.target/i386/pr106010-3c.c |  69 ++
 gcc/testsuite/gcc.target/i386/pr106010-4a.c | 101 +
 gcc/testsuite/gcc.target/i386/pr106010-4b.c |  67 ++
 gcc/testsuite/gcc.target/i386/pr106010-4c.c |  54 +
 gcc/testsuite/gcc.target/i386/pr106010-5a.c | 117 ++
 gcc/testsuite/gcc.target/i386/pr106010-5b.c |  80 +++
 gcc/testsuite/gcc.target/i386/pr106010-5c.c |  62 ++
 gcc/testsuite/gcc.target/i386/pr106010-6a.c | 115 ++
 gcc/testsuite/gcc.target/i386/pr106010-6b.c | 157 +
 gcc/testsuite/gcc.target/i386/pr106010-6c.c |  80 +++
 gcc/testsuite/gcc.target/i386/pr106010-7a.c |  58 +
 gcc/testsuite/gcc.target/i386/pr106010-7b.c |  63 ++
 gcc/testsuite/gcc.target/i386/pr106010-7c.c |  41 
 

[PATCH] Extend 16/32-bit vector bit_op patterns with (m, 0, i)(vertical) alternative.

2022-07-17 Thread liuhongt via Gcc-patches
And split it after reload.

>IMO, the only case it is worth adding is a direct immediate store to
>memory, which HJ recently added.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk?

gcc/ChangeLog:

PR target/106038
* config/i386/mmx.md (3): Extend to AND mem,imm,
and adjust below define_split.
(mmxinsnmode): New mode attribute.
(*mov_imm): Refactor with mmxinsnmode.
* config/i386/predicates.md
(register_or_x86_64_const_vector_operand): New predicate.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr106038-1.c: New test.
---
 gcc/config/i386/mmx.md | 58 +++---
 gcc/config/i386/predicates.md  |  4 ++
 gcc/testsuite/gcc.target/i386/pr106038-1.c | 27 ++
 3 files changed, 60 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr106038-1.c

diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 3294c1e6274..fbcb34d4395 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -86,6 +86,14 @@ (define_mode_attr mmxvecsize
   [(V8QI "b") (V4QI "b") (V2QI "b")
(V4HI "w") (V2HI "w") (V2SI "d") (V1DI "q")])
 
+;; Mapping to same size integral mode.
+(define_mode_attr mmxinsnmode
+  [(V8QI "DI") (V4QI "SI") (V2QI "HI")
+   (V4HI "DI") (V2HI "SI")
+   (V2SI "DI")
+   (V4HF "DI") (V2HF "SI")
+   (V2SF "DI")])
+
 (define_mode_attr mmxdoublemode
   [(V8QI "V8HI") (V4HI "V4SI")])
 
@@ -350,22 +358,7 @@ (define_insn_and_split "*mov_imm"
   HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[1],
mode);
   operands[1] = GEN_INT (val);
-  machine_mode mode;
-  switch (GET_MODE_SIZE (mode))
-{
-case 2:
-  mode = HImode;
-  break;
-case 4:
-  mode = SImode;
-  break;
-case 8:
-  mode = DImode;
-  break;
-default:
-  gcc_unreachable ();
-}
-  operands[0] = lowpart_subreg (mode, operands[0], mode);
+  operands[0] = lowpart_subreg (mode, operands[0], mode);
 })
 
 ;; For TARGET_64BIT we always round up to 8 bytes.
@@ -2975,32 +2968,39 @@ (define_insn "*mmx_3"
(set_attr "mode" "DI,TI,TI,TI")])
 
 (define_insn "3"
-  [(set (match_operand:VI_16_32 0 "register_operand" "=?r,x,x,v")
+  [(set (match_operand:VI_16_32 0 "nonimmediate_operand" "=?r,m,x,x,v")
 (any_logic:VI_16_32
- (match_operand:VI_16_32 1 "register_operand" "%0,0,x,v")
- (match_operand:VI_16_32 2 "register_operand" "r,x,x,v")))
+ (match_operand:VI_16_32 1 "nonimmediate_operand" "%0,0,0,x,v")
+ (match_operand:VI_16_32 2 "register_or_x86_64_const_vector_operand" 
"r,i,x,x,v")))
(clobber (reg:CC FLAGS_REG))]
   ""
   "#"
-  [(set_attr "isa" "*,sse2_noavx,avx,avx512vl")
-   (set_attr "type" "alu,sselog,sselog,sselog")
-   (set_attr "mode" "SI,TI,TI,TI")])
+  [(set_attr "isa" "*,*,sse2_noavx,avx,avx512vl")
+   (set_attr "type" "alu,alu,sselog,sselog,sselog")
+   (set_attr "mode" "SI,SI,TI,TI,TI")])
 
 (define_split
-  [(set (match_operand:VI_16_32 0 "general_reg_operand")
+  [(set (match_operand:VI_16_32 0 "nonimmediate_gr_operand")
 (any_logic:VI_16_32
- (match_operand:VI_16_32 1 "general_reg_operand")
- (match_operand:VI_16_32 2 "general_reg_operand")))
+ (match_operand:VI_16_32 1 "nonimmediate_gr_operand")
+ (match_operand:VI_16_32 2 "register_or_x86_64_const_vector_operand")))
(clobber (reg:CC FLAGS_REG))]
   "reload_completed"
   [(parallel
  [(set (match_dup 0)
-  (any_logic:SI (match_dup 1) (match_dup 2)))
+  (any_logic: (match_dup 1) (match_dup 2)))
   (clobber (reg:CC FLAGS_REG))])]
 {
-  operands[2] = lowpart_subreg (SImode, operands[2], mode);
-  operands[1] = lowpart_subreg (SImode, operands[1], mode);
-  operands[0] = lowpart_subreg (SImode, operands[0], mode);
+  if (GET_CODE (operands[2]) == CONST_VECTOR)
+{
+  HOST_WIDE_INT val = ix86_convert_const_vector_to_integer (operands[2],
+   mode);
+  operands[2] = GEN_INT (val);
+}
+  else
+operands[2] = lowpart_subreg (mode, operands[2], mode);
+  operands[1] = lowpart_subreg (mode, operands[1], mode);
+  operands[0] = lowpart_subreg (mode, operands[0], mode);
 })
 
 (define_split
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index c71c453cceb..5f63a7d52f5 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1205,6 +1205,10 @@ (define_predicate "x86_64_const_vector_operand"
   return trunc_int_for_mode (val, SImode) == val;
 })
 
+(define_predicate "register_or_x86_64_const_vector_operand"
+  (ior (match_operand 0 "register_operand")
+   (match_operand 0 "x86_64_const_vector_operand")))
+
 ;; Return true when OP is nonimmediate or standard SSE constant.
 (define_predicate "nonimmediate_or_sse_const_operand"
   (ior (match_operand 0 

Re: [AVX512 PATCH] Add UNSPEC_MASKOP to kupck instructions in sse.md.

2022-07-17 Thread Hongtao Liu via Gcc-patches
On Sat, Jul 16, 2022 at 10:08 PM Roger Sayle  wrote:
>
>
> This AVX512 specific patch to sse.md is split out from an earlier patch:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596199.html
>
> The new splitters proposed in that patch interfere with AVX512's
> kunpckdq instruction which is defined as identical RTL,
> DW:DI = (HI:SI<<32)|zero_extend(LO:SI).  To distinguish these,
> and avoid AVX512 mask registers accidentally being (ab)used by reload
> to perform SImode scalar shifts, this patch adds the explicit
> (unspec UNSPEC_MASKOP) to the unpack mask operations, which matches
> what sse.md does for the other mask specific (logic) operations.
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-m32}
> with no new failures.  Ok for mainline?
Ok, thanks for handling this.
>
> 2022-07-16  Roger Sayle  
>
> gcc/ChangeLog
> * config/i386/sse.md (kunpckhi): Add UNSPEC_MASKOP unspec.
> (kunpcksi): Likewise, add UNSPEC_MASKOP unspec.
> (kunpckdi): Likewise, add UNSPEC_MASKOP unspec.
> (vec_pack_trunc_qi): Update to specify required UNSPEC_MASKOP
> unspec.
> (vec_pack_trunc_): Likewise.
>
>
> Thanks in advance,
> Roger
> --
>


-- 
BR,
Hongtao


Re: [PATCH] c++: Add __reference_con{struc,ver}ts_from_temporary [PR104477]

2022-07-17 Thread Stephan Bergmann via Gcc-patches

On 7/15/22 22:25, Marek Polacek via Gcc-patches wrote:

Yeah, I guess so.  But I've already pushed the patch.


This commit obviously breaks using libstdc++ with Clang (in -std=c++2b 
mode), which doesn't implement those new builtins.  Something like the 
below would fix that,



diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index b1a1deecf66..a6e028b42ec 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3505,6 +3505,7 @@ template
   template
 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
 
+#if __has_builtin(__reference_constructs_from_temporary) && __has_builtin(__reference_converts_from_temporary)

 #define __cpp_lib_reference_from_temporary 202202L
 
   /// True if _Tp is a reference type, a _Up value can be bound to _Tp in

@@ -3544,6 +3545,7 @@ template
   template
 inline constexpr bool reference_converts_from_temporary_v
   = reference_converts_from_temporary<_Tp, _Up>::value;
+#endif
 #endif // C++23
 
 #if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED

diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 5edca2f3007..7c4b7f7cc6d 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -304,7 +304,9 @@
 #define __cpp_lib_byteswap 202110L
 #define __cpp_lib_constexpr_typeinfo 202106L
 #define __cpp_lib_is_scoped_enum 202011L
+#if __has_builtin(__reference_constructs_from_temporary) && 
__has_builtin(__reference_converts_from_temporary)
 #define __cpp_lib_reference_from_temporary 202202L
+#endif
 
 #if _GLIBCXX_HOSTED

 #define __cpp_lib_adaptor_iterator_pair_constructor 202106L




Re: [PATCH] libphobos: Fix instability in the parallelized testsuite

2022-07-17 Thread Lewis Hyatt via Gcc-patches
> Hi Lewis,
> 
> Thanks! Good spot. I think it should be calling dg-runtest however,
> same as what libphobos.cycles/cycles.exp is doing. Could also fix the
> test name so each one is unique, just to hit two birds in one -
> something like the following would suffice (haven't had time to check).
> 
> Kind Regards,
> Iain.
> 
> ---
> 
> --- a/libphobos/testsuite/libphobos.unittest/unittest.exp
> +++ b/libphobos/testsuite/libphobos.unittest/unittest.exp
> @@ -42,8 +42,10 @@ foreach unit_test $unit_test_list {
>  set expected_fail [lindex $unit_test 1]
>  
>  foreach test $tests {
> -set shouldfail $expected_fail
> -dg-test $test "" $test_flags
> + set libphobos_test_name "[dg-trim-dirname $srcdir $test] $test_flags"
> + set shouldfail $expected_fail
> + dg-runtest $test "" $test_flags
> + set libphobos_test_name ""
>  }
>  
>  set shouldfail 0
> 

Thanks for the followup. I tested and can confirm your version works fine:

PASS: libphobos.unittest/customhandler.d -fversion=FailNoPrintout (test for 
excess errors)
PASS: libphobos.unittest/customhandler.d -fversion=FailNoPrintout execution test
PASS: libphobos.unittest/customhandler.d -fversion=FailedTests (test for excess 
errors)
PASS: libphobos.unittest/customhandler.d -fversion=FailedTests execution test
PASS: libphobos.unittest/customhandler.d -fversion=GoodTests (test for excess 
errors)
PASS: libphobos.unittest/customhandler.d -fversion=GoodTests execution test
PASS: libphobos.unittest/customhandler.d -fversion=NoTests (test for excess 
errors)
PASS: libphobos.unittest/customhandler.d -fversion=NoTests execution test
PASS: libphobos.unittest/customhandler.d -fversion=PassNoPrintout (test for 
excess errors)
PASS: libphobos.unittest/customhandler.d -fversion=PassNoPrintout execution test

Let me know if you want me to do anything from there please?  By the way, there
are a few other tests that cause some minor glitches with comparing results:

libphobos.sum:PASS: libphobos.shared/link.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared lib.so 
-shared-libphobos (test for excess errors)
libphobos.sum:PASS: libphobos.shared/link.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared lib.so 
-shared-libphobos execution test
libphobos.sum:PASS: libphobos.shared/link_linkdep.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared 
liblinkdep.so lib.so -shared-libphobos (test for excess errors)
libphobos.sum:PASS: libphobos.shared/link_linkdep.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared 
liblinkdep.so lib.so -shared-libphobos execution test
libphobos.sum:PASS: libphobos.shared/link_loaddep.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared 
libloaddep.so -shared-libphobos (test for excess errors)
libphobos.sum:PASS: libphobos.shared/link_loaddep.d 
-I/home/lewis/gccdev/base/src/libphobos/testsuite/libphobos.shared 
libloaddep.so -shared-libphobos execution test

The problem here is that the absolute path to the test dir ends up in
the results summary, since it appears in the options string that is
part of the test name. It's not so hard to work around when doing the
comparisons, but it seems to be the only case where this happens in
the whole testsuite, other than one other similar case from libgo. Is
there a standard way to handle it I take it? Thanks...

-Lewis


Re: [PATCH] c: Fix location for _Pragma tokens [PR97498]

2022-07-17 Thread Lewis Hyatt via Gcc-patches
On Sat, Jul 9, 2022 at 11:59 PM Jeff Law via Gcc-patches
 wrote:
>
>
>
> On 7/9/2022 2:52 PM, Lewis Hyatt via Gcc-patches wrote:
> > Hello-
> >
> > PR97498 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97498) is another PR
> > related to the fact that imprecise locations for _Pragma result in
> > counterintuitive behavior for GCC diagnostic pragmas, which inhibit the
> > ability to make convenient wrapper macros for enabling and disabling
> > diagnostics in specific scopes.
> >
> > It looks like David did a lot of work a few years ago improving this
> > (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543 and
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69558), and in particular
> > r233637 added a lot of new test coverage for cases that had regressed in the
> > past.
> >
> > I think the main source of problems for all remaining issues is that we use
> > the global input_location for deciding when/if a diagnostic should apply. I
> > think it should be eventually doable to eliminate this, and rather properly
> > resolve the token locations to the place they need to be
> I've long wanted to see our dependency on input_location be diminished
> with the goal of making it go away completely.
> > so that _Pragma
> > type wrapper macros just work the way people expect.
> Certainly desirable since many projects have built wrapper macros which
> use Pragmas to control warnings.  One of the biggest QOI implementation
> details we've had with the warnings has been problems with location data
> leading to an inability to turn them off in specific locations.
>
> So I'm all for improvements, in terms of getting our location data more
> correct.
>
>
>
> >
> > That said, PR97498 can be solved easily with a 2-line fix without removing
> > input_location, and I think the resulting change to input_location's value
> > is an improvement that will benefit other areas, so I thought I'd see what
> > you think about this patch please?
> >
> > Here is a typical testcase. Note the line continuations so it's all one
> > logical line.
> >
> > ===
> > _Pragma("GCC diagnostic push") \
> > _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \
> > static void f() {} \
> > _Pragma("GCC diagnostic pop")
> > ===
> >
> > What happens is that in C++ mode, input_location is always updated to the
> > most recently-lexed token, so the above case works fine and does not warn
> > when compiled with "g++ -Wunused-functions". However, in C mode, it does
> > warn because input_location in C is almost always set to the start of the
> > line, and is in this case. So the pop is deemed to take place prior to the
> > definition of f().
> >
> > Initially, I thought it best to change input_location for C mode to behave
> > like C++, and always update to the most recently lexed token. Maybe that's
> > still the right way to go, but there was a fair amount of testsuite fallout
> > from that. Most of it, was just that we would need to change the tests to 
> > look
> > for the new locations, and in many cases, the new locations seemed
> > preferable to the old ones, but it seemed a bit much for now, so I took a
> > more measured approach and just changed input_location in the specific case
> > of processing a pragma, to be the location of the CPP_PRAGMA token.
> >
> > Unfortunately, it turns out that the CPP_PRAGMA token that libcpp provides
> > to represent the _Pragma() expression doesn't have a valid location with
> > which input_location could be overridden. Looking into that, in r232893
> > David added logic which sets the location of all tokens inside the
> > _Pragma(...) to a reasonable place (namely it points to "_Pragma" at the
> > expansion point). However, that patch didn't change the location of the
> > CPP_PRAGMA token itself to similarly point there, so the 2nd line of this
> > patch does that.
> >
> > The rest of it is just tweaking a couple tests which were sensitive to the
> > location being output. In all these cases, the new locations seem more
> > informative to me than the old ones. With those tweaks, bootstrap + regtest
> > all languages looks good with no regressions.
> >
> > Please let me know what you think? Thanks!
> > gcc/c/ChangeLog:
> >
> >   PR preprocessor/97498
> >   * c-parser.cc (c_parser_pragma): Set input_location to the
> >   location of the pragma, rather than the start of the line.
> >
> > libcpp/ChangeLog:
> >
> >   PR preprocessor/97498
> >   * directives.cc (destringize_and_run): Override the location of
> >   the CPP_PRAGMA token from a _Pragma directive to the location of
> >   the expansion point, as is done for the tokens lexed from it.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   PR preprocessor/97498
> >   * c-c++-common/pr97498.c: New test.
> >   * c-c++-common/gomp/pragma-3.c: Adapt for improved warning locations.
> >   * c-c++-common/gomp/pragma-5.c: Likewise.
> >   * gcc.dg/pragma-message.c: Likewise.
> >
> > libgomp/ChangeLog:
> >
> >   * 

Re: [PATCH] Revert "[PATCH] RISC-V: Use new linker emulations for glibc ABI."

2022-07-17 Thread Andreas K. Huettel via Gcc-patches
> I'm kind of torn on this one: this has been around for a while and 
> dropping it would be an ABI break, but the feedback from distro folks is 
> pretty consistently that multlib is broken on RISC-V.  If it's really 
> unusably broken then I could buy the argument that there's no binaries 
> (and thus no ABI to break), but there's at some base multilib 
> functionality working -- I build multilib cross toolchains regularly, 
> for example, and they can build simple stuff.

So as the one who initially bootstrapped rv64 for Gentoo in full multilib 
mode...

1) Multilib works in principle.

2) The main problem with the lib64/lp64d etc paths is that software authors
out there assume that the "libdir" is a single-depth directory. 
In Gentoo specifically, "normally" $(get_libdir) echos "lib64" and people
assume that "$(get_libdir)/../" ends up at a specific location. Now if 
$(get_libdir) echos "lib64/lp64" ...
That is not limited to the Gentoo side though.

3) The second problem is that binary-distributed software, built for
non-multilib lp64d (hey, rust, I'm talking of you), of course use
"lib64" and not "lib64/lp64d".

4) The third problem (more of an oddity) is that for rv32 the non-multilib
fallback for the "lib32/ilp32d" directories is not "lib32" but "lib".

With incompatible changes some time ago (the 17.0 to 20.0 profile change), 
2) and 3) was "fixed" in Gentoo (where we officially only do rv64 so far
because usermode qemu-riscv32 is b0rk b0rk b0rk). What I did:

* The main ABI (normally lp64d) was moved to lib64
  https://gitweb.gentoo.org/repo/gentoo.git/tree/eclass/multilib.eclass#n419
* Compat symlinks, e.g. /usr/lib64/lp64d -> . were installed.

This 
* *mostly* solves 2) because only a small subset of libraries is
  installed for the non-default ABI, 
* and solves 3) because the default ABI is in the fallback non-multilib
  location (but also accessible via the symlink if something insists).

https://gentoo.osuosl.org/releases/riscv/autobuilds/

Given these hacks, our multilib stages are not linked on the website, 
but they are built just fine and should work just fine. Feel free to
try in a chroot / with qemu / ...


> I always find making that "nobody's used it" argument really hard, 
> there's just too many users to try and track everyone down.  We're in 
> kind of a weird spot with RISC-V in general when it comes to ABI stuff: 
> we were probably a bit overly optimistic about how fast any of this was 
> going to get used when we committed to the ABI freeze, but any ABi break 
> has such a huge potential for user headaches that I'm not sure it's 
> going to be possible.  It means we're stuck with some baggage, and while 
> it's a headache to keep around stuff that's probably not all that useful 
> I think it's just what we've got to live with.


-- 
Andreas K. Hüttel
dilfri...@gentoo.org
Gentoo Linux developer
(council, toolchain, base-system, perl, libreoffice)

signature.asc
Description: This is a digitally signed message part.