From e55dcff97708a4937dc4d8736b8b3074ebbff6f3 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 27 Oct 2025 17:43:17 +0100
Subject: phiopt: Fix up DEBUG_EXPR_DECL creation in spaceship_replacement
 [PR122394]

The following testcase ICEs in gcc 15 (and is at least latent in 12-14 too),
because the DEBUG_EXPR_DECL has incorrect mode.  It has
TREE_TYPE (orig_use_lhs) type, but TYPE_MODE (type) rather than
TYPE_MODE (TREE_TYPE (orig_use_lhs)) where the two types are sometimes
the same, but sometimes different (same if !has_cast_debug_uses, different
otherwise).

Though, there wouldn't be the this issue if it used the proper API to create
the DEBUG_EXPR_DECL which takes care of everything.  This is the sole
spot that doesn't use that API.

Doesn't affect the trunk because the code has been removed and replaced with
different stuff after the libstdc++ ABI change in r16-3474.
Before r15-5557 the mode has been always wrong because this was done only
for has_cast_debug_uses.  And the bug has been introduced with r12-5490.

Enough archeology, while it could be fixed by changing the second
SET_DECL_MODE argument, I think it is better to use build_debug_expr_decl.

2025-10-27  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/122394
	* tree-ssa-phiopt.cc (spaceship_replacement): Use
	build_debug_expr_decl instead of manually building DEBUG_EXPR_DECL
	and getting SET_DECL_MODE wrong.

	* g++.dg/opt/pr122394.C: New test.

Upstream-Status: Backport [https://gcc.gnu.org/cgit/gcc/commit/?id=e55dcff97708a4937dc4d8736b8b3074ebbff6f3]
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 gcc/testsuite/g++.dg/opt/pr122394.C | 20 ++++++++++++++++++++
 gcc/tree-ssa-phiopt.cc              |  6 ++----
 2 files changed, 22 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/pr122394.C

diff --git a/gcc/testsuite/g++.dg/opt/pr122394.C b/gcc/testsuite/g++.dg/opt/pr122394.C
new file mode 100644
index 000000000000..1f84bebd74c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr122394.C
@@ -0,0 +1,20 @@
+// PR tree-optimization/122394
+// { dg-do compile { target c++23 } }
+// { dg-options "-O1 -g" }
+
+#include <compare>
+
+struct A {
+  friend auto operator<=> (A, A) = default;
+  double a;
+};
+void foo ();
+A b, c;
+
+void
+bar ()
+{
+  bool d = c >= b;
+  if (d)
+    foo ();
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index aaebae6b38c0..3e0ad9d3bb09 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -2995,10 +2995,8 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb,
 	      if (has_cast_debug_uses
 		  || (HONOR_NANS (TREE_TYPE (lhs1)) && !is_cast))
 		{
-		  tree temp3 = make_node (DEBUG_EXPR_DECL);
-		  DECL_ARTIFICIAL (temp3) = 1;
-		  TREE_TYPE (temp3) = TREE_TYPE (orig_use_lhs);
-		  SET_DECL_MODE (temp3, TYPE_MODE (type));
+		  tree temp3
+		    = build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
 		  if (has_cast_debug_uses)
 		    t = fold_convert (TREE_TYPE (temp3), temp2);
 		  else
-- 
cgit 

