llvm/test/Transforms/Reassociate/mulfactor.ll
Chandler Carruth 464bda3a16 Teach the reassociate pass to fold chains of multiplies with repeated
elements to minimize the number of multiplies required to compute the
final result. This uses a heuristic to attempt to form near-optimal
binary exponentiation-style multiply chains. While there are some cases
it misses, it seems to at least a decent job on a very diverse range of
inputs.

Initial benchmarks show no interesting regressions, and an 8%
improvement on SPASS. Let me know if any other interesting results (in
either direction) crop up!

Credit to Richard Smith for the core algorithm, and helping code the
patch itself.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155616 91177308-0d34-0410-b5e6-96231b3b80d8
2012-04-26 05:30:30 +00:00

135 lines
2.2 KiB
LLVM

; RUN: opt < %s -reassociate -S | FileCheck %s
define i32 @test1(i32 %a, i32 %b) {
; CHECK: @test1
; CHECK: mul i32 %a, %a
; CHECK-NEXT: mul i32 %a, 2
; CHECK-NEXT: add
; CHECK-NEXT: mul
; CHECK-NEXT: add
; CHECK-NEXT: ret
entry:
%tmp.2 = mul i32 %a, %a
%tmp.5 = shl i32 %a, 1
%tmp.6 = mul i32 %tmp.5, %b
%tmp.10 = mul i32 %b, %b
%tmp.7 = add i32 %tmp.6, %tmp.2
%tmp.11 = add i32 %tmp.7, %tmp.10
ret i32 %tmp.11
}
define i32 @test2(i32 %t) {
; CHECK: @test2
; CHECK: mul
; CHECK-NEXT: add
; CHECK-NEXT: ret
entry:
%a = mul i32 %t, 6
%b = mul i32 %t, 36
%c = add i32 %b, 15
%d = add i32 %c, %a
ret i32 %d
}
define i32 @test3(i32 %x) {
; (x^8)
; CHECK: @test3
; CHECK: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: ret
entry:
%a = mul i32 %x, %x
%b = mul i32 %a, %x
%c = mul i32 %b, %x
%d = mul i32 %c, %x
%e = mul i32 %d, %x
%f = mul i32 %e, %x
%g = mul i32 %f, %x
ret i32 %g
}
define i32 @test4(i32 %x) {
; (x^7)
; CHECK: @test4
; CHECK: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: ret
entry:
%a = mul i32 %x, %x
%b = mul i32 %a, %x
%c = mul i32 %b, %x
%d = mul i32 %c, %x
%e = mul i32 %d, %x
%f = mul i32 %e, %x
ret i32 %f
}
define i32 @test5(i32 %x, i32 %y) {
; (x^4) * (y^2)
; CHECK: @test5
; CHECK: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: ret
entry:
%a = mul i32 %x, %y
%b = mul i32 %a, %y
%c = mul i32 %b, %x
%d = mul i32 %c, %x
%e = mul i32 %d, %x
ret i32 %e
}
define i32 @test6(i32 %x, i32 %y, i32 %z) {
; (x^5) * (y^3) * z
; CHECK: @test6
; CHECK: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: ret
entry:
%a = mul i32 %x, %y
%b = mul i32 %a, %x
%c = mul i32 %b, %y
%d = mul i32 %c, %x
%e = mul i32 %d, %y
%f = mul i32 %e, %x
%g = mul i32 %f, %z
%h = mul i32 %g, %x
ret i32 %h
}
define i32 @test7(i32 %x, i32 %y, i32 %z) {
; (x^4) * (y^3) * (z^2)
; CHECK: @test7
; CHECK: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: mul
; CHECK-NEXT: ret
entry:
%a = mul i32 %y, %x
%b = mul i32 %a, %z
%c = mul i32 %b, %z
%d = mul i32 %c, %x
%e = mul i32 %d, %y
%f = mul i32 %e, %y
%g = mul i32 %f, %x
%h = mul i32 %g, %x
ret i32 %h
}