aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2024-06-06 09:19:53 +0800
committerPan Li <pan2.li@intel.com>2024-06-07 06:56:28 +0800
commite14afbe2d1c696cc4abda24ca10a5a43ee9c2818 (patch)
tree3c374318b4fcebb61b82e145ad00f13992eac370 /libcpp
parentd5a3c6d43acb8b2211d9fb59d59482d74c010f01 (diff)
downloadgcc-e14afbe2d1c696cc4abda24ca10a5a43ee9c2818.zip
gcc-e14afbe2d1c696cc4abda24ca10a5a43ee9c2818.tar.gz
gcc-e14afbe2d1c696cc4abda24ca10a5a43ee9c2818.tar.bz2
Match: Support more form for scalar unsigned SAT_ADD
After we support one gassign form of the unsigned .SAT_ADD, we would like to support more forms including both the branch and branchless. There are 5 other forms of .SAT_ADD, list as below: Form 1: #define SAT_ADD_U_1(T) \ T sat_add_u_1_##T(T x, T y) \ { \ return (T)(x + y) >= x ? (x + y) : -1; \ } Form 2: #define SAT_ADD_U_2(T) \ T sat_add_u_2_##T(T x, T y) \ { \ T ret; \ T overflow = __builtin_add_overflow (x, y, &ret); \ return (T)(-overflow) | ret; \ } Form 3: #define SAT_ADD_U_3(T) \ T sat_add_u_3_##T (T x, T y) \ { \ T ret; \ return __builtin_add_overflow (x, y, &ret) ? -1 : ret; \ } Form 4: #define SAT_ADD_U_4(T) \ T sat_add_u_4_##T (T x, T y) \ { \ T ret; \ return __builtin_add_overflow (x, y, &ret) == 0 ? ret : -1; \ } Form 5: #define SAT_ADD_U_5(T) \ T sat_add_u_5_##T(T x, T y) \ { \ return (T)(x + y) < x ? -1 : (x + y); \ } Take the forms 3 of above as example: uint64_t sat_add (uint64_t x, uint64_t y) { uint64_t ret; return __builtin_add_overflow (x, y, &ret) ? -1 : ret; } Before this patch: uint64_t sat_add (uint64_t x, uint64_t y) { long unsigned int _1; long unsigned int _2; uint64_t _3; __complex__ long unsigned int _6; ;; basic block 2, loop depth 0 ;; pred: ENTRY _6 = .ADD_OVERFLOW (x_4(D), y_5(D)); _2 = IMAGPART_EXPR <_6>; if (_2 != 0) goto <bb 4>; [35.00%] else goto <bb 3>; [65.00%] ;; succ: 4 ;; 3 ;; basic block 3, loop depth 0 ;; pred: 2 _1 = REALPART_EXPR <_6>; ;; succ: 4 ;; basic block 4, loop depth 0 ;; pred: 3 ;; 2 # _3 = PHI <_1(3), 18446744073709551615(2)> return _3; ;; succ: EXIT } After this patch: uint64_t sat_add (uint64_t x, uint64_t y) { long unsigned int _12; ;; basic block 2, loop depth 0 ;; pred: ENTRY _12 = .SAT_ADD (x_4(D), y_5(D)); [tail call] return _12; ;; succ: EXIT } The flag '^' acts on cond_expr will generate matching code similar as below: else if (gphi *_a1 = dyn_cast <gphi *> (_d1)) { basic_block _b1 = gimple_bb (_a1); if (gimple_phi_num_args (_a1) == 2) { basic_block _pb_0_1 = EDGE_PRED (_b1, 0)->src; basic_block _pb_1_1 = EDGE_PRED (_b1, 1)->src; basic_block _db_1 = safe_dyn_cast <gcond *> (*gsi_last_bb (_pb_0_1)) ? _pb_0_1 : _pb_1_1; basic_block _other_db_1 = safe_dyn_cast <gcond *> (*gsi_last_bb (_pb_0_1)) ? _pb_1_1 : _pb_0_1; gcond *_ct_1 = safe_dyn_cast <gcond *> (*gsi_last_bb (_db_1)); if (_ct_1 && EDGE_COUNT (_other_db_1->preds) == 1 && EDGE_COUNT (_other_db_1->succs) == 1 && EDGE_PRED (_other_db_1, 0)->src == _db_1) { tree _cond_lhs_1 = gimple_cond_lhs (_ct_1); tree _cond_rhs_1 = gimple_cond_rhs (_ct_1); tree _p0 = build2 (gimple_cond_code (_ct_1), boolean_type_node, _cond_lhs_1, _cond_rhs_1); bool _arg_0_is_true_1 = gimple_phi_arg_edge (_a1, 0)->flags & EDGE_TRUE_VALUE; tree _p1 = gimple_phi_arg_def (_a1, _arg_0_is_true_1 ? 0 : 1); tree _p2 = gimple_phi_arg_def (_a1, _arg_0_is_true_1 ? 1 : 0); .... The below test suites are passed for this patch. * The x86 bootstrap test. * The x86 fully regression test. * The riscv fully regression test. gcc/ChangeLog: * doc/match-and-simplify.texi: Add doc for the matching flag '^'. * genmatch.cc (cmp_operand): Add match_phi comparation. (dt_node::gen_kids_1): Add cond_expr bool flag for phi match. (dt_operand::gen_phi_on_cond): Add new func to gen phi matching on cond_expr. (parser::parse_expr): Add handling for the expr flag '^'. * match.pd: Add more form for unsigned .SAT_ADD. * tree-ssa-math-opts.cc (build_saturation_binary_arith_call): Add new func impl to build call for phi gimple. (match_unsigned_saturation_add): Add new func impl to match the .SAT_ADD for phi gimple. (math_opts_dom_walker::after_dom_children): Add phi matching try for all gimple phi stmt. Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'libcpp')
0 files changed, 0 insertions, 0 deletions