]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Constant fold {-1,-1} << 1 in simplify-rtx.cc
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 9 May 2024 21:45:54 +0000 (22:45 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 9 May 2024 21:45:54 +0000 (22:45 +0100)
This patch addresses a missed optimization opportunity in the RTL
optimization passes.  The function simplify_const_binary_operation
will constant fold binary operators with two CONST_INT operands,
and those with two CONST_VECTOR operands, but is missing compile-time
evaluation of binary operators with a CONST_VECTOR and a CONST_INT,
such as vector shifts and rotates.

The first version of this patch didn't contain a switch statement to
explicitly check for valid binary opcodes, which bootstrapped and
regression tested fine, but my paranoia has got the better of me,
so this version now checks that VEC_SELECT or some funky (future)
rtx_code doesn't cause problems.

2024-05-09  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* simplify-rtx.cc (simplify_const_binary_operation): Constant
fold binary operations where the LHS is CONST_VECTOR and the
RHS is CONST_INT (or CONST_DOUBLE) such as vector shifts.

gcc/simplify-rtx.cc

index dceaa13333ca62f5728e76785d379e531e7cba79..53f54d1d392883f3438cd2d32a4b7bf9c1c6cfc1 100644 (file)
@@ -5021,6 +5021,60 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
       return gen_rtx_CONST_VECTOR (mode, v);
     }
 
+  if (VECTOR_MODE_P (mode)
+      && GET_CODE (op0) == CONST_VECTOR
+      && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
+      && (CONST_VECTOR_DUPLICATE_P (op0)
+         || CONST_VECTOR_NUNITS (op0).is_constant ()))
+    {
+      switch (code)
+       {
+       case PLUS:
+       case MINUS:
+       case MULT:
+       case DIV:
+       case MOD:
+       case UDIV:
+       case UMOD:
+       case AND:
+       case IOR:
+       case XOR:
+       case SMIN:
+       case SMAX:
+       case UMIN:
+       case UMAX:
+       case LSHIFTRT:
+       case ASHIFTRT:
+       case ASHIFT:
+       case ROTATE:
+       case ROTATERT:
+       case SS_PLUS:
+       case US_PLUS:
+       case SS_MINUS:
+       case US_MINUS:
+       case SS_ASHIFT:
+       case US_ASHIFT:
+       case COPYSIGN:
+         break;
+       default:
+         return NULL_RTX;
+       }
+
+      unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
+                               ? CONST_VECTOR_NPATTERNS (op0)
+                               : CONST_VECTOR_NUNITS (op0).to_constant ());
+      rtx_vector_builder builder (mode, npatterns, 1);
+      for (unsigned i = 0; i < npatterns; i++)
+       {
+         rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
+                                            CONST_VECTOR_ELT (op0, i), op1);
+         if (!x || !valid_for_const_vector_p (mode, x))
+           return 0;
+         builder.quick_push (x);
+       }
+      return builder.build ();
+    }
+
   if (SCALAR_FLOAT_MODE_P (mode)
       && CONST_DOUBLE_AS_FLOAT_P (op0) 
       && CONST_DOUBLE_AS_FLOAT_P (op1)