1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s 3 4define float @fadd_zero_f32(float %x) #0 { 5; CHECK-LABEL: fadd_zero_f32: 6; CHECK: # %bb.0: 7; CHECK-NEXT: retq 8 %y = fadd float %x, 0.0 9 ret float %y 10} 11 12define <4 x float> @fadd_zero_4f32(<4 x float> %x) #0 { 13; CHECK-LABEL: fadd_zero_4f32: 14; CHECK: # %bb.0: 15; CHECK-NEXT: retq 16 %y = fadd <4 x float> %x, zeroinitializer 17 ret <4 x float> %y 18} 19 20define <4 x float> @fadd_zero_4f32_undef(<4 x float> %x) { 21; CHECK-LABEL: fadd_zero_4f32_undef: 22; CHECK: # %bb.0: 23; CHECK-NEXT: retq 24 %y = fadd nsz <4 x float> %x, <float 0.0, float undef, float 0.0, float undef> 25 ret <4 x float> %y 26} 27 28; CHECK: float 3 29define float @fadd_2const_f32(float %x) #0 { 30; CHECK-LABEL: fadd_2const_f32: 31; CHECK: # %bb.0: 32; CHECK-NEXT: addss {{.*}}(%rip), %xmm0 33; CHECK-NEXT: retq 34 %y = fadd float %x, 1.0 35 %z = fadd float %y, 2.0 36 ret float %z 37} 38 39; CHECK: float 5 40; CHECK: float 5 41; CHECK: float 5 42; CHECK: float 5 43define <4 x float> @fadd_2const_4f32(<4 x float> %x) #0 { 44; CHECK-LABEL: fadd_2const_4f32: 45; CHECK: # %bb.0: 46; CHECK-NEXT: addps {{.*}}(%rip), %xmm0 47; CHECK-NEXT: retq 48 %y = fadd <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 49 %z = fadd <4 x float> %y, <float 4.0, float 3.0, float 2.0, float 1.0> 50 ret <4 x float> %z 51} 52 53; CHECK: float 3 54define float @fadd_x_fmul_x_c_f32(float %x) #0 { 55; CHECK-LABEL: fadd_x_fmul_x_c_f32: 56; CHECK: # %bb.0: 57; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 58; CHECK-NEXT: retq 59 %y = fmul float %x, 2.0 60 %z = fadd float %x, %y 61 ret float %z 62} 63 64; CHECK: float 2 65; CHECK: float 3 66; CHECK: float 4 67; CHECK: float 5 68define <4 x float> @fadd_x_fmul_x_c_4f32(<4 x float> %x) #0 { 69; CHECK-LABEL: fadd_x_fmul_x_c_4f32: 70; CHECK: # %bb.0: 71; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 72; CHECK-NEXT: retq 73 %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 74 %z = fadd <4 x float> %x, %y 75 ret <4 x float> %z 76} 77 78; CHECK: float 3 79define float @fadd_fmul_x_c_x_f32(float %x) #0 { 80; CHECK-LABEL: fadd_fmul_x_c_x_f32: 81; CHECK: # %bb.0: 82; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 83; CHECK-NEXT: retq 84 %y = fmul float %x, 2.0 85 %z = fadd float %y, %x 86 ret float %z 87} 88 89; CHECK: float 2 90; CHECK: float 3 91; CHECK: float 4 92; CHECK: float 5 93define <4 x float> @fadd_fmul_x_c_x_4f32(<4 x float> %x) #0 { 94; CHECK-LABEL: fadd_fmul_x_c_x_4f32: 95; CHECK: # %bb.0: 96; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 97; CHECK-NEXT: retq 98 %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 99 %z = fadd <4 x float> %y, %x 100 ret <4 x float> %z 101} 102 103; CHECK: float 4 104define float @fadd_fadd_x_x_fmul_x_c_f32(float %x) #0 { 105; CHECK-LABEL: fadd_fadd_x_x_fmul_x_c_f32: 106; CHECK: # %bb.0: 107; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 108; CHECK-NEXT: retq 109 %y = fadd float %x, %x 110 %z = fmul float %x, 2.0 111 %w = fadd float %y, %z 112 ret float %w 113} 114 115; CHECK: float 3 116; CHECK: float 4 117; CHECK: float 5 118; CHECK: float 6 119define <4 x float> @fadd_fadd_x_x_fmul_x_c_4f32(<4 x float> %x) #0 { 120; CHECK-LABEL: fadd_fadd_x_x_fmul_x_c_4f32: 121; CHECK: # %bb.0: 122; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 123; CHECK-NEXT: retq 124 %y = fadd <4 x float> %x, %x 125 %z = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 126 %w = fadd <4 x float> %y, %z 127 ret <4 x float> %w 128} 129 130; CHECK: float 4 131define float @fadd_fmul_x_c_fadd_x_x_f32(float %x) #0 { 132; CHECK-LABEL: fadd_fmul_x_c_fadd_x_x_f32: 133; CHECK: # %bb.0: 134; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 135; CHECK-NEXT: retq 136 %y = fadd float %x, %x 137 %z = fmul float %x, 2.0 138 %w = fadd float %z, %y 139 ret float %w 140} 141 142; CHECK: float 3 143; CHECK: float 4 144; CHECK: float 5 145; CHECK: float 6 146define <4 x float> @fadd_fmul_x_c_fadd_x_x_4f32(<4 x float> %x) #0 { 147; CHECK-LABEL: fadd_fmul_x_c_fadd_x_x_4f32: 148; CHECK: # %bb.0: 149; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 150; CHECK-NEXT: retq 151 %y = fadd <4 x float> %x, %x 152 %z = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 153 %w = fadd <4 x float> %z, %y 154 ret <4 x float> %w 155} 156 157; CHECK: float 3 158define float @fadd_x_fadd_x_x_f32(float %x) #0 { 159; CHECK-LABEL: fadd_x_fadd_x_x_f32: 160; CHECK: # %bb.0: 161; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 162; CHECK-NEXT: retq 163 %y = fadd float %x, %x 164 %z = fadd float %x, %y 165 ret float %z 166} 167 168; CHECK: float 3 169; CHECK: float 3 170; CHECK: float 3 171; CHECK: float 3 172define <4 x float> @fadd_x_fadd_x_x_4f32(<4 x float> %x) #0 { 173; CHECK-LABEL: fadd_x_fadd_x_x_4f32: 174; CHECK: # %bb.0: 175; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 176; CHECK-NEXT: retq 177 %y = fadd <4 x float> %x, %x 178 %z = fadd <4 x float> %x, %y 179 ret <4 x float> %z 180} 181 182; CHECK: float 3 183define float @fadd_fadd_x_x_x_f32(float %x) #0 { 184; CHECK-LABEL: fadd_fadd_x_x_x_f32: 185; CHECK: # %bb.0: 186; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 187; CHECK-NEXT: retq 188 %y = fadd float %x, %x 189 %z = fadd float %y, %x 190 ret float %z 191} 192 193; CHECK: float 3 194; CHECK: float 3 195; CHECK: float 3 196; CHECK: float 3 197define <4 x float> @fadd_fadd_x_x_x_4f32(<4 x float> %x) #0 { 198; CHECK-LABEL: fadd_fadd_x_x_x_4f32: 199; CHECK: # %bb.0: 200; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 201; CHECK-NEXT: retq 202 %y = fadd <4 x float> %x, %x 203 %z = fadd <4 x float> %y, %x 204 ret <4 x float> %z 205} 206 207; CHECK: float 4 208define float @fadd_fadd_x_x_fadd_x_x_f32(float %x) #0 { 209; CHECK-LABEL: fadd_fadd_x_x_fadd_x_x_f32: 210; CHECK: # %bb.0: 211; CHECK-NEXT: mulss {{.*}}(%rip), %xmm0 212; CHECK-NEXT: retq 213 %y = fadd float %x, %x 214 %z = fadd float %y, %y 215 ret float %z 216} 217 218; CHECK: float 4 219; CHECK: float 4 220; CHECK: float 4 221; CHECK: float 4 222define <4 x float> @fadd_fadd_x_x_fadd_x_x_4f32(<4 x float> %x) #0 { 223; CHECK-LABEL: fadd_fadd_x_x_fadd_x_x_4f32: 224; CHECK: # %bb.0: 225; CHECK-NEXT: mulps {{.*}}(%rip), %xmm0 226; CHECK-NEXT: retq 227 %y = fadd <4 x float> %x, %x 228 %z = fadd <4 x float> %y, %y 229 ret <4 x float> %z 230} 231 232; ((x + 42.0) + 17.0) + (x + 42.0) --> (x + 59.0) + (x + 17.0) 233; It's still 3 adds, but the first 2 are independent. 234; More reassocation could get this to 2 adds or 1 FMA (that's done in IR, but not in the DAG). 235 236define float @fadd_const_multiuse_attr(float %x) #0 { 237; CHECK-LABEL: fadd_const_multiuse_attr: 238; CHECK: # %bb.0: 239; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 240; CHECK-NEXT: addss %xmm0, %xmm1 241; CHECK-NEXT: addss {{.*}}(%rip), %xmm0 242; CHECK-NEXT: addss %xmm1, %xmm0 243; CHECK-NEXT: retq 244 %a1 = fadd float %x, 42.0 245 %a2 = fadd float %a1, 17.0 246 %a3 = fadd float %a1, %a2 247 ret float %a3 248} 249 250; PR32939 - https://bugs.llvm.org/show_bug.cgi?id=32939 251 252define double @fmul2_negated(double %a, double %b, double %c) { 253; CHECK-LABEL: fmul2_negated: 254; CHECK: # %bb.0: 255; CHECK-NEXT: addsd %xmm1, %xmm1 256; CHECK-NEXT: mulsd %xmm2, %xmm1 257; CHECK-NEXT: subsd %xmm1, %xmm0 258; CHECK-NEXT: retq 259 %mul = fmul double %b, 2.0 260 %mul1 = fmul double %mul, %c 261 %sub = fsub double %a, %mul1 262 ret double %sub 263} 264 265define <2 x double> @fmul2_negated_vec(<2 x double> %a, <2 x double> %b, <2 x double> %c) { 266; CHECK-LABEL: fmul2_negated_vec: 267; CHECK: # %bb.0: 268; CHECK-NEXT: addpd %xmm1, %xmm1 269; CHECK-NEXT: mulpd %xmm2, %xmm1 270; CHECK-NEXT: subpd %xmm1, %xmm0 271; CHECK-NEXT: retq 272 %mul = fmul <2 x double> %b, <double 2.0, double 2.0> 273 %mul1 = fmul <2 x double> %mul, %c 274 %sub = fsub <2 x double> %a, %mul1 275 ret <2 x double> %sub 276} 277 278attributes #0 = { "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" "no-signed-zeros-fp-math"="true" } 279