[llvm] [InstCombine] Fold `(trunc X)` into `X & Mask` inside `decomposeBitTestICmp` (PR #171195)

Tirthankar Mazumder via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 15 10:07:34 PST 2025


================
@@ -314,15 +314,10 @@ define i1 @sgt_n1_use(i32 %x) {
 }
 
 define i1 @trunc_eq_i32_i8(i32 %x) {
-; DL64-LABEL: @trunc_eq_i32_i8(
-; DL64-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 255
-; DL64-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 42
-; DL64-NEXT:    ret i1 [[R]]
-;
-; DL8-LABEL: @trunc_eq_i32_i8(
-; DL8-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
-; DL8-NEXT:    [[R:%.*]] = icmp eq i8 [[T]], 42
-; DL8-NEXT:    ret i1 [[R]]
+; CHECK-LABEL: @trunc_eq_i32_i8(
----------------
wermos wrote:

I understand.

The problem now is that the `shouldChangeType` guard is preventing the optimization from firing and is also causing regressions in other test files (i.e., truncs which were getting folded into `(X & Mask) == C` now are staying as truncs because `shouldChangeType` is deciding that the value should not be lifted to a wider int type.)

This is a bit of a tricky situation. I think we should go back to implementing the transform in `foldAndOrOfICmps` because the parent issue is fundamentally about two `icmp`s, one of which also involves a trunc, implying something about the original variable.

I think I should leave `foldICmpWithTrunc` as it is because the way I understand it, that function is about converting a trunc into a mask + eq when that is valid. But like I said in the previous paragraph, both `icmp`s are required in the parent issue's IR to make the transform valid.

https://github.com/llvm/llvm-project/pull/171195


More information about the llvm-commits mailing list