Missed optimization: Eliminate redundant scalar multiplication by reusing vector multiplication results
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
```llvm
define i1 @src(ptr %arg0, ptr %arg1) {
%v0 = load <2 x float>, ptr %arg1, align 4
%v1 = getelementptr inbounds nuw i8, ptr %arg1, i64 8
%v2 = load float, ptr %v1, align 4
%v3 = load <2 x float>, ptr %arg0, align 4
%v4 = getelementptr inbounds nuw i8, ptr %arg0, i64 8
%v5 = load float, ptr %v4, align 4
%v6 = fmul <2 x float> %v0, %v3
%v7 = extractelement <2 x float> %v6, i64 0
%v8 = extractelement <2 x float> %v0, i64 1
%v9 = extractelement <2 x float> %v3, i64 1
%v10 = fmul float %v8, %v9
%v11 = fadd float %v7, %v10
%v12 = fmul float %v2, %v5
%v13 = fadd float %v12, %v11
%v14 = fcmp olt float %v13, 0.000000e+00
ret i1 %v14
}
define i1 @tgt(ptr %arg0, ptr %arg1) {
%v0 = load <2 x float>, ptr %arg1, align 4
%v1 = getelementptr inbounds nuw i8, ptr %arg1, i64 8
%v2 = load float, ptr %v1, align 4
%v3 = load <2 x float>, ptr %arg0, align 4
%v4 = getelementptr inbounds nuw i8, ptr %arg0, i64 8
%v5 = load float, ptr %v4, align 4
%v6 = fmul <2 x float> %v0, %v3
%v7 = extractelement <2 x float> %v6, i64 0
%v8 = extractelement <2 x float> %v6, i64 1
%v9 = fadd float %v7, %v8
%v10 = fmul float %v2, %v5
%v11 = fadd float %v10, %v9
%v12 = fcmp olt float %v11, 0.000000e+00
ret i1 %v12
}
```
alive2: available in alive2 when timeout limit = 50000
```
----------------------------------------
define i1 @src(ptr %arg0, ptr %arg1) {
#0:
%v0 = load <2 x float>, ptr %arg1, align 4
%v1 = gep inbounds nuw ptr %arg1, 1 x i64 8
%v2 = load float, ptr %v1, align 4
%v3 = load <2 x float>, ptr %arg0, align 4
%v4 = gep inbounds nuw ptr %arg0, 1 x i64 8
%v5 = load float, ptr %v4, align 4
%v6 = fmul <2 x float> %v0, %v3
%v7 = extractelement <2 x float> %v6, i64 0
%v8 = extractelement <2 x float> %v0, i64 1
%v9 = extractelement <2 x float> %v3, i64 1
%v10 = fmul float %v8, %v9
%v11 = fadd float %v7, %v10
%v12 = fmul float %v2, %v5
%v13 = fadd float %v12, %v11
%v14 = fcmp olt float %v13, 0.000000
ret i1 %v14
}
=>
define i1 @tgt(ptr %arg0, ptr %arg1) {
#0:
%v0 = load <2 x float>, ptr %arg1, align 4
%v1 = gep inbounds nuw ptr %arg1, 1 x i64 8
%v2 = load float, ptr %v1, align 4
%v3 = load <2 x float>, ptr %arg0, align 4
%v4 = gep inbounds nuw ptr %arg0, 1 x i64 8
%v5 = load float, ptr %v4, align 4
%v6 = fmul <2 x float> %v0, %v3
%v7 = extractelement <2 x float> %v6, i64 0
%v8 = extractelement <2 x float> %v6, i64 1
%v9 = fadd float %v7, %v8
%v10 = fmul float %v2, %v5
%v11 = fadd float %v10, %v9
%v12 = fcmp olt float %v11, 0.000000
ret i1 %v12
}
Transformation seems to be correct!
```
godbolt: https://godbolt.org/z/nTxrcxfbK
Pattern found in: https://github.com/dtcxzyw/llvm-opt-benchmark/blob/main/bench/pbrt-v4/optimized/vecmath.ll
Contributor guide
Assessment
This issue has not been assessed yet.