Hello. The patch adds a new pass that identifies a series of if-elseif statements and transform then into a GIMPLE switch (if possible). The pass runs right after tree-ssa pass and I decided to implement matching of various forms that are introduced by folder (fold_range_test): 1) if condition with equal operation: : if (argc_8(D) == 1) goto ; [INV] else goto ; [INV] 2) if condition with a range check: : _4 = c_13(D) + 198; if (_4 <= 1) goto ; [INV] else goto ; [INV] 3) mixture of 1) and 2) with a or condition: : _1 = aChar_8(D) == 1; _2 = aChar_8(D) == 10; _3 = _1 | _2; if (_3 != 0) goto ; [INV] else goto ; [INV] or: : aChar.1_1 = (unsigned int) aChar_10(D); _2 = aChar.1_1 + 4294967287; _3 = _2 <= 1; _4 = aChar_10(D) == 12; _5 = _3 | _4; if (_5 != 0) goto ; [INV] else goto ; [INV] The motivation example in PR88702 is transformed now into: IsHTMLWhitespace (int aChar) { int iftmp.0_1; [local count: 1073741824]: switch (aChar_2(D)) [50.00%], case 9 ... 10: [50.00%], case 12 ... 13: [50.00%], case 32: [50.00%]> [local count: 536870913]: : [local count: 1073741824]: # iftmp.0_1 = PHI <1(2), 0(3)> : return iftmp.0_1; } I'm also attaching if-elseif chains that are transformed in make all-host of the GCC compiler. There are ~800 such transformations. The most beautiful transformation is this one: $ cat -n gcc/c-family/c-common.c ... 2895 /* This used to be a switch, but Genix compiler can't handle that. */ 2896 if (code == NE_EXPR) 2897 { 2898 if (max_lt || min_gt) 2899 val = truthvalue_true_node; 2900 } 2901 else if (code == EQ_EXPR) 2902 { 2903 if (max_lt || min_gt) 2904 val = truthvalue_false_node; 2905 } ... Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Thoughts? Thanks, Martin gcc/ChangeLog: 2019-11-04 Martin Liska PR tree-optimization/14799 PR ipa/88702 * Makefile.in: Include new tree-if-to-switch.o. * common.opt: Document -ftree-if-to-switch. * doc/invoke.texi: Likewise. * opts.c: Enable the pass with -O2+. * passes.def: Add ne pass. * timevar.def (TV_TREE_IF_TO_SWITCH): Add new timevar. * tree-if-to-switch.c: New file. * tree-pass.h (make_pass_if_to_switch): New. gcc/testsuite/ChangeLog: 2019-11-04 Martin Liska PR tree-optimization/14799 PR ipa/88702 * gcc.dg/tree-ssa/if-to-switch-1.c: New test. * gcc.dg/tree-ssa/if-to-switch-2.c: New test. * gcc.dg/tree-ssa/if-to-switch-3.c: New test. * gcc.dg/tree-ssa/if-to-switch-4.c: New test. * gcc.dg/tree-ssa/if-to-switch-5.c: New test. * gcc.dg/tree-ssa/reassoc-32.c: Disable tree-if-to-switch in order to transform the range test. * gcc.dg/tree-ssa/reassoc-33.c: Likewise. --- gcc/Makefile.in | 1 + gcc/common.opt | 4 + gcc/doc/invoke.texi | 10 +- gcc/opts.c | 1 + gcc/passes.def | 1 + .../gcc.dg/tree-ssa/if-to-switch-1.c | 35 + .../gcc.dg/tree-ssa/if-to-switch-2.c | 11 + .../gcc.dg/tree-ssa/if-to-switch-3.c | 11 + .../gcc.dg/tree-ssa/if-to-switch-4.c | 35 + .../gcc.dg/tree-ssa/if-to-switch-5.c | 12 + gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/reassoc-33.c | 2 +- gcc/timevar.def | 1 + gcc/tree-if-to-switch.c | 611 ++++++++++++++++++ gcc/tree-pass.h | 1 + 15 files changed, 735 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c create mode 100644 gcc/tree-if-to-switch.c