From 75fb811dfaa29d60a897924b0d1629577b90eee7 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 23 Mar 2020 17:55:20 -0600 Subject: Verify the code used for the optimized comparison is valid for the comparison's mode. PR rtl-optimization/90275 PR target/94238 PR target/94144 * simplify-rtx.c (comparison_code_valid_for_mode): New function. (simplify_logical_relational_operation): Use it. PR target/94144 PR target/94238 * gcc.c-torture/compile/pr94144.c: New test. * gcc.c-torture/compile/pr94238.c: New test. --- gcc/simplify-rtx.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'gcc/simplify-rtx.c') diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index dd3d851..28c2dc6 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2215,6 +2215,53 @@ mask_to_comparison (int mask) } } +/* Return true if CODE is valid for comparisons of mode MODE, false + otherwise. + + It is always safe to return false, even if the code was valid for the + given mode as that will merely suppress optimizations. */ + +static bool +comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode) +{ + switch (code) + { + /* These are valid for integral, floating and vector modes. */ + case NE: + case EQ: + case GE: + case GT: + case LE: + case LT: + return (INTEGRAL_MODE_P (mode) + || FLOAT_MODE_P (mode) + || VECTOR_MODE_P (mode)); + + /* These are valid for floating point modes. */ + case LTGT: + case UNORDERED: + case ORDERED: + case UNEQ: + case UNGE: + case UNGT: + case UNLE: + case UNLT: + return FLOAT_MODE_P (mode); + + /* These are filtered out in simplify_logical_operation, but + we check for them too as a matter of safety. They are valid + for integral and vector modes. */ + case GEU: + case GTU: + case LEU: + case LTU: + return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode); + + default: + gcc_unreachable (); + } +} + /* Simplify a logical operation CODE with result mode MODE, operating on OP0 and OP1, which should be both relational operations. Return 0 if no such simplification is possible. */ @@ -2252,6 +2299,10 @@ simplify_logical_relational_operation (enum rtx_code code, machine_mode mode, code = mask_to_comparison (mask); + /* Many comparison codes are only valid for certain mode classes. */ + if (!comparison_code_valid_for_mode (code, mode)) + return 0; + op0 = XEXP (op1, 0); op1 = XEXP (op1, 1); -- cgit v1.1