opt77.adb: New test.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 26 Feb 2019 10:55:16 +0000 (10:55 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 26 Feb 2019 10:55:16 +0000 (10:55 +0000)
* gnat.dg/opt77.adb: New test.
* gnat.dg/opt77_pkg.ad[sb]: New helper.

From-SVN: r269208

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt77.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt77_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt77_pkg.ads [new file with mode: 0644]
gcc/tree-ssa-dom.c

index fdc72bbaef19669b28e260029c1864d5f71289fb..263cc7b5f112c2f55205b69961852765bf9f03ed 100644 (file)
@@ -1,3 +1,10 @@
+2019-02-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-ssa-dom.c (edge_info::derive_equivalences) <BIT_IOR_EXPR>: Fix
+       and move around comment.
+       <BIT_AND_EXPR>: Likewise.
+       <BIT_NOT_EXPR>: Add specific handling for boolean types.
+
 2019-02-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/89474
index 3c90c8df084518ad153182e1491a1ddb0f407af4..cc582c9e6776a33805cb0b93d6e0b93689334812 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/opt77.adb: New test.
+       * gnat.dg/opt77_pkg.ad[sb]: New helper.
+
 2019-02-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/89474
diff --git a/gcc/testsuite/gnat.dg/opt77.adb b/gcc/testsuite/gnat.dg/opt77.adb
new file mode 100644 (file)
index 0000000..4d0288a
--- /dev/null
@@ -0,0 +1,14 @@
+-- { dg-do run }
+-- { dg-options "-O -fno-inline" }
+
+with Opt77_Pkg; use Opt77_Pkg;
+
+procedure Opt77 is
+  N : Natural := 0;
+  To_Add : Boolean;
+begin
+  Proc ("One", N, To_Add);
+  if To_Add then
+    raise Program_Error;
+  end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt77_pkg.adb b/gcc/testsuite/gnat.dg/opt77_pkg.adb
new file mode 100644 (file)
index 0000000..b3c1e4b
--- /dev/null
@@ -0,0 +1,28 @@
+package body Opt77_Pkg is
+
+  function Compare (S : String) return Boolean is
+  begin
+    return S = "Two";
+  end;
+
+  procedure Proc (S : String; N : in out Natural; To_Add : out Boolean) is
+    To_Take : Boolean := False;
+    To_Read : Boolean := False;
+  begin
+    To_Add := False;
+
+    if S = "One" then
+      To_Read := True;
+      To_Take := Compare (S);
+    end if;
+
+    if To_Read and not To_Take then
+      N := N + 1;
+    end if;
+
+    if To_Take then
+      To_Add := True;
+    end if;
+  end;
+
+end Opt77_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt77_pkg.ads b/gcc/testsuite/gnat.dg/opt77_pkg.ads
new file mode 100644 (file)
index 0000000..ce3985a
--- /dev/null
@@ -0,0 +1,5 @@
+package Opt77_Pkg is
+
+  procedure Proc (S : String; N : in out Natural; To_Add : out Boolean);
+
+end Opt77_Pkg;
index 12647e76b87982b63d7e779c3b611857b50546a7..4f4b7db21896813ff9b204c6eae16b92a567e900 100644 (file)
@@ -170,11 +170,10 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
   if (is_gimple_assign (def_stmt))
     {
-      /* We know the result of DEF_STMT was zero.  See if that allows
-        us to deduce anything about the SSA_NAMEs used on the RHS.  */
       enum tree_code code = gimple_assign_rhs_code (def_stmt);
       switch (code)
        {
+       /* If the result of an OR is zero, then its operands are, too.  */
        case BIT_IOR_EXPR:
          if (integer_zerop (value))
            {
@@ -188,8 +187,7 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
            }
          break;
 
-      /* We know the result of DEF_STMT was one.  See if that allows
-        us to deduce anything about the SSA_NAMEs used on the RHS.  */
+       /* If the result of an AND is nonzero, then its operands are, too.  */
        case BIT_AND_EXPR:
          if (!integer_zerop (value))
            {
@@ -296,7 +294,6 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
            break;
          }
 
-
        case EQ_EXPR:
        case NE_EXPR:
          {
@@ -336,7 +333,28 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
        case NEGATE_EXPR:
          {
            tree rhs = gimple_assign_rhs1 (def_stmt);
-           tree res = fold_build1 (code, TREE_TYPE (rhs), value);
+           tree res;
+           /* If this is a NOT and the operand has a boolean range, then we
+              know its value must be zero or one.  We are not supposed to
+              have a BIT_NOT_EXPR for boolean types with precision > 1 in
+              the general case, see e.g. the handling of TRUTH_NOT_EXPR in
+              the gimplifier, but it can be generated by match.pd out of
+              a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR.  Now the handling
+              of BIT_AND_EXPR above already forces a specific semantics for
+              boolean types with precision > 1 so we must do the same here,
+              otherwise we could change the semantics of TRUTH_NOT_EXPR for
+              boolean types with precision > 1.  */
+           if (code == BIT_NOT_EXPR
+               && TREE_CODE (rhs) == SSA_NAME
+               && ssa_name_has_boolean_range (rhs))
+             {
+               if (integer_zerop (value))
+                 res = build_one_cst (TREE_TYPE (rhs));
+               else
+                 res = build_zero_cst (TREE_TYPE (rhs));
+             }
+           else
+             res = fold_build1 (code, TREE_TYPE (rhs), value);
            derive_equivalences (rhs, res, recursion_limit - 1);
            break;
          }