Hi GCC community, I have a question about pattern matching in match.pd.
So I have a pattern like this [1]: #define CMP != bool f(bool c, int i) { return (c << i) CMP 0; } bool g(bool c, int i) { return c CMP 0;} It is verifiably correct to transfer f to g [2]. Although this pattern looks simple, but the problem rises because GIMPLE converts booleans to int before "<<" operation. So at the end you have boolean->integer->boolean conversion and the shift will happen on the integer in the middle. For example, for something like: bool g(bool c){return (c << 22);} The GIMPLE is: _Bool g (_Bool c) { int _1; int _2; _Bool _4; <bb 2> [local count: 1073741824]: _1 = (int) c_3(D); _2 = _1 << 22; _4 = _2 != 0; return _4; } I wrote a patch to fix this problem in match.pd: +(match boolean_valued_p + @0 + (if (TREE_CODE (type) == BOOLEAN_TYPE + && TYPE_PRECISION (type) == 1))) +(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor) + (match boolean_valued_p + (op @0 @1))) +(match boolean_valued_p + (truth_not @0)) +/* cmp : ==, != */ +/* ((B0 << x) cmp 0) -> B0 cmp 0 */ +(for cmp (eq ne) + (simplify + (cmp (lshift (convert@3 boolean_valued_p@0) @1) integer_zerop@2) + (if (TREE_CODE (TREE_TYPE (@3)) == INTEGER_TYPE + && (GIMPLE || !TREE_SIDE_EFFECTS (@1))) + (cmp @0 @2)))) But the problem is I am not able to restrict to the cases I am interested in. There are many hits in other libraries I have tried compiling with trunk+patch. Any feedback? 1) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98956 2) https://alive2.llvm.org/ce/z/UUTJ_v Best wishes, Navid.