1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64le-linux-gnu | FileCheck %s 3 4; Verify that the fold of a*b-c*d respect the uses of a*b 5define double @fsub1(double %a, double %b, double %c, double %d) { 6; CHECK-LABEL: fsub1: 7; CHECK: # %bb.0: # %entry 8; CHECK-NEXT: xsmuldp 0, 2, 1 9; CHECK-NEXT: fmr 1, 0 10; CHECK-NEXT: xsnmsubadp 1, 4, 3 11; CHECK-NEXT: xsmuldp 1, 0, 1 12; CHECK-NEXT: blr 13entry: 14 %mul = fmul reassoc double %b, %a 15 %mul1 = fmul reassoc double %d, %c 16 %sub = fsub reassoc nsz double %mul, %mul1 17 %mul3 = fmul reassoc double %mul, %sub 18 ret double %mul3 19} 20 21; Verify that the fold of a*b-c*d respect the uses of c*d 22define double @fsub2(double %a, double %b, double %c, double %d) { 23; CHECK-LABEL: fsub2: 24; CHECK: # %bb.0: # %entry 25; CHECK-NEXT: xsmuldp 0, 4, 3 26; CHECK-NEXT: fmr 3, 0 27; CHECK-NEXT: xsmsubadp 3, 2, 1 28; CHECK-NEXT: xsmuldp 1, 0, 3 29; CHECK-NEXT: blr 30entry: 31 %mul = fmul reassoc double %b, %a 32 %mul1 = fmul reassoc double %d, %c 33 %sub = fsub reassoc double %mul, %mul1 34 %mul3 = fmul reassoc double %mul1, %sub 35 ret double %mul3 36} 37 38; Verify that the fold of a*b-c*d if there is no uses of a*b and c*d 39define double @fsub3(double %a, double %b, double %c, double %d) { 40; CHECK-LABEL: fsub3: 41; CHECK: # %bb.0: # %entry 42; CHECK-NEXT: xsmuldp 0, 4, 3 43; CHECK-NEXT: xsmsubadp 0, 2, 1 44; CHECK-NEXT: fmr 1, 0 45; CHECK-NEXT: blr 46entry: 47 %mul = fmul reassoc double %b, %a 48 %mul1 = fmul reassoc double %d, %c 49 %sub = fsub reassoc double %mul, %mul1 50 ret double %sub 51} 52 53; Verify that the fold of a*b+c*d respect the uses of a*b 54define double @fadd1(double %a, double %b, double %c, double %d) { 55; CHECK-LABEL: fadd1: 56; CHECK: # %bb.0: # %entry 57; CHECK-NEXT: xsmuldp 0, 2, 1 58; CHECK-NEXT: fmr 1, 0 59; CHECK-NEXT: xsmaddadp 1, 4, 3 60; CHECK-NEXT: xsmuldp 1, 0, 1 61; CHECK-NEXT: blr 62entry: 63 %mul = fmul reassoc double %b, %a 64 %mul1 = fmul reassoc double %d, %c 65 %add = fadd reassoc double %mul1, %mul 66 %mul3 = fmul reassoc double %mul, %add 67 ret double %mul3 68} 69 70; Verify that the fold of a*b+c*d respect the uses of c*d 71define double @fadd2(double %a, double %b, double %c, double %d) { 72; CHECK-LABEL: fadd2: 73; CHECK: # %bb.0: # %entry 74; CHECK-NEXT: xsmuldp 0, 4, 3 75; CHECK-NEXT: fmr 3, 0 76; CHECK-NEXT: xsmaddadp 3, 2, 1 77; CHECK-NEXT: xsmuldp 1, 0, 3 78; CHECK-NEXT: blr 79entry: 80 %mul = fmul reassoc double %b, %a 81 %mul1 = fmul reassoc double %d, %c 82 %add = fadd reassoc double %mul1, %mul 83 %mul3 = fmul reassoc double %mul1, %add 84 ret double %mul3 85} 86 87; Verify that the fold of a*b+c*d if there is no uses of a*b and c*d 88define double @fadd3(double %a, double %b, double %c, double %d) { 89; CHECK-LABEL: fadd3: 90; CHECK: # %bb.0: # %entry 91; CHECK-NEXT: xsmuldp 1, 2, 1 92; CHECK-NEXT: xsmaddadp 1, 4, 3 93; CHECK-NEXT: blr 94entry: 95 %mul = fmul reassoc double %b, %a 96 %mul1 = fmul reassoc double %d, %c 97 %add = fadd reassoc double %mul1, %mul 98 ret double %add 99} 100 101define double @fma_multi_uses1(double %a, double %b, double %c, double %d, double* %p1, double* %p2, double* %p3) { 102; CHECK-LABEL: fma_multi_uses1: 103; CHECK: # %bb.0: 104; CHECK-NEXT: xsmuldp 1, 1, 2 105; CHECK-NEXT: xsmuldp 0, 3, 4 106; CHECK-NEXT: stfd 1, 0(7) 107; CHECK-NEXT: stfd 1, 0(8) 108; CHECK-NEXT: xsnmsubadp 1, 3, 4 109; CHECK-NEXT: stfd 0, 0(9) 110; CHECK-NEXT: blr 111 %ab = fmul reassoc double %a, %b 112 %cd = fmul reassoc double %c, %d 113 store double %ab, double* %p1 ; extra use of %ab 114 store double %ab, double* %p2 ; another extra use of %ab 115 store double %cd, double* %p3 ; extra use of %cd 116 %r = fsub reassoc nsz double %ab, %cd 117 ret double %r 118} 119 120define double @fma_multi_uses2(double %a, double %b, double %c, double %d, double* %p1, double* %p2, double* %p3) { 121; CHECK-LABEL: fma_multi_uses2: 122; CHECK: # %bb.0: 123; CHECK-NEXT: xsmuldp 5, 1, 2 124; CHECK-NEXT: xsmuldp 0, 3, 4 125; CHECK-NEXT: stfd 5, 0(7) 126; CHECK-NEXT: stfd 0, 0(8) 127; CHECK-NEXT: stfd 0, 0(9) 128; CHECK-NEXT: xsmsubadp 0, 1, 2 129; CHECK-NEXT: fmr 1, 0 130; CHECK-NEXT: blr 131 %ab = fmul reassoc double %a, %b 132 %cd = fmul reassoc double %c, %d 133 store double %ab, double* %p1 ; extra use of %ab 134 store double %cd, double* %p2 ; extra use of %cd 135 store double %cd, double* %p3 ; another extra use of %cd 136 %r = fsub reassoc double %ab, %cd 137 ret double %r 138} 139 140define double @fma_multi_uses3(double %a, double %b, double %c, double %d, double %f, double %g, double* %p1, double* %p2, double* %p3) { 141; CHECK-LABEL: fma_multi_uses3: 142; CHECK: # %bb.0: 143; CHECK-NEXT: xsmuldp 0, 1, 2 144; CHECK-NEXT: xsmuldp 1, 5, 6 145; CHECK-NEXT: ld 3, 96(1) 146; CHECK-NEXT: stfd 0, 0(9) 147; CHECK-NEXT: stfd 0, 0(10) 148; CHECK-NEXT: stfd 1, 0(3) 149; CHECK-NEXT: xsnmsubadp 1, 3, 4 150; CHECK-NEXT: xsnmsubadp 0, 3, 4 151; CHECK-NEXT: xsadddp 1, 0, 1 152; CHECK-NEXT: blr 153 %ab = fmul reassoc double %a, %b 154 %cd = fmul reassoc double %c, %d 155 %fg = fmul reassoc double %f, %g 156 store double %ab, double* %p1 ; extra use of %ab 157 store double %ab, double* %p2 ; another extra use of %ab 158 store double %fg, double* %p3 ; extra use of %fg 159 %q = fsub reassoc nsz double %fg, %cd ; The uses of %cd reduce to 1 after %r is folded. 2 uses of %fg, fold %cd, remove def of %cd 160 %r = fsub reassoc nsz double %ab, %cd ; Fold %r before %q. 3 uses of %ab, 2 uses of %cd, fold %cd 161 %add = fadd reassoc double %r, %q 162 ret double %add 163} 164