[InstCombine] Fold `switch(zext/sext(X))` into `switch(X)` (#76988)
This patch folds `switch(zext/sext(X))` into `switch(X)`. The original motivation of this patch is to optimize a pattern found in cvc5. For example: ``` %bf.load.i = load i16, ptr %d_kind.i, align 8 %bf.clear.i = and i16 %bf.load.i, 1023 %bf.cast.i = zext nneg i16 %bf.clear.i to i32 switch i32 %bf.cast.i, label %if.else [ i32 335, label %if.then i32 303, label %if.then ] if.then: ; preds = %entry, %entry %d_children.i.i = getelementptr inbounds %"class.cvc5::internal::expr::NodeValue", ptr %0, i64 0, i32 3 %cmp.i.i.i.i.i = icmp eq i16 %bf.clear.i, 1023 %cond.i.i.i.i.i = select i1 %cmp.i.i.i.i.i, i32 -1, i32 %bf.cast.i ``` `%cmp.i.i.i.i.i` always evaluates to false because `%bf.clear.i` can only be 335 or 303. Folding `switch i32 %bf.cast.i` to `switch i16 %bf.clear.i` will help `CVP` to handle this case. See also https://github.com/llvm/llvm-project/pull/76928#issuecomment-1877055722. Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=7954c57124b495fbdc73674d71f2e366e4afe522&to=502b13ed34e561d995ae1f724cf06d20008bd86f&stat=instructions:u |stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang| |--|--|--|--|--|--|--| |+0.03%|+0.06%|+0.07%|+0.00%|-0.02%|-0.03%|+0.02%|
Loading
Please sign in to comment