llvm / llvm/llvm-project

Missed optimization: Eliminate redundant scalar multiplication by reusing vector multiplication results

Open
#185,564 3 comments 0 reactions 0 assignees View on GitHub
llvm:optimizations missed-optimization
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.