1; RUN: llc -verify-machineinstrs -O3 -mcpu=pwr7 < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-PWR 2; RUN: llc -verify-machineinstrs -O3 -mcpu=a2q < %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-QPX 3; RUN: llc -verify-machineinstrs -O3 -mcpu=pwr9 < %s | FileCheck %s -check-prefix=FIXPOINT 4target datalayout = "E-m:e-i64:64-n32:64" 5target triple = "powerpc64-unknown-linux-gnu" 6 7; Verify that the first two adds are independent regardless of how the inputs are 8; commuted. The destination registers are used as source registers for the third add. 9 10define float @reassociate_adds1(float %x0, float %x1, float %x2, float %x3) { 11; CHECK-LABEL: reassociate_adds1: 12; CHECK: # %bb.0: 13; CHECK: fadds [[REG0:[0-9]+]], 1, 2 14; CHECK: fadds [[REG1:[0-9]+]], 3, 4 15; CHECK: fadds 1, [[REG0]], [[REG1]] 16; CHECK-NEXT: blr 17 18 %t0 = fadd reassoc nsz float %x0, %x1 19 %t1 = fadd reassoc nsz float %t0, %x2 20 %t2 = fadd reassoc nsz float %t1, %x3 21 ret float %t2 22} 23 24define float @reassociate_adds2(float %x0, float %x1, float %x2, float %x3) { 25; CHECK-LABEL: reassociate_adds2: 26; CHECK: # %bb.0: 27; CHECK: fadds [[REG0:[0-9]+]], 1, 2 28; CHECK: fadds [[REG1:[0-9]+]], 3, 4 29; CHECK: fadds 1, [[REG0]], [[REG1]] 30; CHECK-NEXT: blr 31 32 %t0 = fadd reassoc nsz float %x0, %x1 33 %t1 = fadd reassoc nsz float %x2, %t0 34 %t2 = fadd reassoc nsz float %t1, %x3 35 ret float %t2 36} 37 38define float @reassociate_adds3(float %x0, float %x1, float %x2, float %x3) { 39; CHECK-LABEL: reassociate_adds3: 40; CHECK: # %bb.0: 41; CHECK: fadds [[REG0:[0-9]+]], 1, 2 42; CHECK: fadds [[REG1:[0-9]+]], 3, 4 43; CHECK: fadds 1, [[REG0]], [[REG1]] 44; CHECK-NEXT: blr 45 46 %t0 = fadd reassoc nsz float %x0, %x1 47 %t1 = fadd reassoc nsz float %t0, %x2 48 %t2 = fadd reassoc nsz float %x3, %t1 49 ret float %t2 50} 51 52define float @reassociate_adds4(float %x0, float %x1, float %x2, float %x3) { 53; CHECK-LABEL: reassociate_adds4: 54; CHECK: # %bb.0: 55; CHECK: fadds [[REG0:[0-9]+]], 1, 2 56; CHECK: fadds [[REG1:[0-9]+]], 3, 4 57; CHECK: fadds 1, [[REG0]], [[REG1]] 58; CHECK-NEXT: blr 59 60 %t0 = fadd reassoc nsz float %x0, %x1 61 %t1 = fadd reassoc nsz float %x2, %t0 62 %t2 = fadd reassoc nsz float %x3, %t1 63 ret float %t2 64} 65 66; Verify that we reassociate some of these ops. The optimal balanced tree of adds is not 67; produced because that would cost more compile time. 68 69define float @reassociate_adds5(float %x0, float %x1, float %x2, float %x3, float %x4, float %x5, float %x6, float %x7) { 70; CHECK-LABEL: reassociate_adds5: 71; CHECK: # %bb.0: 72; CHECK-DAG: fadds [[REG12:[0-9]+]], 5, 6 73; CHECK-DAG: fadds [[REG0:[0-9]+]], 1, 2 74; CHECK-DAG: fadds [[REG11:[0-9]+]], 3, 4 75; CHECK-DAG: fadds [[REG13:[0-9]+]], [[REG12]], 7 76; CHECK-DAG: fadds [[REG1:[0-9]+]], [[REG0]], [[REG11]] 77; CHECK-DAG: fadds [[REG2:[0-9]+]], [[REG1]], [[REG13]] 78; CHECK: fadds 1, [[REG2]], 8 79; CHECK-NEXT: blr 80 81 %t0 = fadd reassoc nsz float %x0, %x1 82 %t1 = fadd reassoc nsz float %t0, %x2 83 %t2 = fadd reassoc nsz float %t1, %x3 84 %t3 = fadd reassoc nsz float %t2, %x4 85 %t4 = fadd reassoc nsz float %t3, %x5 86 %t5 = fadd reassoc nsz float %t4, %x6 87 %t6 = fadd reassoc nsz float %t5, %x7 88 ret float %t6 89} 90 91; Verify that we reassociate vector instructions too. 92 93define <4 x float> @vector_reassociate_adds1(<4 x float> %x0, <4 x float> %x1, <4 x float> %x2, <4 x float> %x3) { 94; CHECK-LABEL: vector_reassociate_adds1: 95; CHECK: # %bb.0: 96; CHECK-QPX: qvfadds [[REG0:[0-9]+]], 1, 2 97; CHECK-QPX: qvfadds [[REG1:[0-9]+]], 3, 4 98; CHECK-QPX: qvfadds 1, [[REG0]], [[REG1]] 99; CHECK-PWR: xvaddsp [[REG0:[0-9]+]], 34, 35 100; CHECK-PWR: xvaddsp [[REG1:[0-9]+]], 36, 37 101; CHECK-PWR: xvaddsp 34, [[REG0]], [[REG1]] 102; CHECK-NEXT: blr 103 104 %t0 = fadd reassoc nsz <4 x float> %x0, %x1 105 %t1 = fadd reassoc nsz <4 x float> %t0, %x2 106 %t2 = fadd reassoc nsz <4 x float> %t1, %x3 107 ret <4 x float> %t2 108} 109 110define <4 x float> @vector_reassociate_adds2(<4 x float> %x0, <4 x float> %x1, <4 x float> %x2, <4 x float> %x3) { 111; CHECK-LABEL: vector_reassociate_adds2: 112; CHECK: # %bb.0: 113; CHECK-QPX: qvfadds [[REG0:[0-9]+]], 1, 2 114; CHECK-QPX: qvfadds [[REG1:[0-9]+]], 3, 4 115; CHECK-QPX: qvfadds 1, [[REG0]], [[REG1]] 116; CHECK-PWR: xvaddsp [[REG0:[0-9]+]], 34, 35 117; CHECK-PWR: xvaddsp [[REG1:[0-9]+]], 36, 37 118; CHECK-PWR: xvaddsp 34, [[REG0]], [[REG1]] 119; CHECK-NEXT: blr 120 121 %t0 = fadd reassoc nsz <4 x float> %x0, %x1 122 %t1 = fadd reassoc nsz <4 x float> %x2, %t0 123 %t2 = fadd reassoc nsz <4 x float> %t1, %x3 124 ret <4 x float> %t2 125} 126 127define <4 x float> @vector_reassociate_adds3(<4 x float> %x0, <4 x float> %x1, <4 x float> %x2, <4 x float> %x3) { 128; CHECK-LABEL: vector_reassociate_adds3: 129; CHECK: # %bb.0: 130; CHECK-QPX: qvfadds [[REG0:[0-9]+]], 1, 2 131; CHECK-QPX: qvfadds [[REG1:[0-9]+]], 3, 4 132; CHECK-QPX: qvfadds 1, [[REG0]], [[REG1]] 133; CHECK-PWR: xvaddsp [[REG0:[0-9]+]], 34, 35 134; CHECK-PWR: xvaddsp [[REG1:[0-9]+]], 36, 37 135; CHECK-PWR: xvaddsp 34, [[REG0]], [[REG1]] 136; CHECK-NEXT: blr 137 138 %t0 = fadd reassoc nsz <4 x float> %x0, %x1 139 %t1 = fadd reassoc nsz <4 x float> %t0, %x2 140 %t2 = fadd reassoc nsz <4 x float> %x3, %t1 141 ret <4 x float> %t2 142} 143 144define <4 x float> @vector_reassociate_adds4(<4 x float> %x0, <4 x float> %x1, <4 x float> %x2, <4 x float> %x3) { 145; CHECK-LABEL: vector_reassociate_adds4: 146; CHECK: # %bb.0: 147; CHECK-QPX: qvfadds [[REG0:[0-9]+]], 1, 2 148; CHECK-QPX: qvfadds [[REG1:[0-9]+]], 3, 4 149; CHECK-QPX: qvfadds 1, [[REG0]], [[REG1]] 150; CHECK-PWR: xvaddsp [[REG0:[0-9]+]], 34, 35 151; CHECK-PWR: xvaddsp [[REG1:[0-9]+]], 36, 37 152; CHECK-PWR: xvaddsp 34, [[REG0]], [[REG1]] 153; CHECK-NEXT: blr 154 155 %t0 = fadd reassoc nsz <4 x float> %x0, %x1 156 %t1 = fadd reassoc nsz <4 x float> %x2, %t0 157 %t2 = fadd reassoc nsz <4 x float> %x3, %t1 158 ret <4 x float> %t2 159} 160 161define float @reassociate_adds6(float %x0, float %x1, float %x2, float %x3) { 162 %t0 = fdiv float %x0, %x1 163 %t1 = fadd float %x2, %t0 164 %t2 = fadd float %x3, %t1 165 ret float %t2 166} 167 168define float @reassociate_muls1(float %x0, float %x1, float %x2, float %x3) { 169 %t0 = fdiv float %x0, %x1 170 %t1 = fmul float %x2, %t0 171 %t2 = fmul float %x3, %t1 172 ret float %t2 173} 174 175define double @reassociate_adds_double(double %x0, double %x1, double %x2, double %x3) { 176 %t0 = fdiv double %x0, %x1 177 %t1 = fadd double %x2, %t0 178 %t2 = fadd double %x3, %t1 179 ret double %t2 180} 181 182define double @reassociate_muls_double(double %x0, double %x1, double %x2, double %x3) { 183 %t0 = fdiv double %x0, %x1 184 %t1 = fmul double %x2, %t0 185 %t2 = fmul double %x3, %t1 186 ret double %t2 187} 188 189define i32 @reassociate_mullw(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 190; FIXPOINT-LABEL: reassociate_mullw: 191; FIXPOINT: # %bb.0: 192; FIXPOINT: mullw [[REG0:[0-9]+]], 3, 4 193; FIXPOINT: mullw [[REG1:[0-9]+]], 5, 6 194; FIXPOINT: mullw 3, [[REG0]], [[REG1]] 195; FIXPOINT-NEXT: blr 196 197 %t0 = mul i32 %x0, %x1 198 %t1 = mul i32 %t0, %x2 199 %t2 = mul i32 %t1, %x3 200 ret i32 %t2 201} 202 203define i64 @reassociate_mulld(i64 %x0, i64 %x1, i64 %x2, i64 %x3) { 204; FIXPOINT-LABEL: reassociate_mulld: 205; FIXPOINT: # %bb.0: 206; FIXPOINT: mulld [[REG0:[0-9]+]], 3, 4 207; FIXPOINT: mulld [[REG1:[0-9]+]], 5, 6 208; FIXPOINT: mulld 3, [[REG0]], [[REG1]] 209; FIXPOINT-NEXT: blr 210 211 %t0 = mul i64 %x0, %x1 212 %t1 = mul i64 %t0, %x2 213 %t2 = mul i64 %t1, %x3 214 ret i64 %t2 215} 216 217define double @reassociate_mamaa_double(double %0, double %1, double %2, double %3, double %4, double %5) { 218; CHECK-LABEL: reassociate_mamaa_double: 219; CHECK: # %bb.0: 220; CHECK-QPX-DAG: fmadd [[REG0:[0-9]+]], 4, 3, 2 221; CHECK-QPX-DAG: fmadd [[REG1:[0-9]+]], 6, 5, 1 222; CHECK-QPX: fadd 1, [[REG0]], [[REG1]] 223; CHECK-PWR-DAG: xsmaddadp 1, 6, 5 224; CHECK-PWR-DAG: xsmaddadp 2, 4, 3 225; CHECK-PWR: xsadddp 1, 2, 1 226; CHECK-NEXT: blr 227 %7 = fmul reassoc nsz double %3, %2 228 %8 = fmul reassoc nsz double %5, %4 229 %9 = fadd reassoc nsz double %1, %0 230 %10 = fadd reassoc nsz double %9, %7 231 %11 = fadd reassoc nsz double %10, %8 232 ret double %11 233} 234 235define float @reassociate_mamaa_float(float %0, float %1, float %2, float %3, float %4, float %5) { 236; CHECK-LABEL: reassociate_mamaa_float: 237; CHECK: # %bb.0: 238; CHECK-DAG: fmadds [[REG0:[0-9]+]], 4, 3, 2 239; CHECK-DAG: fmadds [[REG1:[0-9]+]], 6, 5, 1 240; CHECK: fadds 1, [[REG0]], [[REG1]] 241; CHECK-NEXT: blr 242 %7 = fmul reassoc nsz float %3, %2 243 %8 = fmul reassoc nsz float %5, %4 244 %9 = fadd reassoc nsz float %1, %0 245 %10 = fadd reassoc nsz float %9, %7 246 %11 = fadd reassoc nsz float %10, %8 247 ret float %11 248} 249 250define <4 x float> @reassociate_mamaa_vec(<4 x float> %0, <4 x float> %1, <4 x float> %2, <4 x float> %3, <4 x float> %4, <4 x float> %5) { 251; CHECK-LABEL: reassociate_mamaa_vec: 252; CHECK: # %bb.0: 253; CHECK-QPX-DAG: qvfmadds [[REG0:[0-9]+]], 4, 3, 2 254; CHECK-QPX-DAG: qvfmadds [[REG1:[0-9]+]], 6, 5, 1 255; CHECK-QPX: qvfadds 1, [[REG0]], [[REG1]] 256; CHECK-PWR-DAG: xvmaddasp [[REG0:[0-9]+]], 39, 38 257; CHECK-PWR-DAG: xvmaddasp [[REG1:[0-9]+]], 37, 36 258; CHECK-PWR: xvaddsp 34, [[REG1]], [[REG0]] 259; CHECK-NEXT: blr 260 %7 = fmul reassoc nsz <4 x float> %3, %2 261 %8 = fmul reassoc nsz <4 x float> %5, %4 262 %9 = fadd reassoc nsz <4 x float> %1, %0 263 %10 = fadd reassoc nsz <4 x float> %9, %7 264 %11 = fadd reassoc nsz <4 x float> %10, %8 265 ret <4 x float> %11 266} 267 268define double @reassociate_mamama_double(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8) { 269; CHECK-LABEL: reassociate_mamama_double: 270; CHECK: # %bb.0: 271; CHECK-QPX: fmadd [[REG0:[0-9]+]], 2, 1, 7 272; CHECK-QPX-DAG: fmul [[REG1:[0-9]+]], 4, 3 273; CHECK-QPX-DAG: fmadd [[REG2:[0-9]+]], 6, 5, [[REG0]] 274; CHECK-QPX-DAG: fmadd [[REG3:[0-9]+]], 9, 8, [[REG1]] 275; CHECK-QPX: fadd 1, [[REG2]], [[REG3]] 276; CHECK-PWR: xsmaddadp 7, 2, 1 277; CHECK-PWR-DAG: xsmuldp [[REG0:[0-9]+]], 4, 3 278; CHECK-PWR-DAG: xsmaddadp 7, 6, 5 279; CHECK-PWR-DAG: xsmaddadp [[REG0]], 9, 8 280; CHECK-PWR: xsadddp 1, 7, [[REG0]] 281; CHECK-NEXT: blr 282 %10 = fmul reassoc nsz double %1, %0 283 %11 = fmul reassoc nsz double %3, %2 284 %12 = fmul reassoc nsz double %5, %4 285 %13 = fmul reassoc nsz double %8, %7 286 %14 = fadd reassoc nsz double %11, %10 287 %15 = fadd reassoc nsz double %14, %6 288 %16 = fadd reassoc nsz double %15, %12 289 %17 = fadd reassoc nsz double %16, %13 290 ret double %17 291} 292 293define dso_local float @reassociate_mamama_8(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, float %8, 294 float %9, float %10, float %11, float %12, float %13, float %14, float %15, float %16) { 295; CHECK-LABEL: reassociate_mamama_8: 296; CHECK: # %bb.0: 297; CHECK-DAG: fmadds [[REG0:[0-9]+]], 3, 2, 1 298; CHECK-DAG: fmuls [[REG1:[0-9]+]], 5, 4 299; CHECK-DAG: fmadds [[REG2:[0-9]+]], 7, 6, [[REG0]] 300; CHECK-DAG: fmadds [[REG3:[0-9]+]], 9, 8, [[REG1]] 301; 302; CHECK-DAG: fmadds [[REG4:[0-9]+]], 13, 12, [[REG3]] 303; CHECK-DAG: fmadds [[REG5:[0-9]+]], 11, 10, [[REG2]] 304; 305; CHECK-DAG: fmadds [[REG6:[0-9]+]], 3, 2, [[REG4]] 306; CHECK-DAG: fmadds [[REG7:[0-9]+]], 5, 4, [[REG5]] 307; CHECK: fadds 1, [[REG7]], [[REG6]] 308; CHECK-NEXT: blr 309 %18 = fmul reassoc nsz float %2, %1 310 %19 = fadd reassoc nsz float %18, %0 311 %20 = fmul reassoc nsz float %4, %3 312 %21 = fadd reassoc nsz float %19, %20 313 %22 = fmul reassoc nsz float %6, %5 314 %23 = fadd reassoc nsz float %21, %22 315 %24 = fmul reassoc nsz float %8, %7 316 %25 = fadd reassoc nsz float %23, %24 317 %26 = fmul reassoc nsz float %10, %9 318 %27 = fadd reassoc nsz float %25, %26 319 %28 = fmul reassoc nsz float %12, %11 320 %29 = fadd reassoc nsz float %27, %28 321 %30 = fmul reassoc nsz float %14, %13 322 %31 = fadd reassoc nsz float %29, %30 323 %32 = fmul reassoc nsz float %16, %15 324 %33 = fadd reassoc nsz float %31, %32 325 ret float %33 326} 327 328