public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-9730] d: Suboptimal codegen for __builtin_expect(cond, false)
@ 2023-06-26  2:07 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2023-06-26  2:07 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0f54a73b998b72f7c8452a63730ec3b16fc47854

commit r12-9730-g0f54a73b998b72f7c8452a63730ec3b16fc47854
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Mon Jun 26 03:24:27 2023 +0200

    d: Suboptimal codegen for __builtin_expect(cond, false)
    
    Since PR96435, both boolean objects and expressions have been evaluated
    in the following way.
    
        (*(ubyte*)&obj_or_expr) & 1
    
    It has been noted that sometimes this can cause the back-end to optimize
    in non-obvious ways - in particular with __builtin_expect.
    
    This @safe feature is now restricted to just when reading the value of a
    bool field that comes from a union.
    
            PR d/110359
    
    gcc/d/ChangeLog:
    
            * d-convert.cc (convert_for_rvalue): Only apply the @safe boolean
            conversion to boolean fields of a union.
            (convert_for_condition): Call convert_for_rvalue in the default case.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/pr110359.d: New test.
    
    (cherry picked from commit ab98db1e8c1b997414539f41b7fb814019497d8d)

Diff:
---
 gcc/d/d-convert.cc              | 31 +++++++++++++++++++------------
 gcc/testsuite/gdc.dg/pr110359.d | 22 ++++++++++++++++++++++
 2 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index ec5da6c10a6..2023245256b 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -620,7 +620,7 @@ convert_expr (tree exp, Type *etype, Type *totype)
   return result ? result : convert (build_ctype (totype), exp);
 }
 
-/* Return a TREE represenwation of EXPR, whose type has been converted from
+/* Return a TREE representation of EXPR, whose type has been converted from
  * ETYPE to TOTYPE, and is being used in an rvalue context.  */
 
 tree
@@ -635,20 +635,27 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
     {
       /* If casting from bool, the result is either 0 or 1, any other value
 	 violates @safe code, so enforce that it is never invalid.  */
-      if (CONSTANT_CLASS_P (expr))
-	result = d_truthvalue_conversion (expr);
-      else
+      for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
+	   ref = TREE_OPERAND (ref, 0))
 	{
-	  /* Reinterpret the boolean as an integer and test the first bit.
-	     The generated code should end up being equivalent to:
+	  /* If the expression is a field that's part of a union, reinterpret
+	     the boolean as an integer and test the first bit.  The generated
+	     code should end up being equivalent to:
 		*cast(ubyte *)&expr & 1;  */
-	  machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
-	  tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
-	  result = fold_build2 (BIT_AND_EXPR, mtype,
-				build_vconvert (mtype, expr),
-				build_one_cst (mtype));
+	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
+	    {
+	      machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
+	      tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
+	      result = fold_build2 (BIT_AND_EXPR, mtype,
+				    build_vconvert (mtype, expr),
+				    build_one_cst (mtype));
+	      break;
+	    }
 	}
 
+      if (result == NULL_TREE)
+	result = d_truthvalue_conversion (expr);
+
       result = convert (build_ctype (tbtype), result);
     }
 
@@ -845,7 +852,7 @@ convert_for_condition (tree expr, Type *type)
       break;
 
     default:
-      result = expr;
+      result = convert_for_rvalue (expr, type, type);
       break;
     }
 
diff --git a/gcc/testsuite/gdc.dg/pr110359.d b/gcc/testsuite/gdc.dg/pr110359.d
new file mode 100644
index 00000000000..bf69201d9a5
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr110359.d
@@ -0,0 +1,22 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110359
+// { dg-do compile }
+// { dg-options "-fdump-tree-original" }
+double pow(in double x, in ulong p)
+{
+    import gcc.builtins : __builtin_expect;
+    if (__builtin_expect(p == 0, false))
+        return 1;
+    if (__builtin_expect(p == 1, false))
+        return x;
+
+    double s = x;
+    double v = 1;
+    for (ulong i = p; i > 1; i >>= 1)
+    {
+        v = (i & 0x1) ? s * v : v;
+        s = s * s;
+    }
+    return v * s;
+}
+// { dg-final { scan-tree-dump "if \\(__builtin_expect \\(p == 0, 0\\) != 0\\)" "original" } }
+// { dg-final { scan-tree-dump "if \\(__builtin_expect \\(p == 1, 0\\) != 0\\)" "original" } }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-26  2:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-26  2:07 [gcc r12-9730] d: Suboptimal codegen for __builtin_expect(cond, false) Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).