[gcc r14-9418] VECT: Fix ICE for vectorizable LD/ST when both len and store are enabled

2024-03-10 Thread Pan Li via Gcc-cvs
https://gcc.gnu.org/g:993c6de642ffeb2867edbe80ff2a72c0a2eb604e

commit r14-9418-g993c6de642ffeb2867edbe80ff2a72c0a2eb604e
Author: Pan Li 
Date:   Sun Mar 10 11:02:35 2024 +0800

VECT: Fix ICE for vectorizable LD/ST when both len and store are enabled

This patch would like to fix one ICE in vectorizable_store when both the
loop_masks and loop_lens are enabled.  The ICE looks like below when build
with "-march=rv64gcv -O3".

during GIMPLE pass: vect
test.c: In function ā€˜d’:
test.c:6:6: internal compiler error: in vectorizable_store, at
tree-vect-stmts.cc:8691
6 | void d() {
  |  ^
0x37a6f2f vectorizable_store
.../__RISC-V_BUILD__/../gcc/tree-vect-stmts.cc:8691
0x37b861c vect_analyze_stmt(vec_info*, _stmt_vec_info*, bool*,
_slp_tree*, _slp_instance*, vec*)
.../__RISC-V_BUILD__/../gcc/tree-vect-stmts.cc:13242
0x1db5dca vect_analyze_loop_operations
.../__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:2208
0x1db885b vect_analyze_loop_2
.../__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3041
0x1dba029 vect_analyze_loop_1
.../__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3481
0x1dbabad vect_analyze_loop(loop*, vec_info_shared*)
.../__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3639
0x1e389d1 try_vectorize_loop_1
.../__RISC-V_BUILD__/../gcc/tree-vectorizer.cc:1066
0x1e38f3d try_vectorize_loop
.../__RISC-V_BUILD__/../gcc/tree-vectorizer.cc:1182
0x1e39230 execute
.../__RISC-V_BUILD__/../gcc/tree-vectorizer.cc:1298

There are two ways to reach vectorizer LD/ST, one is the analysis and
the other is transform.  We cannot have both the lens and the masks
enabled during transform but it is valid during analysis.  Given the
transform doesn't required cost_vec,  we can only enable the assert
based on cost_vec is NULL or not.

Below testsuites are passed for this patch:
* The x86 bootstrap tests.
* The x86 fully regression tests.
* The aarch64 fully regression tests.
* The riscv fully regressison tests.

gcc/ChangeLog:

* tree-vect-stmts.cc (vectorizable_store): Enable the assert
during transform process.
(vectorizable_load): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr114195-1.c: New test.

Signed-off-by: Pan Li 

Diff:
---
 gcc/testsuite/gcc.target/riscv/rvv/base/pr114195-1.c | 15 +++
 gcc/tree-vect-stmts.cc   | 18 ++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr114195-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr114195-1.c
new file mode 100644
index 000..a67b847112b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr114195-1.c
@@ -0,0 +1,15 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize" } */
+
+long a, b;
+extern short c[];
+
+void d() {
+  for (int e = 0; e < 35; e = 2) {
+a = ({ a < 0 ? a : 0; });
+b = ({ b < 0 ? b : 0; });
+
+c[e] = 0;
+  }
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 14a3ffb5f02..e8617439a48 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -8697,8 +8697,13 @@ vectorizable_store (vec_info *vinfo,
? &LOOP_VINFO_LENS (loop_vinfo)
: NULL);
 
-  /* Shouldn't go with length-based approach if fully masked.  */
-  gcc_assert (!loop_lens || !loop_masks);
+  /* The vect_transform_stmt and vect_analyze_stmt will go here but there
+ are some difference here.  We cannot enable both the lens and masks
+ during transform but it is allowed during analysis.
+ Shouldn't go with length-based approach if fully masked.  */
+  if (cost_vec == NULL)
+/* The cost_vec is NULL during transfrom.  */
+gcc_assert ((!loop_lens || !loop_masks));
 
   /* Targets with store-lane instructions must not require explicit
  realignment.  vect_supportable_dr_alignment always returns either
@@ -10577,8 +10582,13 @@ vectorizable_load (vec_info *vinfo,
? &LOOP_VINFO_LENS (loop_vinfo)
: NULL);
 
-  /* Shouldn't go with length-based approach if fully masked.  */
-  gcc_assert (!loop_lens || !loop_masks);
+  /* The vect_transform_stmt and vect_analyze_stmt will go here but there
+ are some difference here.  We cannot enable both the lens and masks
+ during transform but it is allowed during analysis.
+ Shouldn't go with length-based approach if fully masked.  */
+  if (cost_vec == NULL)
+/* The cost_vec is NULL during transfrom.  */
+gcc_assert ((!loop_lens || !loop_masks));
 
   /* Targets with store-lane instructions must not require explicit
  realignment.  vect_supportable_dr_alignment always returns either


[gcc r14-9419] [committed] [PR tree-optimization/110199] Simplify MIN/MAX more often

2024-03-10 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:8fe27ed193d60f6cd8b34761858a720c95eabbdb

commit r14-9419-g8fe27ed193d60f6cd8b34761858a720c95eabbdb
Author: jlaw 
Date:   Sun Mar 10 11:58:00 2024 -0600

[committed] [PR tree-optimization/110199] Simplify MIN/MAX more often

So as I mentioned in the BZ, the case of

t = MIN_EXPR (A, B)

where we know something about the relationship between A and B can be 
trivially
handled by some existing code in DOM.  That existing code would simplify 
when A
== B.  But by testing GE and LE instead of EQ we can cover more cases with
minimal effort.  When applicable the MIN/MAX turns into a simple copy.

I made one other change.  We have other binary operations that we simplify 
when
we know something about the relationship between the operands.  That code 
was
not canonicalizing the order of operands when building the expression to 
lookup
in the hash tables to discover that relationship.  Since those paths are 
only
testing for equality, we can trivially reverse them and not have to worry 
about
changing codes or anything like that.  So extremely safe and avoids having 
to
come back and fix that code to match the MIN_EXPR/MAX_EXPR case later.

Bootstrapped on x86 and also tested on the crosses.  I briefly thought there
was an sh regression, but that was actually the recent fwprop changes 
twiddling
code generation for one test.

PR tree-optimization/110199
gcc/
* tree-ssa-scopedtables.cc
(avail_exprs_stack::simplify_binary_operation): Generalize handling
of MIN_EXPR/MAX_EXPR to allow additional simplifications.  
Canonicalize
comparison operands for other cases.

gcc/testsuite

* gcc.dg/tree-ssa/minmax-27.c: New test.
* gcc.dg/tree-ssa/minmax-28.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c | 118 ++
 gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c | 117 +
 gcc/tree-ssa-scopedtables.cc  |  53 --
 3 files changed, 282 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c 
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c
new file mode 100644
index 000..4b94203b0d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom2" } */
+
+
+int min1(int a, int b)
+{
+if (a <= b)
+return a < b ? a : b;
+return 0;
+}
+
+int min2(int a, int b)
+{
+if (a <= b)
+return a > b ? b : a;
+return 0;
+}
+
+int min3(int a, int b)
+{
+if (a < b)
+return a < b ? a : b;
+return 0;
+}
+
+int min4(int a, int b)
+{
+if (a < b)
+return a > b ? b : a;
+return 0;
+}
+
+int min5(int a, int b)
+{
+if (a <= b)
+return a <= b ? a : b;
+return 0;
+}
+
+int min6(int a, int b)
+{
+if (a <= b)
+return a >= b ? b : a;
+return 0;
+}
+
+int min7(int a, int b)
+{
+if (a < b)
+return a <= b ? a : b;
+return 0;
+}
+
+int min8(int a, int b)
+{
+if (b > a)
+return a >= b ? b : a;
+return 0;
+}
+
+int min9(int a, int b)
+{
+if (b >= a)
+return a < b ? a : b;
+return 0;
+}
+
+int min10(int a, int b)
+{
+if (b >= a)
+return a > b ? b : a;
+return 0;
+}
+
+int min11(int a, int b)
+{
+if (b > a)
+return a < b ? a : b;
+return 0;
+}
+
+int min12(int a, int b)
+{
+if (b > a)
+return a > b ? b : a;
+return 0;
+}
+
+int min13(int a, int b)
+{
+if (b >= a)
+return a <= b ? a : b;
+return 0;
+}
+
+int min14(int a, int b)
+{
+if (b >= a)
+return a >= b ? b : a;
+return 0;
+}
+
+int min15(int a, int b)
+{
+if (b > a)
+return a <= b ? a : b;
+return 0;
+}
+
+int min16(int a, int b)
+{
+if (b > a)
+return a >= b ? b : a;
+return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "dom2" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c 
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c
new file mode 100644
index 000..732126d7449
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom2" } */
+
+int max1(int a, int b)
+{
+if (a <= b)
+return a < b ? b : a;
+return 0;
+}
+
+int max2(int a, int b)
+{
+if (a <= b)
+return a > b ? a : b;
+return 0;
+}
+
+int max3(int a, int b)
+{
+if (a < b)
+return a < b ? b : a;
+return 0;
+}
+
+int max4(int a, int b)
+{
+if (a < b)
+return a > b ? a : b;
+return 0;
+}
+
+int max5(int a, int b)
+{
+if (a <= b)
+return a <= b ? b : a;
+return 0;
+}
+
+int max6(int a, int b)
+{
+if (a <= b)
+return a >= b ? a : b;
+return 0;
+}
+
+int max7(int a, int b)
+{
+if (a < b)
+re

[gcc r14-9420] d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

2024-03-10 Thread Iain Buclaw via Gcc-cvs
https://gcc.gnu.org/g:a84b98c62d90bf9e8b01038f624a62725e6a44db

commit r14-9420-ga84b98c62d90bf9e8b01038f624a62725e6a44db
Author: Iain Buclaw 
Date:   Sun Mar 10 17:49:06 2024 +0100

d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

The way that the target hook preferPassByRef is implemented, it relied
on the GCC "back-end" tree type to determine whether or not to use `ref'
ABI for D `in' parameters; e.g: prefer by value if it is expected that
the target will pass the type around in registers.

Building the GCC tree type depends on the AST type being complete - all
semantic processing is finished - but as this hook is called from the
front-end, this will not be the case for forward referenced or
self-referencing types.

The consensus in upstream is that `in' parameters should always be
implicitly `ref', but as the front-end does not yet support all types
being rvalue references, limit this just static arrays and structs.

PR d/112285
PR d/112290

gcc/d/ChangeLog:

* d-target.cc (Target::preferPassByRef): Return true for all static
array and struct types.

gcc/testsuite/ChangeLog:

* gdc.dg/pr112285.d: New test.
* gdc.dg/pr112290.d: New test.

Diff:
---
 gcc/d/d-target.cc   | 25 +
 gcc/testsuite/gdc.dg/pr112285.d | 13 +
 gcc/testsuite/gdc.dg/pr112290.d | 15 +++
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index b9d124422b7..127b9d7ce7c 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -575,31 +575,16 @@ Target::supportsLinkerDirective (void) const
 }
 
 /* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to
-   be passed by reference or by valie.  This is used only when compiling with
+   be passed by reference or by value.  This is used only when compiling with
`-fpreview=in' enabled.  */
 
 bool
 Target::preferPassByRef (Type *param_type)
 {
-  if (param_type->size () == SIZE_INVALID)
+  /* See note in Target::isReturnOnStack.  */
+  Type *tb = param_type->toBasetype ();
+  if (tb->size () == SIZE_INVALID)
 return false;
 
-  tree type = build_ctype (param_type);
-
-  /* Prefer a `ref' if the type is an aggregate, and its size is greater than
- its alignment.  */
-  if (AGGREGATE_TYPE_P (type)
-  && (!valid_constant_size_p (TYPE_SIZE_UNIT (type))
- || compare_tree_int (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type)) > 0))
-return true;
-
-  /* If the back-end is always going to pass this by invisible reference.  */
-  if (pass_by_reference (NULL, function_arg_info (type, true)))
-return true;
-
-  /* If returning the parameter means the caller will do RVO.  */
-  if (targetm.calls.return_in_memory (type, NULL_TREE))
-return true;
-
-  return false;
+  return (tb->ty == TY::Tstruct || tb->ty == TY::Tsarray);
 }
diff --git a/gcc/testsuite/gdc.dg/pr112285.d b/gcc/testsuite/gdc.dg/pr112285.d
new file mode 100644
index 000..5ca100a74a9
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112285.d
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112285
+{
+}
+
+class C112285
+{
+S112285 s;
+void f112285(in C112285)
+{
+}
+}
diff --git a/gcc/testsuite/gdc.dg/pr112290.d b/gcc/testsuite/gdc.dg/pr112290.d
new file mode 100644
index 000..7456fc21be1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112290.d
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112290a
+{
+S112290b* p;
+bool opEquals(in S112290a)
+{
+return p == p;
+}
+}
+
+struct S112290b
+{
+string s;
+}


[gcc r13-8415] d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

2024-03-10 Thread Iain Buclaw via Gcc-cvs
https://gcc.gnu.org/g:025ff57c19efae6c8d76df6b93e7d9827017acc9

commit r13-8415-g025ff57c19efae6c8d76df6b93e7d9827017acc9
Author: Iain Buclaw 
Date:   Sun Mar 10 17:49:06 2024 +0100

d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

The way that the target hook preferPassByRef is implemented, it relied
on the GCC "back-end" tree type to determine whether or not to use `ref'
ABI for D `in' parameters; e.g: prefer by value if it is expected that
the target will pass the type around in registers.

Building the GCC tree type depends on the AST type being complete - all
semantic processing is finished - but as this hook is called from the
front-end, this will not be the case for forward referenced or
self-referencing types.

The consensus in upstream is that `in' parameters should always be
implicitly `ref', but as the front-end does not yet support all types
being rvalue references, limit this just static arrays and structs.

PR d/112285
PR d/112290

gcc/d/ChangeLog:

* d-target.cc (Target::preferPassByRef): Return true for all static
array and struct types.

gcc/testsuite/ChangeLog:

* gdc.dg/pr112285.d: New test.
* gdc.dg/pr112290.d: New test.
* gdc.test/compilable/previewin.d: Adjust testcase.

(cherry picked from commit a84b98c62d90bf9e8b01038f624a62725e6a44db)

Diff:
---
 gcc/d/d-target.cc | 25 +
 gcc/testsuite/gdc.dg/pr112285.d   | 13 +
 gcc/testsuite/gdc.dg/pr112290.d   | 15 +++
 gcc/testsuite/gdc.test/compilable/previewin.d |  6 --
 4 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index 4c7a212703e..73366fdde16 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -575,31 +575,16 @@ Target::supportsLinkerDirective (void) const
 }
 
 /* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to
-   be passed by reference or by valie.  This is used only when compiling with
+   be passed by reference or by value.  This is used only when compiling with
`-fpreview=in' enabled.  */
 
 bool
 Target::preferPassByRef (Type *param_type)
 {
-  if (param_type->size () == SIZE_INVALID)
+  /* See note in Target::isReturnOnStack.  */
+  Type *tb = param_type->toBasetype ();
+  if (tb->size () == SIZE_INVALID)
 return false;
 
-  tree type = build_ctype (param_type);
-
-  /* Prefer a `ref' if the type is an aggregate, and its size is greater than
- its alignment.  */
-  if (AGGREGATE_TYPE_P (type)
-  && (!valid_constant_size_p (TYPE_SIZE_UNIT (type))
- || compare_tree_int (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type)) > 0))
-return true;
-
-  /* If the back-end is always going to pass this by invisible reference.  */
-  if (pass_by_reference (NULL, function_arg_info (type, true)))
-return true;
-
-  /* If returning the parameter means the caller will do RVO.  */
-  if (targetm.calls.return_in_memory (type, NULL_TREE))
-return true;
-
-  return false;
+  return (tb->ty == TY::Tstruct || tb->ty == TY::Tsarray);
 }
diff --git a/gcc/testsuite/gdc.dg/pr112285.d b/gcc/testsuite/gdc.dg/pr112285.d
new file mode 100644
index 000..5ca100a74a9
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112285.d
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112285
+{
+}
+
+class C112285
+{
+S112285 s;
+void f112285(in C112285)
+{
+}
+}
diff --git a/gcc/testsuite/gdc.dg/pr112290.d b/gcc/testsuite/gdc.dg/pr112290.d
new file mode 100644
index 000..7456fc21be1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112290.d
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112290a
+{
+S112290b* p;
+bool opEquals(in S112290a)
+{
+return p == p;
+}
+}
+
+struct S112290b
+{
+string s;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/previewin.d 
b/gcc/testsuite/gdc.test/compilable/previewin.d
index 8926fbd6aa7..558005c5280 100644
--- a/gcc/testsuite/gdc.test/compilable/previewin.d
+++ b/gcc/testsuite/gdc.test/compilable/previewin.d
@@ -79,14 +79,11 @@ version (Win64)
 {
 void checkReal(in real p)
 {
-// ref for x87 real, value for double-precision real
-static assert(__traits(isRef, p) == (real.sizeof > 8));
 }
 
 struct RGB { ubyte r, g, b; }
 void checkNonPowerOf2(in RGB p)
 {
-static assert(__traits(isRef, p));
 }
 }
 else version (X86_64) // Posix x86_64
@@ -94,7 +91,6 @@ else version (X86_64) // Posix x86_64
 struct Empty {} // 1 dummy byte passed on the stack
 void checkEmptyStruct(in Empty p)
 {
-static assert(!__traits(isRef, p));
 }
 
 static if (is(__vector(double[4])))
@@ -102,7 +98,6 @@ else version (X86_64) // Posix x86_6

[gcc r12-10202] d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

2024-03-10 Thread Iain Buclaw via Gcc-cvs
https://gcc.gnu.org/g:ec3a01024dd86c51d1e563df9395123765cf548d

commit r12-10202-gec3a01024dd86c51d1e563df9395123765cf548d
Author: Iain Buclaw 
Date:   Sun Mar 10 17:49:06 2024 +0100

d: Fix -fpreview=in ICEs with forward referenced parameter [PR112285]

The way that the target hook preferPassByRef is implemented, it relied
on the GCC "back-end" tree type to determine whether or not to use `ref'
ABI for D `in' parameters; e.g: prefer by value if it is expected that
the target will pass the type around in registers.

Building the GCC tree type depends on the AST type being complete - all
semantic processing is finished - but as this hook is called from the
front-end, this will not be the case for forward referenced or
self-referencing types.

The consensus in upstream is that `in' parameters should always be
implicitly `ref', but as the front-end does not yet support all types
being rvalue references, limit this just static arrays and structs.

PR d/112285
PR d/112290

gcc/d/ChangeLog:

* d-target.cc (Target::preferPassByRef): Return true for all static
array and struct types.

gcc/testsuite/ChangeLog:

* gdc.dg/pr112285.d: New test.
* gdc.dg/pr112290.d: New test.
* gdc.test/compilable/previewin.d: Adjust testcase.

(cherry picked from commit 025ff57c19efae6c8d76df6b93e7d9827017acc9)

Diff:
---
 gcc/d/d-target.cc | 25 +
 gcc/testsuite/gdc.dg/pr112285.d   | 13 +
 gcc/testsuite/gdc.dg/pr112290.d   | 15 +++
 gcc/testsuite/gdc.test/compilable/previewin.d |  6 --
 4 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d4350e593e4..f80ea466e24 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -586,31 +586,16 @@ Target::supportsLinkerDirective (void) const
 }
 
 /* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to
-   be passed by reference or by valie.  This is used only when compiling with
+   be passed by reference or by value.  This is used only when compiling with
`-fpreview=in' enabled.  */
 
 bool
 Target::preferPassByRef (Type *param_type)
 {
-  if (param_type->size () == SIZE_INVALID)
+  /* See note in Target::isReturnOnStack.  */
+  Type *tb = param_type->toBasetype ();
+  if (tb->size () == SIZE_INVALID)
 return false;
 
-  tree type = build_ctype (param_type);
-
-  /* Prefer a `ref' if the type is an aggregate, and its size is greater than
- its alignment.  */
-  if (AGGREGATE_TYPE_P (type)
-  && (!valid_constant_size_p (TYPE_SIZE_UNIT (type))
- || compare_tree_int (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type)) > 0))
-return true;
-
-  /* If the back-end is always going to pass this by invisible reference.  */
-  if (pass_by_reference (NULL, function_arg_info (type, true)))
-return true;
-
-  /* If returning the parameter means the caller will do RVO.  */
-  if (targetm.calls.return_in_memory (type, NULL_TREE))
-return true;
-
-  return false;
+  return (tb->ty == TY::Tstruct || tb->ty == TY::Tsarray);
 }
diff --git a/gcc/testsuite/gdc.dg/pr112285.d b/gcc/testsuite/gdc.dg/pr112285.d
new file mode 100644
index 000..5ca100a74a9
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112285.d
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112285
+{
+}
+
+class C112285
+{
+S112285 s;
+void f112285(in C112285)
+{
+}
+}
diff --git a/gcc/testsuite/gdc.dg/pr112290.d b/gcc/testsuite/gdc.dg/pr112290.d
new file mode 100644
index 000..7456fc21be1
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr112290.d
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-additional-options "-fpreview=in" }
+struct S112290a
+{
+S112290b* p;
+bool opEquals(in S112290a)
+{
+return p == p;
+}
+}
+
+struct S112290b
+{
+string s;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/previewin.d 
b/gcc/testsuite/gdc.test/compilable/previewin.d
index 8926fbd6aa7..558005c5280 100644
--- a/gcc/testsuite/gdc.test/compilable/previewin.d
+++ b/gcc/testsuite/gdc.test/compilable/previewin.d
@@ -79,14 +79,11 @@ version (Win64)
 {
 void checkReal(in real p)
 {
-// ref for x87 real, value for double-precision real
-static assert(__traits(isRef, p) == (real.sizeof > 8));
 }
 
 struct RGB { ubyte r, g, b; }
 void checkNonPowerOf2(in RGB p)
 {
-static assert(__traits(isRef, p));
 }
 }
 else version (X86_64) // Posix x86_64
@@ -94,7 +91,6 @@ else version (X86_64) // Posix x86_64
 struct Empty {} // 1 dummy byte passed on the stack
 void checkEmptyStruct(in Empty p)
 {
-static assert(!__traits(isRef, p));
 }
 
 static if (is(__vector(double[4])))
@@ -102,7 +98,6 @@ else version (X86_64) // Posix x86_

[gcc r14-9422] Fold: Fix up merge_truthop_with_opposite_arm for NaNs [PR95351]

2024-03-10 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:31ce2e993d09dcad1ce139a2848a28de5931056d

commit r14-9422-g31ce2e993d09dcad1ce139a2848a28de5931056d
Author: Andrew Pinski 
Date:   Sun Mar 10 22:17:09 2024 +

Fold: Fix up merge_truthop_with_opposite_arm for NaNs [PR95351]

The problem here is that merge_truthop_with_opposite_arm would
use the type of the result of the comparison rather than the operands
of the comparison to figure out if we are honoring NaNs.
This fixes that oversight and now we get the correct results in this
case.

Committed as obvious after a bootstrap/test on x86_64-linux-gnu.

PR middle-end/95351

gcc/ChangeLog:

* fold-const.cc (merge_truthop_with_opposite_arm): Use
the type of the operands of the comparison and not the type
of the comparison.

gcc/testsuite/ChangeLog:

* gcc.dg/float_opposite_arm-1.c: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/fold-const.cc   |  3 ++-
 gcc/testsuite/gcc.dg/float_opposite_arm-1.c | 17 +
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 43105d20be3..299c22bf391 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -6420,7 +6420,6 @@ static tree
 merge_truthop_with_opposite_arm (location_t loc, tree op, tree cmpop,
 bool rhs_only)
 {
-  tree type = TREE_TYPE (cmpop);
   enum tree_code code = TREE_CODE (cmpop);
   enum tree_code truthop_code = TREE_CODE (op);
   tree lhs = TREE_OPERAND (op, 0);
@@ -6436,6 +6435,8 @@ merge_truthop_with_opposite_arm (location_t loc, tree op, 
tree cmpop,
   if (TREE_CODE_CLASS (code) != tcc_comparison)
 return NULL_TREE;
 
+  tree type = TREE_TYPE (TREE_OPERAND (cmpop, 0));
+
   if (rhs_code == truthop_code)
 {
   tree newrhs = merge_truthop_with_opposite_arm (loc, rhs, cmpop, 
rhs_only);
diff --git a/gcc/testsuite/gcc.dg/float_opposite_arm-1.c 
b/gcc/testsuite/gcc.dg/float_opposite_arm-1.c
new file mode 100644
index 000..d2dbff35066
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/float_opposite_arm-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-original -fdump-tree-optimized" } */
+/* { dg-add-options ieee } */
+/* PR middle-end/95351 */
+
+int Foo(double possiblyNAN, double b, double c)
+{
+return (possiblyNAN <= 2.0) || ((possiblyNAN  > 2.0) && (b > c));
+}
+
+/* Make sure we don't remove either >/<=  */
+
+/* { dg-final { scan-tree-dump "possiblyNAN > 2.0e.0" "original" } } */
+/* { dg-final { scan-tree-dump "possiblyNAN_\[0-9\]+.D. > 2.0e.0" "optimized" 
} } */
+
+/* { dg-final { scan-tree-dump "possiblyNAN <= 2.0e.0" "original" } } */
+/* { dg-final { scan-tree-dump "possiblyNAN_\[0-9\]+.D. <= 2.0e.0" "optimized" 
} } */