Hello Richard, Thank you for reviewing the patch! I have made changes based on your comments, but I have some doubts for a few comments as mentioned below.
On Thu, 2025-09-11 at 13:08 +0200, Richard Biener wrote: > On Wed, 10 Sep 2025, Avinash Jayakar wrote: > > + bool unsignedp = TYPE_UNSIGNED (itype) && (tree_int_cst_sgn > > (oprnd1) > 0); > > + > > + if (unsignedp) > > + { > > + switch (rhs_code) > > + { > > + case FLOOR_DIV_EXPR: > > + rhs_code = TRUNC_DIV_EXPR; > > + break; > > + case FLOOR_MOD_EXPR: > > + rhs_code = TRUNC_MOD_EXPR; > > + break; > > I would have expected this to be already done on gimple, in > a more generic way by > > /* For unsigned integral types, FLOOR_DIV_EXPR is the same as > TRUNC_DIV_EXPR. Rewrite into the latter in this case. Similarly > for MOD instead of DIV. */ > (for floor_divmod (floor_div floor_mod) > trunc_divmod (trunc_div trunc_mod) > (simplify > (floor_divmod @0 @1) > (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) > && TYPE_UNSIGNED (type)) > (trunc_divmod @0 @1)))) > I think this happens only if types for both operands is of integer type. But in this particular case operand #1 is a constant so I think this rule is not working for that case. bool unsignedp = TYPE_UNSIGNED (itype) && (tree_int_cst_sgn (oprnd1) > 0); This line however checks if operand #1 > 0, the previous checks in this function also makes sure that operand #1 must be a constant, else this pattern returns NULL. > > You are emitting code that might not be vectorizable and which needs > post-processing with bool vector patterns. So you should > > 1) use the appropriate precision scalar bools, anticipating the > vector > mask type used > 2) check at least whether the compares are supported, I think we can > rely on bit operations suppoort I have limited COND_EXPR stmt in the following code to just 1 stmt. Also added checks to see all used operations are supported for the target. I did not understand point 1), would it still be valid if I use only the result of LT_EXPR only as the input for COND_EXPR as in the below code? if (rhs_code == FLOOR_MOD_EXPR) { if (!target_has_vecop_for_code(NEGATE_EXPR, vectype) || !target_has_vecop_for_code(BIT_XOR_EXPR, vectype) || !target_has_vecop_for_code(LT_EXPR, vectype) || !target_has_vecop_for_code(BIT_IOR_EXPR, vectype) || !target_has_vecop_for_code(COND_EXPR, vectype) || !target_has_vecop_for_code(PLUS_EXPR, vectype) ) return NULL; append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt); // r = x %[fl] y; // is // r = x % y; if (r && (x ^ y) < 0) r += y; // Produce following sequence // v0 = x^y // v1 = -r // v2 = r | -r // v3 = v0 & v2 // v4 = v3 < 0 (equivalent to (r && (x ^ y) < 0)) // v5 = v4 ? y : 0 // v6 = r + v5 (final result) tree cond_reg = vect_recog_temp_ssa_var(itype, NULL); def_stmt = gimple_build_assign(cond_reg, BIT_XOR_EXPR, oprnd0, oprnd1); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt); // -r tree negate_r = vect_recog_temp_ssa_var(itype, NULL); def_stmt = gimple_build_assign(negate_r, NEGATE_EXPR, r); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt); // r | -r , sign bit is set if r!=0 tree r_or_negr = vect_recog_temp_ssa_var(itype, NULL); def_stmt = gimple_build_assign(r_or_negr, BIT_IOR_EXPR, r, negate_r); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt); // (x^y) & (r|-r) tree r_or_negr_and_xor = vect_recog_temp_ssa_var(itype, NULL); def_stmt = gimple_build_assign(r_or_negr_and_xor, BIT_AND_EXPR, r_or_negr, cond_reg); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt); // (x^y) & (r|-r) < 0 which is equivalent to (x^y < 0 && r!=0) tree bool_cond = vect_recog_temp_ssa_var(boolean_type_node, NULL); def_stmt = gimple_build_assign(bool_cond, LT_EXPR, r_or_negr_and_xor, build_int_cst(itype, 0)); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt, truth_type_for(vectype), itype); // (x^y < 0 && r) ? y : 0 tree extr_cond = vect_recog_temp_ssa_var(itype, NULL); def_stmt = gimple_build_assign(extr_cond, COND_EXPR, bool_cond, oprnd1, build_int_cst(itype, 0)); append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt); // r += (x ^ y < 0 && r) ? y : 0 tree floor_mod_r = vect_recog_temp_ssa_var(itype, NULL); pattern_stmt = gimple_build_assign(floor_mod_r, PLUS_EXPR, r, extr_cond); } Thanks and regards, Avinash Jayakar