[llvm] [InstCombine] Fold zext(sub(0, trunc(X))) to and(sub(0, X), mask) (PR #207564)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 5 02:16:40 PDT 2026


def3r wrote:

Regarding the concern about `canEvaluateZExt` to match this pattern, as discussed in #167101, I tried updating the condition to `(DestTy->isVectorTy() || shouldChangeType(SrcTy, DestTy))` (as used in `visitTrunc`) to see if that could work.

<details>
<summary>
On X86 target these were the test failures:
</summary>

```llvm
define <2 x i64> @test46vec(<2 x i64> %A) {
; ALL-LABEL: @test46vec(
; ALL-NEXT:    [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
; ALL-NEXT:    [[C:%.*]] = shl <2 x i32> [[B]], splat (i32 8)
; ALL-NEXT:    [[D:%.*]] = and <2 x i32> [[C]], splat (i32 10752)
; ALL-NEXT:    [[E:%.*]] = zext nneg <2 x i32> [[D]] to <2 x i64>
; ALL-NEXT:    ret <2 x i64> [[E]]
;
  %B = trunc <2 x i64> %A to <2 x i32>
  %C = and <2 x i32> %B, <i32 42, i32 42>
  %D = shl <2 x i32> %C, <i32 8, i32 8>
  %E = zext <2 x i32> %D to <2 x i64>
  ret <2 x i64> %E
}
=>
define <2 x i64> @test46vec(<2 x i64> %A) {
  %C = shl <2 x i64> %A, splat (i64 8)
  %D = and <2 x i64> %C, splat (i64 10752)
  ret <2 x i64> %D
}

define <2 x i64> @zext_less_casting_with_wideop(<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: @zext_less_casting_with_wideop(
; CHECK-NEXT:    [[XNARROW:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32>
; CHECK-NEXT:    [[YNARROW:%.*]] = trunc <2 x i64> [[Y:%.*]] to <2 x i32>
; CHECK-NEXT:    [[MUL:%.*]] = mul <2 x i32> [[XNARROW]], [[YNARROW]]
; CHECK-NEXT:    [[R:%.*]] = zext <2 x i32> [[MUL]] to <2 x i64>
; CHECK-NEXT:    ret <2 x i64> [[R]]
;
  %xnarrow = trunc <2 x i64> %x to <2 x i32>
  %ynarrow = trunc <2 x i64> %y to <2 x i32>
  %mul = mul <2 x i32> %xnarrow, %ynarrow
  %r = zext <2 x i32> %mul to <2 x i64>
  ret <2 x i64> %r
}
=>
define <2 x i64> @zext_less_casting_with_wideop(<2 x i64> %x, <2 x i64> %y) {
  %mul = mul <2 x i64> %x, %y
  %r = and <2 x i64> %mul, splat (i64 4294967295)
  ret <2 x i64> %r
}
```
</details>

So i decided not to implement it as a part of `canEvaluateZExt`.

Should this be then done in VectorCombine or is the cur impl fine?

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


More information about the llvm-commits mailing list