mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
691f754300
This is an extension of a transform that tries to produce positive floating-point constants to improve canonicalization (and hopefully lead to more reassociation and CSE). The original patches were: D4904 D5363 (rL221721) But as the test diffs show, these were limited to basic patterns by walking from an instruction to its single user rather than recursively moving up the def-use sequence. No fast-math is required here because we're only rearranging implicit FP negations in intermediate ops. A motivating bug is: https://bugs.llvm.org/show_bug.cgi?id=32939 Differential Revision: https://reviews.llvm.org/D65954 llvm-svn: 368512
457 lines
18 KiB
LLVM
457 lines
18 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -reassociate -S | FileCheck %s
|
|
|
|
; Check that a*c+b*c is turned into (a+b)*c
|
|
|
|
define <4 x float> @test1(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = fadd fast <4 x float> [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast <4 x float> [[REASS_ADD]], [[C:%.*]]
|
|
; CHECK-NEXT: ret <4 x float> [[REASS_MUL]]
|
|
;
|
|
%mul = fmul fast <4 x float> %a, %c
|
|
%mul1 = fmul fast <4 x float> %b, %c
|
|
%add = fadd fast <4 x float> %mul, %mul1
|
|
ret <4 x float> %add
|
|
}
|
|
|
|
; Check that a*c+b*c is turned into (a+b)*c - minimum FMF subset version
|
|
|
|
define <4 x float> @test1_reassoc(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
|
|
; CHECK-LABEL: @test1_reassoc(
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc <4 x float> [[A:%.*]], [[C:%.*]]
|
|
; CHECK-NEXT: [[MUL1:%.*]] = fmul reassoc <4 x float> [[B:%.*]], [[C]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc <4 x float> [[MUL]], [[MUL1]]
|
|
; CHECK-NEXT: ret <4 x float> [[ADD]]
|
|
;
|
|
%mul = fmul reassoc <4 x float> %a, %c
|
|
%mul1 = fmul reassoc <4 x float> %b, %c
|
|
%add = fadd reassoc <4 x float> %mul, %mul1
|
|
ret <4 x float> %add
|
|
}
|
|
|
|
; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
|
|
|
|
define <2 x float> @test2(<2 x float> %a, <2 x float> %b, <2 x float> %c) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: [[REASS_ADD1:%.*]] = fadd fast <2 x float> [[C:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL2:%.*]] = fmul fast <2 x float> [[A:%.*]], [[A]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast <2 x float> [[REASS_MUL2]], [[REASS_ADD1]]
|
|
; CHECK-NEXT: ret <2 x float> [[REASS_MUL]]
|
|
;
|
|
%t0 = fmul fast <2 x float> %a, %b
|
|
%t1 = fmul fast <2 x float> %a, %t0
|
|
%t2 = fmul fast <2 x float> %a, %c
|
|
%t3 = fmul fast <2 x float> %a, %t2
|
|
%t4 = fadd fast <2 x float> %t1, %t3
|
|
ret <2 x float> %t4
|
|
}
|
|
|
|
; Check that a*a*b+a*a*c is turned into a*(a*(b+c)) - minimum FMF subset version
|
|
|
|
define <2 x float> @test2_reassoc(<2 x float> %a, <2 x float> %b, <2 x float> %c) {
|
|
; CHECK-LABEL: @test2_reassoc(
|
|
; CHECK-NEXT: [[T0:%.*]] = fmul reassoc <2 x float> [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[T1:%.*]] = fmul reassoc <2 x float> [[A]], [[T0]]
|
|
; CHECK-NEXT: [[T2:%.*]] = fmul reassoc <2 x float> [[A]], [[C:%.*]]
|
|
; CHECK-NEXT: [[T3:%.*]] = fmul reassoc <2 x float> [[A]], [[T2]]
|
|
; CHECK-NEXT: [[T4:%.*]] = fadd reassoc <2 x float> [[T1]], [[T3]]
|
|
; CHECK-NEXT: ret <2 x float> [[T4]]
|
|
;
|
|
%t0 = fmul reassoc <2 x float> %a, %b
|
|
%t1 = fmul reassoc <2 x float> %a, %t0
|
|
%t2 = fmul reassoc <2 x float> %a, %c
|
|
%t3 = fmul reassoc <2 x float> %a, %t2
|
|
%t4 = fadd reassoc <2 x float> %t1, %t3
|
|
ret <2 x float> %t4
|
|
}
|
|
|
|
; Check that a*b+a*c+d is turned into a*(b+c)+d.
|
|
|
|
define <2 x double> @test3(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = fadd fast <2 x double> [[C:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast <2 x double> [[REASS_ADD]], [[A:%.*]]
|
|
; CHECK-NEXT: [[T3:%.*]] = fadd fast <2 x double> [[REASS_MUL]], [[D:%.*]]
|
|
; CHECK-NEXT: ret <2 x double> [[T3]]
|
|
;
|
|
%t0 = fmul fast <2 x double> %a, %b
|
|
%t1 = fmul fast <2 x double> %a, %c
|
|
%t2 = fadd fast <2 x double> %t1, %d
|
|
%t3 = fadd fast <2 x double> %t0, %t2
|
|
ret <2 x double> %t3
|
|
}
|
|
|
|
; Check that a*b+a*c+d is turned into a*(b+c)+d - minimum FMF subset version
|
|
|
|
define <2 x double> @test3_reassoc(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d) {
|
|
; CHECK-LABEL: @test3_reassoc(
|
|
; CHECK-NEXT: [[T0:%.*]] = fmul reassoc <2 x double> [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[T1:%.*]] = fmul reassoc <2 x double> [[A]], [[C:%.*]]
|
|
; CHECK-NEXT: [[T2:%.*]] = fadd reassoc <2 x double> [[T1]], [[D:%.*]]
|
|
; CHECK-NEXT: [[T3:%.*]] = fadd reassoc <2 x double> [[T0]], [[T2]]
|
|
; CHECK-NEXT: ret <2 x double> [[T3]]
|
|
;
|
|
%t0 = fmul reassoc <2 x double> %a, %b
|
|
%t1 = fmul reassoc <2 x double> %a, %c
|
|
%t2 = fadd reassoc <2 x double> %t1, %d
|
|
%t3 = fadd reassoc <2 x double> %t0, %t2
|
|
ret <2 x double> %t3
|
|
}
|
|
|
|
; No fast-math.
|
|
|
|
define <2 x float> @test4(<2 x float> %A) {
|
|
; CHECK-LABEL: @test4(
|
|
; CHECK-NEXT: [[X:%.*]] = fadd <2 x float> [[A:%.*]], <float 1.000000e+00, float 1.000000e+00>
|
|
; CHECK-NEXT: [[Y:%.*]] = fadd <2 x float> [[A]], <float 1.000000e+00, float 1.000000e+00>
|
|
; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[X]], [[Y]]
|
|
; CHECK-NEXT: ret <2 x float> [[R]]
|
|
;
|
|
%X = fadd <2 x float> %A, < float 1.000000e+00, float 1.000000e+00 >
|
|
%Y = fadd <2 x float> %A, < float 1.000000e+00, float 1.000000e+00 >
|
|
%R = fsub <2 x float> %X, %Y
|
|
ret <2 x float> %R
|
|
}
|
|
|
|
; Check 47*X + 47*X -> 94*X.
|
|
|
|
define <2 x float> @test5(<2 x float> %X) {
|
|
; CHECK-LABEL: @test5(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast <2 x float> [[X:%.*]], <float 9.400000e+01, float 9.400000e+01>
|
|
; CHECK-NEXT: ret <2 x float> [[FACTOR]]
|
|
;
|
|
%Y = fmul fast <2 x float> %X, <float 4.700000e+01, float 4.700000e+01>
|
|
%Z = fadd fast <2 x float> %Y, %Y
|
|
ret <2 x float> %Z
|
|
}
|
|
|
|
; Check 47*X + 47*X -> 94*X - minimum FMF subset version
|
|
|
|
define <2 x float> @test5_reassoc(<2 x float> %X) {
|
|
; CHECK-LABEL: @test5_reassoc(
|
|
; CHECK-NEXT: [[Y:%.*]] = fmul reassoc <2 x float> [[X:%.*]], <float 4.700000e+01, float 4.700000e+01>
|
|
; CHECK-NEXT: [[Z:%.*]] = fadd reassoc <2 x float> [[Y]], [[Y]]
|
|
; CHECK-NEXT: ret <2 x float> [[Z]]
|
|
;
|
|
%Y = fmul reassoc <2 x float> %X, <float 4.700000e+01, float 4.700000e+01>
|
|
%Z = fadd reassoc <2 x float> %Y, %Y
|
|
ret <2 x float> %Z
|
|
}
|
|
|
|
; Check X+X+X -> 3*X.
|
|
|
|
define <2 x float> @test6(<2 x float> %X) {
|
|
; CHECK-LABEL: @test6(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast <2 x float> [[X:%.*]], <float 3.000000e+00, float 3.000000e+00>
|
|
; CHECK-NEXT: ret <2 x float> [[FACTOR]]
|
|
;
|
|
%Y = fadd fast <2 x float> %X ,%X
|
|
%Z = fadd fast <2 x float> %Y, %X
|
|
ret <2 x float> %Z
|
|
}
|
|
|
|
; Check X+X+X -> 3*X - minimum FMF subset version
|
|
|
|
define <2 x float> @test6_reassoc(<2 x float> %X) {
|
|
; CHECK-LABEL: @test6_reassoc(
|
|
; CHECK-NEXT: [[Y:%.*]] = fadd reassoc <2 x float> [[X:%.*]], [[X]]
|
|
; CHECK-NEXT: [[Z:%.*]] = fadd reassoc <2 x float> [[X]], [[Y]]
|
|
; CHECK-NEXT: ret <2 x float> [[Z]]
|
|
;
|
|
%Y = fadd reassoc <2 x float> %X ,%X
|
|
%Z = fadd reassoc <2 x float> %Y, %X
|
|
ret <2 x float> %Z
|
|
}
|
|
|
|
; Check 127*W+50*W -> 177*W.
|
|
|
|
define <2 x double> @test7(<2 x double> %W) {
|
|
; CHECK-LABEL: @test7(
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast <2 x double> [[W:%.*]], <double 1.770000e+02, double 1.770000e+02>
|
|
; CHECK-NEXT: ret <2 x double> [[REASS_MUL]]
|
|
;
|
|
%X = fmul fast <2 x double> %W, <double 127.0, double 127.0>
|
|
%Y = fmul fast <2 x double> %W, <double 50.0, double 50.0>
|
|
%Z = fadd fast <2 x double> %Y, %X
|
|
ret <2 x double> %Z
|
|
}
|
|
|
|
; Check 127*W+50*W -> 177*W - minimum FMF subset version
|
|
|
|
define <2 x double> @test7_reassoc(<2 x double> %W) {
|
|
; CHECK-LABEL: @test7_reassoc(
|
|
; CHECK-NEXT: [[X:%.*]] = fmul reassoc <2 x double> [[W:%.*]], <double 1.270000e+02, double 1.270000e+02>
|
|
; CHECK-NEXT: [[Y:%.*]] = fmul reassoc <2 x double> [[W]], <double 5.000000e+01, double 5.000000e+01>
|
|
; CHECK-NEXT: [[Z:%.*]] = fadd reassoc <2 x double> [[Y]], [[X]]
|
|
; CHECK-NEXT: ret <2 x double> [[Z]]
|
|
;
|
|
%X = fmul reassoc <2 x double> %W, <double 127.0, double 127.0>
|
|
%Y = fmul reassoc <2 x double> %W, <double 50.0, double 50.0>
|
|
%Z = fadd reassoc <2 x double> %Y, %X
|
|
ret <2 x double> %Z
|
|
}
|
|
|
|
; Check X*12*12 -> X*144.
|
|
|
|
define <2 x float> @test8(<2 x float> %arg) {
|
|
; CHECK-LABEL: @test8(
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <2 x float> [[ARG:%.*]], <float 1.440000e+02, float 1.440000e+02>
|
|
; CHECK-NEXT: ret <2 x float> [[TMP2]]
|
|
;
|
|
%tmp1 = fmul fast <2 x float> <float 1.200000e+01, float 1.200000e+01>, %arg
|
|
%tmp2 = fmul fast <2 x float> %tmp1, <float 1.200000e+01, float 1.200000e+01>
|
|
ret <2 x float> %tmp2
|
|
}
|
|
|
|
; Check X*12*12 -> X*144 - minimum FMF subset version
|
|
|
|
define <2 x float> @test8_reassoc(<2 x float> %arg) {
|
|
; CHECK-LABEL: @test8_reassoc(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc <2 x float> [[ARG:%.*]], <float 1.200000e+01, float 1.200000e+01>
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc <2 x float> [[TMP1]], <float 1.200000e+01, float 1.200000e+01>
|
|
; CHECK-NEXT: ret <2 x float> [[TMP2]]
|
|
;
|
|
%tmp1 = fmul reassoc <2 x float> <float 1.200000e+01, float 1.200000e+01>, %arg
|
|
%tmp2 = fmul reassoc <2 x float> %tmp1, <float 1.200000e+01, float 1.200000e+01>
|
|
ret <2 x float> %tmp2
|
|
}
|
|
|
|
; Check (b+(a+1234))+-a -> b+1234.
|
|
|
|
define <2 x double> @test9(<2 x double> %b, <2 x double> %a) {
|
|
; CHECK-LABEL: @test9(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <2 x double> zeroinitializer, [[A:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fadd fast <2 x double> [[B:%.*]], <double 1.234000e+03, double 1.234000e+03>
|
|
; CHECK-NEXT: ret <2 x double> [[TMP2]]
|
|
;
|
|
%1 = fadd fast <2 x double> %a, <double 1.234000e+03, double 1.234000e+03>
|
|
%2 = fadd fast <2 x double> %b, %1
|
|
%3 = fsub fast <2 x double> <double 0.000000e+00, double 0.000000e+00>, %a
|
|
%4 = fadd fast <2 x double> %2, %3
|
|
ret <2 x double> %4
|
|
}
|
|
|
|
define <2 x double> @test9_unary_fneg(<2 x double> %b, <2 x double> %a) {
|
|
; CHECK-LABEL: @test9_unary_fneg(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg fast <2 x double> [[A:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fadd fast <2 x double> [[B:%.*]], <double 1.234000e+03, double 1.234000e+03>
|
|
; CHECK-NEXT: ret <2 x double> [[TMP2]]
|
|
;
|
|
%1 = fadd fast <2 x double> %a, <double 1.234000e+03, double 1.234000e+03>
|
|
%2 = fadd fast <2 x double> %b, %1
|
|
%3 = fneg fast <2 x double> %a
|
|
%4 = fadd fast <2 x double> %2, %3
|
|
ret <2 x double> %4
|
|
}
|
|
|
|
; Check (b+(a+1234))+-a -> b+1234 - minimum FMF subset version
|
|
|
|
define <2 x double> @test9_reassoc(<2 x double> %b, <2 x double> %a) {
|
|
; CHECK-LABEL: @test9_reassoc(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc <2 x double> [[A:%.*]], <double 1.234000e+03, double 1.234000e+03>
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fadd reassoc <2 x double> [[B:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fsub reassoc <2 x double> zeroinitializer, [[A]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fadd reassoc <2 x double> [[TMP3]], [[TMP2]]
|
|
; CHECK-NEXT: ret <2 x double> [[TMP4]]
|
|
;
|
|
%1 = fadd reassoc <2 x double> %a, <double 1.234000e+03, double 1.234000e+03>
|
|
%2 = fadd reassoc <2 x double> %b, %1
|
|
%3 = fsub reassoc <2 x double> <double 0.000000e+00, double 0.000000e+00>, %a
|
|
%4 = fadd reassoc <2 x double> %2, %3
|
|
ret <2 x double> %4
|
|
}
|
|
|
|
define <2 x double> @test9_reassoc_unary_fneg(<2 x double> %b, <2 x double> %a) {
|
|
; CHECK-LABEL: @test9_reassoc_unary_fneg(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc <2 x double> [[A:%.*]], <double 1.234000e+03, double 1.234000e+03>
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fadd reassoc <2 x double> [[B:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fneg reassoc <2 x double> [[A]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fadd reassoc <2 x double> [[TMP3]], [[TMP2]]
|
|
; CHECK-NEXT: ret <2 x double> [[TMP4]]
|
|
;
|
|
%1 = fadd reassoc <2 x double> %a, <double 1.234000e+03, double 1.234000e+03>
|
|
%2 = fadd reassoc <2 x double> %b, %1
|
|
%3 = fneg reassoc <2 x double> %a
|
|
%4 = fadd reassoc <2 x double> %2, %3
|
|
ret <2 x double> %4
|
|
}
|
|
|
|
; Check -(-(z*40)*a) -> a*40*z.
|
|
|
|
define <2 x float> @test10(<2 x float> %a, <2 x float> %b, <2 x float> %z) {
|
|
; CHECK-LABEL: @test10(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <2 x float> zeroinitializer, zeroinitializer
|
|
; CHECK-NEXT: [[C:%.*]] = fmul fast <2 x float> [[A:%.*]], <float 4.000000e+01, float 4.000000e+01>
|
|
; CHECK-NEXT: [[E:%.*]] = fmul fast <2 x float> [[C]], [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fadd fast <2 x float> [[E]], zeroinitializer
|
|
; CHECK-NEXT: ret <2 x float> [[TMP2]]
|
|
;
|
|
%d = fmul fast <2 x float> %z, <float 4.000000e+01, float 4.000000e+01>
|
|
%c = fsub fast <2 x float> <float 0.000000e+00, float 0.000000e+00>, %d
|
|
%e = fmul fast <2 x float> %a, %c
|
|
%f = fsub fast <2 x float> <float 0.000000e+00, float 0.000000e+00>, %e
|
|
ret <2 x float> %f
|
|
}
|
|
|
|
define <2 x float> @test10_unary_fneg(<2 x float> %a, <2 x float> %b, <2 x float> %z) {
|
|
; CHECK-LABEL: @test10_unary_fneg(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fneg fast <2 x float> zeroinitializer
|
|
; CHECK-NEXT: [[E:%.*]] = fmul fast <2 x float> [[A:%.*]], <float 4.000000e+01, float 4.000000e+01>
|
|
; CHECK-NEXT: [[F:%.*]] = fmul fast <2 x float> [[E]], [[Z:%.*]]
|
|
; CHECK-NEXT: ret <2 x float> [[F]]
|
|
;
|
|
%d = fmul fast <2 x float> %z, <float 4.000000e+01, float 4.000000e+01>
|
|
%c = fneg fast <2 x float> %d
|
|
%e = fmul fast <2 x float> %a, %c
|
|
%f = fneg fast <2 x float> %e
|
|
ret <2 x float> %f
|
|
}
|
|
|
|
; Check -(-(z*40)*a) -> a*40*z - minimum FMF subset version
|
|
|
|
define <2 x float> @test10_reassoc(<2 x float> %a, <2 x float> %b, <2 x float> %z) {
|
|
; CHECK-LABEL: @test10_reassoc(
|
|
; CHECK-NEXT: [[D:%.*]] = fmul reassoc <2 x float> [[Z:%.*]], <float 4.000000e+01, float 4.000000e+01>
|
|
; CHECK-NEXT: [[C:%.*]] = fsub reassoc <2 x float> zeroinitializer, [[D]]
|
|
; CHECK-NEXT: [[E:%.*]] = fmul reassoc <2 x float> [[A:%.*]], [[C]]
|
|
; CHECK-NEXT: [[F:%.*]] = fsub reassoc <2 x float> zeroinitializer, [[E]]
|
|
; CHECK-NEXT: ret <2 x float> [[F]]
|
|
;
|
|
%d = fmul reassoc <2 x float> %z, <float 4.000000e+01, float 4.000000e+01>
|
|
%c = fsub reassoc <2 x float> <float 0.000000e+00, float 0.000000e+00>, %d
|
|
%e = fmul reassoc <2 x float> %a, %c
|
|
%f = fsub reassoc <2 x float> <float 0.000000e+00, float 0.000000e+00>, %e
|
|
ret <2 x float> %f
|
|
}
|
|
|
|
define <2 x float> @test10_reassoc_unary_fneg(<2 x float> %a, <2 x float> %b, <2 x float> %z) {
|
|
; CHECK-LABEL: @test10_reassoc_unary_fneg(
|
|
; CHECK-NEXT: [[D:%.*]] = fmul reassoc <2 x float> [[Z:%.*]], <float 4.000000e+01, float 4.000000e+01>
|
|
; CHECK-NEXT: [[C:%.*]] = fneg reassoc <2 x float> [[D]]
|
|
; CHECK-NEXT: [[E:%.*]] = fmul reassoc <2 x float> [[A:%.*]], [[C]]
|
|
; CHECK-NEXT: [[F:%.*]] = fneg reassoc <2 x float> [[E]]
|
|
; CHECK-NEXT: ret <2 x float> [[F]]
|
|
;
|
|
%d = fmul reassoc <2 x float> %z, <float 4.000000e+01, float 4.000000e+01>
|
|
%c = fneg reassoc <2 x float> %d
|
|
%e = fmul reassoc <2 x float> %a, %c
|
|
%f = fneg reassoc <2 x float> %e
|
|
ret <2 x float> %f
|
|
}
|
|
|
|
; Check x*y+y*x -> x*y*2.
|
|
|
|
define <2 x double> @test11(<2 x double> %x, <2 x double> %y) {
|
|
; CHECK-LABEL: @test11(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast <2 x double> [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast <2 x double> [[FACTOR]], <double 2.000000e+00, double 2.000000e+00>
|
|
; CHECK-NEXT: ret <2 x double> [[REASS_MUL]]
|
|
;
|
|
%1 = fmul fast <2 x double> %x, %y
|
|
%2 = fmul fast <2 x double> %y, %x
|
|
%3 = fadd fast <2 x double> %1, %2
|
|
ret <2 x double> %3
|
|
}
|
|
|
|
; Check x*y+y*x -> x*y*2 - minimum FMF subset version
|
|
|
|
define <2 x double> @test11_reassoc(<2 x double> %x, <2 x double> %y) {
|
|
; CHECK-LABEL: @test11_reassoc(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc <2 x double> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc <2 x double> [[X]], [[Y]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fadd reassoc <2 x double> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret <2 x double> [[TMP3]]
|
|
;
|
|
%1 = fmul reassoc <2 x double> %x, %y
|
|
%2 = fmul reassoc <2 x double> %y, %x
|
|
%3 = fadd reassoc <2 x double> %1, %2
|
|
ret <2 x double> %3
|
|
}
|
|
|
|
; FIXME: shifts should be converted to mul to assist further reassociation.
|
|
|
|
define <2 x i64> @test12(<2 x i64> %b, <2 x i64> %c) {
|
|
; CHECK-LABEL: @test12(
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i64> [[C:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> [[MUL]], <i64 5, i64 5>
|
|
; CHECK-NEXT: ret <2 x i64> [[SHL]]
|
|
;
|
|
%mul = mul <2 x i64> %c, %b
|
|
%shl = shl <2 x i64> %mul, <i64 5, i64 5>
|
|
ret <2 x i64> %shl
|
|
}
|
|
|
|
; (-5*b)+a -> a-(5*b)
|
|
|
|
define <4 x float> @test13(<4 x float> %a, <4 x float> %b) {
|
|
; CHECK-LABEL: @test13(
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul fast <4 x float> [[B:%.*]], <float 5.000000e+00, float 5.000000e+00, float 5.000000e+00, float 5.000000e+00>
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <4 x float> [[A:%.*]], [[MUL]]
|
|
; CHECK-NEXT: ret <4 x float> [[TMP1]]
|
|
;
|
|
%mul = fmul fast <4 x float> <float -5.000000e+00, float -5.000000e+00, float -5.000000e+00, float -5.000000e+00>, %b
|
|
%add = fadd fast <4 x float> %mul, %a
|
|
ret <4 x float> %add
|
|
}
|
|
|
|
; Break up subtract to assist further reassociation.
|
|
; Check a+b-c -> a+b+-c.
|
|
|
|
define <2 x i64> @test14(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) {
|
|
; CHECK-LABEL: @test14(
|
|
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i64> [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[C_NEG:%.*]] = sub <2 x i64> zeroinitializer, [[C:%.*]]
|
|
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i64> [[ADD]], [[C_NEG]]
|
|
; CHECK-NEXT: ret <2 x i64> [[SUB]]
|
|
;
|
|
%add = add <2 x i64> %b, %a
|
|
%sub = sub <2 x i64> %add, %c
|
|
ret <2 x i64> %sub
|
|
}
|
|
|
|
define <2 x i32> @test15(<2 x i32> %x, <2 x i32> %y) {
|
|
; CHECK-LABEL: @test15(
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: ret <2 x i32> [[TMP3]]
|
|
;
|
|
%tmp1 = and <2 x i32> %x, %y
|
|
%tmp2 = and <2 x i32> %y, %x
|
|
%tmp3 = and <2 x i32> %tmp1, %tmp2
|
|
ret <2 x i32> %tmp3
|
|
}
|
|
|
|
define <2 x i32> @test16(<2 x i32> %x, <2 x i32> %y) {
|
|
; CHECK-LABEL: @test16(
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i32> [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: ret <2 x i32> [[TMP3]]
|
|
;
|
|
%tmp1 = or <2 x i32> %x, %y
|
|
%tmp2 = or <2 x i32> %y, %x
|
|
%tmp3 = or <2 x i32> %tmp1, %tmp2
|
|
ret <2 x i32> %tmp3
|
|
}
|
|
|
|
define <2 x i32> @test17(<2 x i32> %x, <2 x i32> %y) {
|
|
; CHECK-LABEL: @test17(
|
|
; CHECK-NEXT: ret <2 x i32> zeroinitializer
|
|
;
|
|
%tmp1 = xor <2 x i32> %x, %y
|
|
%tmp2 = xor <2 x i32> %y, %x
|
|
%tmp3 = xor <2 x i32> %tmp1, %tmp2
|
|
ret <2 x i32> %tmp3
|
|
}
|
|
|
|
define <2 x i32> @test18(<2 x i32> %x, <2 x i32> %y) {
|
|
; CHECK-LABEL: @test18(
|
|
; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i32> [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: ret <2 x i32> [[TMP5]]
|
|
;
|
|
%tmp1 = xor <2 x i32> %x, %y
|
|
%tmp2 = xor <2 x i32> %y, %x
|
|
%tmp3 = xor <2 x i32> %x, %y
|
|
%tmp4 = xor <2 x i32> %tmp1, %tmp2
|
|
%tmp5 = xor <2 x i32> %tmp4, %tmp3
|
|
ret <2 x i32> %tmp5
|
|
}
|