Refactoring and enhancement to FMA combine.

llvm-svn: 235344
diff --git a/llvm/test/CodeGen/PowerPC/fma-assoc.ll b/llvm/test/CodeGen/PowerPC/fma-assoc.ll
index dc1316e..3044dd0 100644
--- a/llvm/test/CodeGen/PowerPC/fma-assoc.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-assoc.ll
@@ -3,11 +3,11 @@
 
 define double @test_FMADD_ASSOC1(double %A, double %B, double %C,
                                  double %D, double %E) {
-	%F = fmul double %A, %B         ; <double> [#uses=1]
-	%G = fmul double %C, %D         ; <double> [#uses=1]
-	%H = fadd double %F, %G         ; <double> [#uses=1]
-	%I = fadd double %H, %E         ; <double> [#uses=1]
-	ret double %I
+  %F = fmul double %A, %B         ; <double> [#uses=1]
+  %G = fmul double %C, %D         ; <double> [#uses=1]
+  %H = fadd double %F, %G         ; <double> [#uses=1]
+  %I = fadd double %H, %E         ; <double> [#uses=1]
+  ret double %I
 ; CHECK-LABEL: test_FMADD_ASSOC1:
 ; CHECK: fmadd
 ; CHECK-NEXT: fmadd
@@ -22,11 +22,11 @@
 
 define double @test_FMADD_ASSOC2(double %A, double %B, double %C,
                                  double %D, double %E) {
-	%F = fmul double %A, %B         ; <double> [#uses=1]
-	%G = fmul double %C, %D         ; <double> [#uses=1]
-	%H = fadd double %F, %G         ; <double> [#uses=1]
-	%I = fadd double %E, %H         ; <double> [#uses=1]
-	ret double %I
+  %F = fmul double %A, %B         ; <double> [#uses=1]
+  %G = fmul double %C, %D         ; <double> [#uses=1]
+  %H = fadd double %F, %G         ; <double> [#uses=1]
+  %I = fadd double %E, %H         ; <double> [#uses=1]
+  ret double %I
 ; CHECK-LABEL: test_FMADD_ASSOC2:
 ; CHECK: fmadd
 ; CHECK-NEXT: fmadd
@@ -41,11 +41,11 @@
 
 define double @test_FMSUB_ASSOC1(double %A, double %B, double %C,
                                  double %D, double %E) {
-	%F = fmul double %A, %B         ; <double> [#uses=1]
-	%G = fmul double %C, %D         ; <double> [#uses=1]
-	%H = fadd double %F, %G         ; <double> [#uses=1]
-	%I = fsub double %H, %E         ; <double> [#uses=1]
-	ret double %I
+  %F = fmul double %A, %B         ; <double> [#uses=1]
+  %G = fmul double %C, %D         ; <double> [#uses=1]
+  %H = fadd double %F, %G         ; <double> [#uses=1]
+  %I = fsub double %H, %E         ; <double> [#uses=1]
+  ret double %I
 ; CHECK-LABEL: test_FMSUB_ASSOC1:
 ; CHECK: fmsub
 ; CHECK-NEXT: fmadd
@@ -60,11 +60,11 @@
 
 define double @test_FMSUB_ASSOC2(double %A, double %B, double %C,
                                  double %D, double %E) {
-	%F = fmul double %A, %B         ; <double> [#uses=1]
-	%G = fmul double %C, %D         ; <double> [#uses=1]
-	%H = fadd double %F, %G         ; <double> [#uses=1]
-	%I = fsub double %E, %H         ; <double> [#uses=1]
-	ret double %I
+  %F = fmul double %A, %B         ; <double> [#uses=1]
+  %G = fmul double %C, %D         ; <double> [#uses=1]
+  %H = fadd double %F, %G         ; <double> [#uses=1]
+  %I = fsub double %E, %H         ; <double> [#uses=1]
+  ret double %I
 ; CHECK-LABEL: test_FMSUB_ASSOC2:
 ; CHECK: fnmsub
 ; CHECK-NEXT: fnmsub
@@ -77,3 +77,159 @@
 ; CHECK-VSX-NEXT: blr
 }
 
+define double @test_FMADD_ASSOC_EXT1(float %A, float %B, double %C,
+                                 double %D, double %E) {
+  %F = fmul float %A, %B         ; <float> [#uses=1]
+  %G = fpext float %F to double   ; <double> [#uses=1]
+  %H = fmul double %C, %D         ; <double> [#uses=1]
+  %I = fadd double %H, %G         ; <double> [#uses=1]
+  %J = fadd double %I, %E         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMADD_ASSOC_EXT1:
+; CHECK: fmadd
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMADD_ASSOC_EXT1:
+; CHECK-VSX: xsmaddmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMADD_ASSOC_EXT2(float %A, float %B, float %C,
+                                 float %D, double %E) {
+  %F = fmul float %A, %B         ; <float> [#uses=1]
+  %G = fmul float %C, %D         ; <float> [#uses=1]
+  %H = fadd float %F, %G         ; <float> [#uses=1]
+  %I = fpext float %H to double   ; <double> [#uses=1]
+  %J = fadd double %I, %E         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMADD_ASSOC_EXT2:
+; CHECK: fmadd
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMADD_ASSOC_EXT2:
+; CHECK-VSX: xsmaddmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: fmr
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMADD_ASSOC_EXT3(float %A, float %B, double %C,
+                                 double %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fpext float %F to double   ; <double> [#uses=1]
+  %H = fmul double %C, %D         ; <double> [#uses=1]
+  %I = fadd double %H, %G         ; <double> [#uses=1]
+  %J = fadd double %E, %I         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMADD_ASSOC_EXT3:
+; CHECK: fmadd
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMADD_ASSOC_EXT3:
+; CHECK-VSX: xsmaddmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMADD_ASSOC_EXT4(float %A, float %B, float %C,
+                                 float %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fmul float %C, %D          ; <float> [#uses=1]
+  %H = fadd float %F, %G          ; <float> [#uses=1]
+  %I = fpext float %H to double   ; <double> [#uses=1]
+  %J = fadd double %E, %I         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMADD_ASSOC_EXT4:
+; CHECK: fmadd
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMADD_ASSOC_EXT4:
+; CHECK-VSX: xsmaddmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: fmr
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMSUB_ASSOC_EXT1(float %A, float %B, double %C,
+                                 double %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fpext float %F to double   ; <double> [#uses=1]
+  %H = fmul double %C, %D         ; <double> [#uses=1]
+  %I = fadd double %H, %G         ; <double> [#uses=1]
+  %J = fsub double %I, %E         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMSUB_ASSOC_EXT1:
+; CHECK: fmsub
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT1:
+; CHECK-VSX: xsmsubmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMSUB_ASSOC_EXT2(float %A, float %B, float %C,
+                                 float %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fmul float %C, %D          ; <float> [#uses=1]
+  %H = fadd float %F, %G          ; <float> [#uses=1]
+  %I = fpext float %H to double   ; <double> [#uses=1]
+  %J = fsub double %I, %E         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMSUB_ASSOC_EXT2:
+; CHECK: fmsub
+; CHECK-NEXT: fmadd
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT2:
+; CHECK-VSX: xsmsubmdp
+; CHECK-VSX-NEXT: xsmaddadp
+; CHECK-VSX-NEXT: fmr
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
+                                 double %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fpext float %F to double   ; <double> [#uses=1]
+  %H = fmul double %C, %D         ; <double> [#uses=1]
+  %I = fadd double %H, %G         ; <double> [#uses=1]
+  %J = fsub double %E, %I         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMSUB_ASSOC_EXT3:
+; CHECK: fnmsub
+; CHECK-NEXT: fnmsub
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT3:
+; CHECK-VSX: xsnmsubmdp
+; CHECK-VSX-NEXT: xsnmsubadp
+; CHECK-VSX-NEXT: fmr
+; CHECK-VSX-NEXT: blr
+}
+
+define double @test_FMSUB_ASSOC_EXT4(float %A, float %B, float %C,
+                                 float %D, double %E) {
+  %F = fmul float %A, %B          ; <float> [#uses=1]
+  %G = fmul float %C, %D          ; <float> [#uses=1]
+  %H = fadd float %F, %G          ; <float> [#uses=1]
+  %I = fpext float %H to double   ; <double> [#uses=1]
+  %J = fsub double %E, %I         ; <double> [#uses=1]
+  ret double %J
+; CHECK-LABEL: test_FMSUB_ASSOC_EXT4:
+; CHECK: fnmsub
+; CHECK-NEXT: fnmsub
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT4:
+; CHECK-VSX: xsnmsubmdp
+; CHECK-VSX-NEXT: xsnmsubadp
+; CHECK-VSX-NEXT: fmr
+; CHECK-VSX-NEXT: blr
+}
diff --git a/llvm/test/CodeGen/PowerPC/fma-ext.ll b/llvm/test/CodeGen/PowerPC/fma-ext.ll
index 56825ce..da7c34c 100644
--- a/llvm/test/CodeGen/PowerPC/fma-ext.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-ext.ll
@@ -60,34 +60,34 @@
 
 define double @test_FMSUB_EXT3(float %A, float %B, double %C) {
     %D = fmul float %A, %B          ; <float> [#uses=1]
-    %E = fsub float -0.000000e+00, %D ;		<float> [#uses=1]
+    %E = fsub float -0.000000e+00, %D ;    <float> [#uses=1]
     %F = fpext float %E to double   ; <double> [#uses=1]
     %G = fsub double %F, %C         ; <double> [#uses=1]
     ret double %G
 ; CHECK-LABEL: test_FMSUB_EXT3:
-; CHECK: fneg
-; CHECK-NEXT: fmsub
+; CHECK: fnmadd
+
 ; CHECK-NEXT: blr
                                 
 ; CHECK-VSX-LABEL: test_FMSUB_EXT3:
-; CHECK-VSX: xsnegdp
-; CHECK-VSX-NEXT: xsmsubmdp
+; CHECK-VSX: xsnmaddmdp
+
 ; CHECK-VSX-NEXT: blr
 }
     
 define double @test_FMSUB_EXT4(float %A, float %B, double %C) {
     %D = fmul float %A, %B          ; <float> [#uses=1]
     %E = fpext float %D to double   ; <double> [#uses=1]
-    %F = fsub double -0.000000e+00, %E ;		<double> [#uses=1]
+    %F = fsub double -0.000000e+00, %E ;    <double> [#uses=1]
     %G = fsub double %F, %C         ; <double> [#uses=1]
     ret double %G
 ; CHECK-LABEL: test_FMSUB_EXT4:
-; CHECK: fneg
-; CHECK-NEXT: fmsub
+; CHECK: fnmadd
+
 ; CHECK-NEXT: blr
                                 
 ; CHECK-VSX-LABEL: test_FMSUB_EXT4:
-; CHECK-VSX: xsnegdp
-; CHECK-VSX-NEXT: xsmsubmdp
+; CHECK-VSX: xsnmaddmdp
+
 ; CHECK-VSX-NEXT: blr
-}  
\ No newline at end of file
+}