[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