[llvm] [LV] Directly emit predicated select for reduction in VPlan. (PR #201740)

Elvis Wang via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 01:14:07 PDT 2026


================
@@ -22,13 +22,14 @@ define i32 @mla_i32(ptr noalias nocapture readonly %A, ptr noalias nocapture rea
 ; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <16 x i1> @llvm.get.active.lane.mask.v16i1.i32(i32 [[INDEX]], i32 [[N]])
 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 [[INDEX]]
 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <16 x i8> @llvm.masked.load.v16i8.p0(ptr align 1 [[TMP0]], <16 x i1> [[ACTIVE_LANE_MASK]], <16 x i8> poison)
+; CHECK-NEXT:    [[TMP1:%.*]] = select <16 x i1> [[ACTIVE_LANE_MASK]], <16 x i8> [[WIDE_MASKED_LOAD]], <16 x i8> zeroinitializer
 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[B:%.*]], i32 [[INDEX]]
 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <16 x i8> @llvm.masked.load.v16i8.p0(ptr align 1 [[TMP2]], <16 x i1> [[ACTIVE_LANE_MASK]], <16 x i8> poison)
-; CHECK-NEXT:    [[TMP4:%.*]] = sext <16 x i8> [[WIDE_MASKED_LOAD1]] to <16 x i32>
-; CHECK-NEXT:    [[TMP5:%.*]] = sext <16 x i8> [[WIDE_MASKED_LOAD]] to <16 x i32>
+; CHECK-NEXT:    [[TMP3:%.*]] = select <16 x i1> [[ACTIVE_LANE_MASK]], <16 x i8> [[WIDE_MASKED_LOAD1]], <16 x i8> zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = sext <16 x i8> [[TMP3]] to <16 x i32>
+; CHECK-NEXT:    [[TMP5:%.*]] = sext <16 x i8> [[TMP1]] to <16 x i32>
 ; CHECK-NEXT:    [[TMP6:%.*]] = mul nsw <16 x i32> [[TMP4]], [[TMP5]]
-; CHECK-NEXT:    [[TMP7:%.*]] = select <16 x i1> [[ACTIVE_LANE_MASK]], <16 x i32> [[TMP6]], <16 x i32> zeroinitializer
-; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP7]])
+; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> [[TMP6]])
----------------
ElvisWang123 wrote:

Yes currently DAG combine handle this pattern (`partial.reduce.add(sel(%mask, mul(ext(a), ext(b)), 0))`) quite well. But hoist the select out in the backend is hard to estimate and maintain the cost model in LV.

I updated patch that only predicate  the first operand of `sdot` .  ([27feaf7](https://github.com/llvm/llvm-project/pull/201740/commits/27feaf7c5ca20d3da1eb38e10ba85c10c018bc2c))
This can fix the issue of the potential regression.
 The last example in https://godbolt.org/z/Yb51P1Mzx. now has similar code gen with the previous example.
The IR after LV will look like 
```
%la = masked.load 
%lb = masked.load
%sel = select %mask, %lb, zeroinitializer
%fre = freeze %lb
%exta = zext %fre
%extb = zext %sel
%mul = mul %exta, %extb
%red = partial.reduce.add(%red.phi, %mul)
```

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


More information about the llvm-commits mailing list