Jeff approved an older version of this (as a separate unittests/test-folding.c): https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03305.html > OK if/when prereqs are approved. Minor twiddling if we end up > moving it elsewhere or standardizing/reducing header files > is pre-approved.
gcc/ChangeLog: * fold-const.c: Include "selftest.h". (class tree_folding_test): New test subclass. (tree_folding_test, arithmetic_folding): New selftest. --- gcc/fold-const.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 698062e..27c9216 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-into-ssa.h" #include "md5.h" #include "case-cfn-macros.h" +#include "selftest.h" #ifndef LOAD_EXTEND_OP #define LOAD_EXTEND_OP(M) UNKNOWN @@ -14423,3 +14424,68 @@ c_getstr (tree src) return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node); } + +#if CHECKING_P + +namespace { + +/* A test fixture for writing tests of folding trees. */ +class tree_folding_test : public ::selftest::test +{ + protected: + void + assert_binop_folds_to_const (tree lhs, enum tree_code code, tree rhs, + tree constant) + { + EXPECT_EQ (constant, fold_build2 (code, TREE_TYPE (lhs), lhs, rhs)); + } + + void + assert_binop_folds_to_nonlvalue (tree lhs, enum tree_code code, tree rhs, + tree wrapped_expr) + { + tree result = fold_build2 (code, TREE_TYPE (lhs), lhs, rhs); + EXPECT_NE (wrapped_expr, result); + EXPECT_EQ (NON_LVALUE_EXPR, TREE_CODE (result)); + EXPECT_EQ (wrapped_expr, TREE_OPERAND (result, 0)); + } +}; + +TEST_F (tree_folding_test, arithmetic_folding) +{ + tree type = integer_type_node; + tree x = create_tmp_var_raw (type, "x"); + tree zero = build_zero_cst (type); + tree one = build_int_cst (type, 1); + + /* Addition. */ + /* 1 <-- (0 + 1) */ + assert_binop_folds_to_const (zero, PLUS_EXPR, one, + one); + assert_binop_folds_to_const (one, PLUS_EXPR, zero, + one); + + /* (nonlvalue)x <-- (x + 0) */ + assert_binop_folds_to_nonlvalue (x, PLUS_EXPR, zero, + x); + + /* Subtraction. */ + /* 0 <-- (x - x) */ + assert_binop_folds_to_const (x, MINUS_EXPR, x, + zero); + assert_binop_folds_to_nonlvalue (x, MINUS_EXPR, zero, + x); + + /* Multiplication. */ + /* 0 <-- (x * 0) */ + assert_binop_folds_to_const (x, MULT_EXPR, zero, + zero); + + /* (nonlvalue)x <-- (x * 1) */ + assert_binop_folds_to_nonlvalue (x, MULT_EXPR, one, + x); +} + +} // anon namespace + +#endif /* CHECKING_P */ -- 1.8.5.3