[llvm] [LV] Improve AnyOf reduction codegen. (PR #78304)
Mel Chen via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 02:11:56 PST 2024
================
@@ -8,13 +8,12 @@ target triple = "aarch64-linux-gnu"
define i32 @select_const_i32_from_icmp(ptr nocapture readonly %v, i64 %n) #0 {
; CHECK-VF4IC1-LABEL: @select_const_i32_from_icmp
; CHECK-VF4IC1: vector.body:
-; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <vscale x 4 x i32> [ shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 3, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer), %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ]
+; CHECK-VF4IC1: [[VEC_PHI:%.*]] = phi <vscale x 4 x i1> [ zeroinitializer, %vector.ph ], [ [[VEC_SEL:%.*]], %vector.body ]
; CHECK-VF4IC1: [[VEC_LOAD:%.*]] = load <vscale x 4 x i32>
; CHECK-VF4IC1-NEXT: [[VEC_ICMP:%.*]] = icmp eq <vscale x 4 x i32> [[VEC_LOAD]], shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 3, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer)
-; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = select <vscale x 4 x i1> [[VEC_ICMP]], <vscale x 4 x i32> [[VEC_PHI]], <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 7, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer)
+; CHECK-VF4IC1-NEXT: [[VEC_SEL]] = or <vscale x 4 x i1> [[VEC_PHI]], [[VEC_ICMP]]
; CHECK-VF4IC1: middle.block:
-; CHECK-VF4IC1-NEXT: [[FIN_ICMP:%.*]] = icmp ne <vscale x 4 x i32> [[VEC_SEL]], shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 3, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer)
-; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.nxv4i1(<vscale x 4 x i1> [[FIN_ICMP]])
+; CHECK-VF4IC1-NEXT: [[OR_RDX:%.*]] = call i1 @llvm.vector.reduce.or.nxv4i1(<vscale x 4 x i1> [[VEC_SEL]])
; CHECK-VF4IC1-NEXT: {{.*}} = select i1 [[OR_RDX]], i32 7, i32 3
----------------
Mel-Chen wrote:
I'm glad to see someone willing to address this issue. It was also in my task list, so I have some information to share with you, hoping it will be helpful. I've divided the cases of AnyOf into two types:
1. True-side update
```
rdx = <condition> ? <loop-invariant-rhs> : rdx
```
It can be transformed to OR reduction:
```
%vmask = <all-false>
for () {
%pred = <widened-predicate>
%vmask |= %pred
}
%rdx = reduce.or %vmask
%red = select %rdx, <loop-invariant-rhs>, <initial-value>
```
2. False-side update:
```
rdx = <condition> ? rdx : <loop-invariant-rhs>
```
It can be transformed to OR reduction with NOT condition:
```
%vmask = <all-false>
for () {
%pred = <widened-predicate>
%pred.not = (%pred == <all-false>)
%vmask |= %pred.not
}
%rdx = reduce.or %vmask
%red = select %rdx, <loop-invariant-rhs>, <initial-value>
```
Or, to AND reduction:
```
%vmask = <all-true>
for () {
%pred = <widened-predicate>
%vmask &= %pred
}
%rdx = reduce.and %vmask
%red = select %rdx, <initial-value>, <loop-invariant-rhs>
```
Take `@select_const_i32_from_icmp` as an example, this should be the type 2, so there may be bugs with the current transformation.
https://github.com/llvm/llvm-project/pull/78304
More information about the llvm-commits
mailing list