On Sun, Nov 1, 2026 at 1:48 AM Torbjorn SVENSSON <[email protected]> wrote: > > Hi, > > The new test is failing for MVE enabled targets on arm-none-eabi. > > These are the errors produced for > thumb/arch=armv8.1-m.main+mve.fp+fp.dp/cpu=cortex-m55/float-abi=hard/fpu=auto: > > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c: In function > 'a': > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:10:14: error: > incompatible types when initializing type 'v4sib' {aka '__vector(4) signed > char:4'} using type '__vector(4) int' > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:11:14: error: > incompatible types when initializing type 'v4sib' {aka '__vector(4) signed > char:4'} using type '__vector(4) int' > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:12:3: error: > cannot convert a value of type '__vector(4) signed char' to vector type > '__vector(4) int' which has different size > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c: In function > 'b': > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:17:14: error: > incompatible types when initializing type 'v4sib' {aka '__vector(4) signed > char:4'} using type '__vector(4) int' > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:18:14: error: > incompatible types when initializing type 'v4sib' {aka '__vector(4) signed > char:4'} using type '__vector(4) int' > /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:19:3: error: > cannot convert a value of type '__vector(4) signed char' to vector type > '__vector(4) int' which has different size > > Any idea how to fix?
Yes, the best option is just to have it tested for x86_64/i386 and aarch64. vector_mask is not very portable. > > Kind regards, > Torbjörn > > On 2026-10-25 18:54, Andrea Pinski wrote: > > r17-4001-gbbc2517fe41 added support to combine_comparisons for LT/LE/GT/GE > > but it assumed unsigned boolean types ([0,1]) which is wrong for signed > > boolean types ([0,-1]). For an example, for signed boolean types, > > LT is the same as GT for unsigned boolean types. So this was combining > > incorrectly and getting the incorrect answer. > > This fixes the problem by adding support for signed boolean. Since we > > need to pass in a new argument to combine_comparisons, this updates > > all of the uses of combine_comparisons which makes the patch > > look bigger than it really is. > > > > Bootstrapped and tested on x86_64-linux-gnu with no regressions. > > > > PR tree-optimization/128123 > > > > gcc/ChangeLog: > > > > * fold-const.cc (combine_comparisons): Take new argument, > > inner_truth_type and look to see if it is signed boolean > > and support that for LT/LE/GT/GE. > > (fold_truth_andor_1): Update call to combine_comparisons. > > * fold-const.h (combine_comparisons): Add new argument. > > * gimple-fold.cc (and_comparisons_1): Update call to > > combine_comparisons. > > (or_comparisons_1): Likewise. > > * tree-ssa-ifcombine.cc (ifcombine_ifandif): Likewise. > > * tree-ssa-phiopt.cc (comparison_combine): Likewise. > > * match.pd (`(CMP) OP (CMP)`): Update call to > > combine_comparisons. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/tree-ssa/vect-cmp-cmp-1.c: New test. > > > > Signed-off-by: Andrea Pinski <[email protected]> > > --- > > gcc/fold-const.cc | 54 ++++++++++++++----- > > gcc/fold-const.h | 4 +- > > gcc/gimple-fold.cc | 8 +-- > > gcc/match.pd | 5 +- > > .../gcc.dg/tree-ssa/vect-cmp-cmp-1.c | 34 ++++++++++++ > > gcc/tree-ssa-ifcombine.cc | 15 ++++-- > > gcc/tree-ssa-phiopt.cc | 2 +- > > 7 files changed, 95 insertions(+), 27 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c > > > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > > index 1fc4941b481..047c7dcada4 100644 > > --- a/gcc/fold-const.cc > > +++ b/gcc/fold-const.cc > > @@ -3010,13 +3010,21 @@ inverse_conditions_p (const_tree cond1, const_tree > > cond2) > > > > enum tree_code > > combine_comparisons (enum tree_code code, enum tree_code lcode, > > - enum tree_code rcode, tree truth_type, > > - bool honor_nans, tree *res) > > + enum tree_code rcode, tree truth_type, > > + tree inner_truth_type, > > + bool honor_nans, tree *res) > > { > > enum comparison_code lcompcode = comparison_to_compcode (lcode); > > enum comparison_code rcompcode = comparison_to_compcode (rcode); > > int compcode; > > *res = NULL_TREE; > > + if (TREE_CODE (inner_truth_type) == VECTOR_TYPE) > > + inner_truth_type = TREE_TYPE (inner_truth_type); > > + bool signed_bool = false; > > + if (TYPE_SIGN (inner_truth_type) == SIGNED > > + && (TREE_CODE (inner_truth_type) == BOOLEAN_TYPE > > + || TYPE_PRECISION (inner_truth_type) == 1)) > > + signed_bool = true; > > > > switch (code) > > { > > @@ -3039,24 +3047,40 @@ combine_comparisons (enum tree_code code, enum > > tree_code lcode, > > compcode = ~(lcompcode ^ rcompcode); > > break; > > > > - //`bool0 < bool1` is `!bool0 & bool1` > > + //`bool0 < bool1` is `!bool0 & bool1` for unsigned > > + //`bool0 < bool1` is `bool0 & !bool1` for signed > > case LT_EXPR: > > - compcode = ~lcompcode & rcompcode; > > + if (signed_bool) > > + compcode = lcompcode & ~rcompcode; > > + else > > + compcode = ~lcompcode & rcompcode; > > break; > > > > - //`bool0 > bool1` is `bool0 & !bool1` > > + //`bool0 > bool1` is `bool0 & !bool1` for unsigned > > + //`bool0 > bool1` is `!bool0 & bool1` for signed > > case GT_EXPR: > > - compcode = lcompcode & ~rcompcode; > > + if (signed_bool) > > + compcode = ~lcompcode & rcompcode; > > + else > > + compcode = lcompcode & ~rcompcode; > > break; > > > > - // `bool0 <= bool1` as !bool0 | bool1 > > + // `bool0 <= bool1` as !bool0 | bool1 for unsigned > > + // `bool0 <= bool1` as bool0 | !bool1 for signed > > case LE_EXPR: > > - compcode = ~lcompcode | rcompcode; > > + if (signed_bool) > > + compcode = lcompcode | ~rcompcode; > > + else > > + compcode = ~lcompcode | rcompcode; > > break; > > > > - //`bool0 >= bool1` is `bool0 | !bool1` > > + //`bool0 >= bool1` is `bool0 | !bool1` for unsigned > > + //`bool0 >= bool1` is `bool0 | !bool1` for signed > > case GE_EXPR: > > - compcode = lcompcode | ~rcompcode; > > + if (signed_bool) > > + compcode = ~lcompcode | rcompcode; > > + else > > + compcode = lcompcode | ~rcompcode; > > break; > > > > default: > > @@ -3136,12 +3160,14 @@ tree > > combine_comparisons (location_t loc, > > enum tree_code code, enum tree_code lcode, > > enum tree_code rcode, tree truth_type, > > + tree inner_truth_type, > > tree ll_arg, tree lr_arg) > > { > > bool honor_nans = HONOR_NANS (ll_arg); > > tree_code rescode; > > tree res; > > - rescode = combine_comparisons (code, lcode, rcode, truth_type, > > + rescode = combine_comparisons (code, lcode, rcode, > > + truth_type, inner_truth_type, > > honor_nans, &res); > > if (rescode == ERROR_MARK) > > return NULL_TREE; > > @@ -6504,7 +6530,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code > > code, tree truth_type, > > && operand_equal_p (lr_arg, rr_arg, 0)) > > { > > result = combine_comparisons (loc, code, lcode, rcode, > > - truth_type, ll_arg, lr_arg); > > + truth_type, TREE_TYPE (lhs), > > + ll_arg, lr_arg); > > if (result) > > return result; > > } > > @@ -6513,7 +6540,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code > > code, tree truth_type, > > { > > result = combine_comparisons (loc, code, lcode, > > swap_tree_comparison (rcode), > > - truth_type, ll_arg, lr_arg); > > + truth_type, TREE_TYPE (lhs), > > + ll_arg, lr_arg); > > if (result) > > return result; > > } > > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > > index 437d8ece021..4e640de725f 100644 > > --- a/gcc/fold-const.h > > +++ b/gcc/fold-const.h > > @@ -180,9 +180,9 @@ extern bool fold_cmp_float_cst_p (const wide_int &lo, > > const wide_int &hi, > > const wide_int &i, signop isign); > > > > extern tree combine_comparisons (location_t, enum tree_code, enum > > tree_code, > > - enum tree_code, tree, tree, tree); > > + enum tree_code, tree, tree, tree, tree); > > extern tree_code combine_comparisons (enum tree_code, enum tree_code, > > - enum tree_code, tree, bool, tree*); > > + enum tree_code, tree, tree, bool, > > tree*); > > extern void debug_fold_checksum (const_tree); > > extern bool may_negate_without_overflow_p (const_tree); > > #define round_up(T,N) round_up_loc (UNKNOWN_LOCATION, T, N) > > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc > > index e0197edece6..ed84dab7f37 100644 > > --- a/gcc/gimple-fold.cc > > +++ b/gcc/gimple-fold.cc > > @@ -7602,7 +7602,7 @@ and_comparisons_1 (tree type, enum tree_code code1, > > tree op1a, tree op1b, > > /* Result will be either NULL_TREE, or a combined comparison. */ > > tree t = combine_comparisons (UNKNOWN_LOCATION, > > TRUTH_ANDIF_EXPR, code1, code2, > > - truth_type, op1a, op1b); > > + truth_type, truth_type, op1a, op1b); > > if (t) > > return t; > > } > > @@ -7615,7 +7615,7 @@ and_comparisons_1 (tree type, enum tree_code code1, > > tree op1a, tree op1b, > > tree t = combine_comparisons (UNKNOWN_LOCATION, > > TRUTH_ANDIF_EXPR, code1, > > swap_tree_comparison (code2), > > - truth_type, op1a, op1b); > > + truth_type, truth_type, op1a, op1b); > > if (t) > > return t; > > } > > @@ -9574,7 +9574,7 @@ or_comparisons_1 (tree type, enum tree_code code1, > > tree op1a, tree op1b, > > /* Result will be either NULL_TREE, or a combined comparison. */ > > tree t = combine_comparisons (UNKNOWN_LOCATION, > > TRUTH_ORIF_EXPR, code1, code2, > > - truth_type, op1a, op1b); > > + truth_type, truth_type, op1a, op1b); > > if (t) > > return t; > > } > > @@ -9587,7 +9587,7 @@ or_comparisons_1 (tree type, enum tree_code code1, > > tree op1a, tree op1b, > > tree t = combine_comparisons (UNKNOWN_LOCATION, > > TRUTH_ORIF_EXPR, code1, > > swap_tree_comparison (code2), > > - truth_type, op1a, op1b); > > + truth_type, truth_type, op1a, op1b); > > if (t) > > return t; > > } > > diff --git a/gcc/match.pd b/gcc/match.pd > > index 696e69fd980..02941a7dacf 100644 > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -3771,14 +3771,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > (for cmp1 (tcc_comparison) > > (for cmp2 (tcc_comparison) > > (simplify > > - (bitop (cmp1 @0 @1) (cmp2 @0 @1)) > > + (bitop (cmp1@2 @0 @1) (cmp2 @0 @1)) > > (with rescmpcode (tcc_comparison) > > { > > tree_code rescmpcode; > > tree res; > > bool honor_nans = HONOR_NANS (@0); > > rescmpcode = combine_comparisons (bitop, cmp1, cmp2, > > - type, honor_nans, &res); > > + type, TREE_TYPE (@2), > > + honor_nans, &res); > > } > > (if (rescmpcode == INTEGER_CST) > > { res; } > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c > > b/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c > > new file mode 100644 > > index 00000000000..8ccf94df274 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c > > @@ -0,0 +1,34 @@ > > +/* { dg-do run } */ > > +/* { dg-options "-O -fgimple" } */ > > +/* PR tree-optimization/128123 */ > > + > > +typedef int v4si __attribute__((vector_size (4*sizeof(int)))); > > +typedef v4si v4sib __attribute__((vector_mask)); > > + > > +__attribute__((noipa)) void a(v4si *x, v4si *y, v4si *res) > > +{ > > + v4sib m1 = *x < *y; > > + v4sib m2 = *x > *y; > > + *res = (v4si) (m1 < m2); > > +} > > + > > +__attribute__((noipa)) void b(v4si *x, v4si *y, v4si *res) > > +{ > > + v4sib m1 = *x < *y; > > + v4sib m2 = *x > *y; > > + *res = (v4si) (m1 <= m2); > > +} > > + > > +int main (void) > > +{ > > + v4si x = { 1, 2, 3, 4 }, y = { 2, 2, 2, 5 }; > > + v4si r; > > + a(&x, &y, &r); > > + v4si s; > > + b(&x, &y, &s); > > + for (int i = 0; i < 4; i++) > > + if (r[i] != -(x[i] < y[i]) || s[i] != -(x[i] <= y[i])) > > + __builtin_abort(); > > + return 0; > > +} > > + > > diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc > > index 28bb5bf0998..0d663f4130b 100644 > > --- a/gcc/tree-ssa-ifcombine.cc > > +++ b/gcc/tree-ssa-ifcombine.cc > > @@ -865,14 +865,16 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool > > inner_inv, > > if (!inner_inv && !outer_inv) > > res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ANDIF_EXPR, > > outer_cond_code, inner_cond_code, > > - boolean_type_node, larg, rarg); > > + boolean_type_node, boolean_type_node, > > + larg, rarg); > > // If both are inverse, `!a && !b`, then handle it as `!(a || b)` > > // As that !a or !b are most likely not producing a comparison code. > > else if (inner_inv && outer_inv) > > { > > res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR, > > outer_cond_code, inner_cond_code, > > - boolean_type_node, larg, rarg); > > + boolean_type_node, boolean_type_node, > > + larg, rarg); > > if (res) > > res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res); > > } > > @@ -891,7 +893,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool > > inner_inv, > > if (inner_cond_code1 != ERROR_MARK && outer_cond_code1 != > > ERROR_MARK) > > res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ANDIF_EXPR, > > outer_cond_code1, inner_cond_code1, > > - boolean_type_node, larg, rarg); > > + boolean_type_node, boolean_type_node, > > + larg, rarg); > > // Otherwise, we need to try `!(!a || b) > > else if (inner_cond_code1 == ERROR_MARK) > > { > > @@ -901,7 +904,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool > > inner_inv, > > if (outer_cond_code1 != ERROR_MARK) > > res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR, > > outer_cond_code1, inner_cond_code, > > - boolean_type_node, larg, rarg); > > + boolean_type_node, > > boolean_type_node, > > + larg, rarg); > > if (res) > > res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res); > > } > > @@ -914,7 +918,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool > > inner_inv, > > if (inner_cond_code1 != ERROR_MARK) > > res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR, > > outer_cond_code, inner_cond_code1, > > - boolean_type_node, larg, rarg); > > + boolean_type_node, > > boolean_type_node, > > + larg, rarg); > > if (res) > > res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res); > > } > > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc > > index 08b40897a60..51553484226 100644 > > --- a/gcc/tree-ssa-phiopt.cc > > +++ b/gcc/tree-ssa-phiopt.cc > > @@ -1651,7 +1651,7 @@ comparison_combine (basic_block cond_bb, basic_block > > middle_bb, > > tree result; > > tree_code newcmp_code; > > newcmp_code = combine_comparisons (logical, outer_code, inner_code, > > - boolean_type_node, > > + boolean_type_node, boolean_type_node, > > HONOR_NANS (larg), &result); > > if (newcmp_code == ERROR_MARK) > > return false; >
