1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX 4 5; It's the extra tests coverage for recip as discussed on D26855. 6 7define float @f32_no_step_2(float %x) #3 { 8; SSE-LABEL: f32_no_step_2: 9; SSE: # BB#0: 10; SSE-NEXT: rcpss %xmm0, %xmm0 11; SSE-NEXT: mulss {{.*}}(%rip), %xmm0 12; SSE-NEXT: retq 13; 14; AVX-LABEL: f32_no_step_2: 15; AVX: # BB#0: 16; AVX-NEXT: vrcpss %xmm0, %xmm0, %xmm0 17; AVX-NEXT: vmulss {{.*}}(%rip), %xmm0, %xmm0 18; AVX-NEXT: retq 19 %div = fdiv fast float 1234.0, %x 20 ret float %div 21} 22 23define float @f32_one_step_2(float %x) #1 { 24; SSE-LABEL: f32_one_step_2: 25; SSE: # BB#0: 26; SSE-NEXT: rcpss %xmm0, %xmm2 27; SSE-NEXT: mulss %xmm2, %xmm0 28; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 29; SSE-NEXT: subss %xmm0, %xmm1 30; SSE-NEXT: mulss %xmm2, %xmm1 31; SSE-NEXT: addss %xmm2, %xmm1 32; SSE-NEXT: mulss {{.*}}(%rip), %xmm1 33; SSE-NEXT: movaps %xmm1, %xmm0 34; SSE-NEXT: retq 35; 36; AVX-LABEL: f32_one_step_2: 37; AVX: # BB#0: 38; AVX-NEXT: vrcpss %xmm0, %xmm0, %xmm1 39; AVX-NEXT: vmulss %xmm1, %xmm0, %xmm0 40; AVX-NEXT: vmovss {{.*#+}} xmm2 = mem[0],zero,zero,zero 41; AVX-NEXT: vsubss %xmm0, %xmm2, %xmm0 42; AVX-NEXT: vmulss %xmm0, %xmm1, %xmm0 43; AVX-NEXT: vaddss %xmm0, %xmm1, %xmm0 44; AVX-NEXT: vmulss {{.*}}(%rip), %xmm0, %xmm0 45; AVX-NEXT: retq 46 %div = fdiv fast float 3456.0, %x 47 ret float %div 48} 49 50define float @f32_two_step_2(float %x) #2 { 51; SSE-LABEL: f32_two_step_2: 52; SSE: # BB#0: 53; SSE-NEXT: rcpss %xmm0, %xmm2 54; SSE-NEXT: movaps %xmm0, %xmm3 55; SSE-NEXT: mulss %xmm2, %xmm3 56; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 57; SSE-NEXT: movaps %xmm1, %xmm4 58; SSE-NEXT: subss %xmm3, %xmm4 59; SSE-NEXT: mulss %xmm2, %xmm4 60; SSE-NEXT: addss %xmm2, %xmm4 61; SSE-NEXT: mulss %xmm4, %xmm0 62; SSE-NEXT: subss %xmm0, %xmm1 63; SSE-NEXT: mulss %xmm4, %xmm1 64; SSE-NEXT: addss %xmm4, %xmm1 65; SSE-NEXT: mulss {{.*}}(%rip), %xmm1 66; SSE-NEXT: movaps %xmm1, %xmm0 67; SSE-NEXT: retq 68; 69; AVX-LABEL: f32_two_step_2: 70; AVX: # BB#0: 71; AVX-NEXT: vrcpss %xmm0, %xmm0, %xmm1 72; AVX-NEXT: vmulss %xmm1, %xmm0, %xmm2 73; AVX-NEXT: vmovss {{.*#+}} xmm3 = mem[0],zero,zero,zero 74; AVX-NEXT: vsubss %xmm2, %xmm3, %xmm2 75; AVX-NEXT: vmulss %xmm2, %xmm1, %xmm2 76; AVX-NEXT: vaddss %xmm2, %xmm1, %xmm1 77; AVX-NEXT: vmulss %xmm1, %xmm0, %xmm0 78; AVX-NEXT: vsubss %xmm0, %xmm3, %xmm0 79; AVX-NEXT: vmulss %xmm0, %xmm1, %xmm0 80; AVX-NEXT: vaddss %xmm0, %xmm1, %xmm0 81; AVX-NEXT: vmulss {{.*}}(%rip), %xmm0, %xmm0 82; AVX-NEXT: retq 83 %div = fdiv fast float 6789.0, %x 84 ret float %div 85} 86 87define <4 x float> @v4f32_one_step2(<4 x float> %x) #1 { 88; SSE-LABEL: v4f32_one_step2: 89; SSE: # BB#0: 90; SSE-NEXT: rcpps %xmm0, %xmm2 91; SSE-NEXT: mulps %xmm2, %xmm0 92; SSE-NEXT: movaps {{.*#+}} xmm1 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 93; SSE-NEXT: subps %xmm0, %xmm1 94; SSE-NEXT: mulps %xmm2, %xmm1 95; SSE-NEXT: addps %xmm2, %xmm1 96; SSE-NEXT: mulps {{.*}}(%rip), %xmm1 97; SSE-NEXT: movaps %xmm1, %xmm0 98; SSE-NEXT: retq 99; 100; AVX-LABEL: v4f32_one_step2: 101; AVX: # BB#0: 102; AVX-NEXT: vrcpps %xmm0, %xmm1 103; AVX-NEXT: vmulps %xmm1, %xmm0, %xmm0 104; AVX-NEXT: vmovaps {{.*#+}} xmm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 105; AVX-NEXT: vsubps %xmm0, %xmm2, %xmm0 106; AVX-NEXT: vmulps %xmm0, %xmm1, %xmm0 107; AVX-NEXT: vaddps %xmm0, %xmm1, %xmm0 108; AVX-NEXT: vmulps {{.*}}(%rip), %xmm0, %xmm0 109; AVX-NEXT: retq 110 %div = fdiv fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x 111 ret <4 x float> %div 112} 113 114define <4 x float> @v4f32_two_step2(<4 x float> %x) #2 { 115; SSE-LABEL: v4f32_two_step2: 116; SSE: # BB#0: 117; SSE-NEXT: rcpps %xmm0, %xmm2 118; SSE-NEXT: movaps %xmm0, %xmm3 119; SSE-NEXT: mulps %xmm2, %xmm3 120; SSE-NEXT: movaps {{.*#+}} xmm1 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 121; SSE-NEXT: movaps %xmm1, %xmm4 122; SSE-NEXT: subps %xmm3, %xmm4 123; SSE-NEXT: mulps %xmm2, %xmm4 124; SSE-NEXT: addps %xmm2, %xmm4 125; SSE-NEXT: mulps %xmm4, %xmm0 126; SSE-NEXT: subps %xmm0, %xmm1 127; SSE-NEXT: mulps %xmm4, %xmm1 128; SSE-NEXT: addps %xmm4, %xmm1 129; SSE-NEXT: mulps {{.*}}(%rip), %xmm1 130; SSE-NEXT: movaps %xmm1, %xmm0 131; SSE-NEXT: retq 132; 133; AVX-LABEL: v4f32_two_step2: 134; AVX: # BB#0: 135; AVX-NEXT: vrcpps %xmm0, %xmm1 136; AVX-NEXT: vmulps %xmm1, %xmm0, %xmm2 137; AVX-NEXT: vmovaps {{.*#+}} xmm3 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 138; AVX-NEXT: vsubps %xmm2, %xmm3, %xmm2 139; AVX-NEXT: vmulps %xmm2, %xmm1, %xmm2 140; AVX-NEXT: vaddps %xmm2, %xmm1, %xmm1 141; AVX-NEXT: vmulps %xmm1, %xmm0, %xmm0 142; AVX-NEXT: vsubps %xmm0, %xmm3, %xmm0 143; AVX-NEXT: vmulps %xmm0, %xmm1, %xmm0 144; AVX-NEXT: vaddps %xmm0, %xmm1, %xmm0 145; AVX-NEXT: vmulps {{.*}}(%rip), %xmm0, %xmm0 146; AVX-NEXT: retq 147 %div = fdiv fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x 148 ret <4 x float> %div 149} 150 151define <8 x float> @v8f32_one_step2(<8 x float> %x) #1 { 152; SSE-LABEL: v8f32_one_step2: 153; SSE: # BB#0: 154; SSE-NEXT: rcpps %xmm1, %xmm4 155; SSE-NEXT: mulps %xmm4, %xmm1 156; SSE-NEXT: movaps {{.*#+}} xmm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 157; SSE-NEXT: movaps %xmm2, %xmm3 158; SSE-NEXT: subps %xmm1, %xmm3 159; SSE-NEXT: mulps %xmm4, %xmm3 160; SSE-NEXT: addps %xmm4, %xmm3 161; SSE-NEXT: rcpps %xmm0, %xmm1 162; SSE-NEXT: mulps %xmm1, %xmm0 163; SSE-NEXT: subps %xmm0, %xmm2 164; SSE-NEXT: mulps %xmm1, %xmm2 165; SSE-NEXT: addps %xmm1, %xmm2 166; SSE-NEXT: mulps {{.*}}(%rip), %xmm2 167; SSE-NEXT: mulps {{.*}}(%rip), %xmm3 168; SSE-NEXT: movaps %xmm2, %xmm0 169; SSE-NEXT: movaps %xmm3, %xmm1 170; SSE-NEXT: retq 171; 172; AVX-LABEL: v8f32_one_step2: 173; AVX: # BB#0: 174; AVX-NEXT: vrcpps %ymm0, %ymm1 175; AVX-NEXT: vmulps %ymm1, %ymm0, %ymm0 176; AVX-NEXT: vmovaps {{.*#+}} ymm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 177; AVX-NEXT: vsubps %ymm0, %ymm2, %ymm0 178; AVX-NEXT: vmulps %ymm0, %ymm1, %ymm0 179; AVX-NEXT: vaddps %ymm0, %ymm1, %ymm0 180; AVX-NEXT: vmulps {{.*}}(%rip), %ymm0, %ymm0 181; AVX-NEXT: retq 182 %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x 183 ret <8 x float> %div 184} 185 186define <8 x float> @v8f32_two_step2(<8 x float> %x) #2 { 187; SSE-LABEL: v8f32_two_step2: 188; SSE: # BB#0: 189; SSE-NEXT: movaps %xmm0, %xmm2 190; SSE-NEXT: rcpps %xmm1, %xmm3 191; SSE-NEXT: movaps %xmm1, %xmm4 192; SSE-NEXT: mulps %xmm3, %xmm4 193; SSE-NEXT: movaps {{.*#+}} xmm0 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 194; SSE-NEXT: movaps %xmm0, %xmm5 195; SSE-NEXT: subps %xmm4, %xmm5 196; SSE-NEXT: mulps %xmm3, %xmm5 197; SSE-NEXT: addps %xmm3, %xmm5 198; SSE-NEXT: mulps %xmm5, %xmm1 199; SSE-NEXT: movaps %xmm0, %xmm3 200; SSE-NEXT: subps %xmm1, %xmm3 201; SSE-NEXT: mulps %xmm5, %xmm3 202; SSE-NEXT: addps %xmm5, %xmm3 203; SSE-NEXT: rcpps %xmm2, %xmm1 204; SSE-NEXT: movaps %xmm2, %xmm4 205; SSE-NEXT: mulps %xmm1, %xmm4 206; SSE-NEXT: movaps %xmm0, %xmm5 207; SSE-NEXT: subps %xmm4, %xmm5 208; SSE-NEXT: mulps %xmm1, %xmm5 209; SSE-NEXT: addps %xmm1, %xmm5 210; SSE-NEXT: mulps %xmm5, %xmm2 211; SSE-NEXT: subps %xmm2, %xmm0 212; SSE-NEXT: mulps %xmm5, %xmm0 213; SSE-NEXT: addps %xmm5, %xmm0 214; SSE-NEXT: mulps {{.*}}(%rip), %xmm0 215; SSE-NEXT: mulps {{.*}}(%rip), %xmm3 216; SSE-NEXT: movaps %xmm3, %xmm1 217; SSE-NEXT: retq 218; 219; AVX-LABEL: v8f32_two_step2: 220; AVX: # BB#0: 221; AVX-NEXT: vrcpps %ymm0, %ymm1 222; AVX-NEXT: vmulps %ymm1, %ymm0, %ymm2 223; AVX-NEXT: vmovaps {{.*#+}} ymm3 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00] 224; AVX-NEXT: vsubps %ymm2, %ymm3, %ymm2 225; AVX-NEXT: vmulps %ymm2, %ymm1, %ymm2 226; AVX-NEXT: vaddps %ymm2, %ymm1, %ymm1 227; AVX-NEXT: vmulps %ymm1, %ymm0, %ymm0 228; AVX-NEXT: vsubps %ymm0, %ymm3, %ymm0 229; AVX-NEXT: vmulps %ymm0, %ymm1, %ymm0 230; AVX-NEXT: vaddps %ymm0, %ymm1, %ymm0 231; AVX-NEXT: vmulps {{.*}}(%rip), %ymm0, %ymm0 232; AVX-NEXT: retq 233 %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x 234 ret <8 x float> %div 235} 236 237define <8 x float> @v8f32_no_step(<8 x float> %x) #3 { 238; SSE-LABEL: v8f32_no_step: 239; SSE: # BB#0: 240; SSE-NEXT: rcpps %xmm0, %xmm0 241; SSE-NEXT: rcpps %xmm1, %xmm1 242; SSE-NEXT: retq 243; 244; AVX-LABEL: v8f32_no_step: 245; AVX: # BB#0: 246; AVX-NEXT: vrcpps %ymm0, %ymm0 247; AVX-NEXT: retq 248 %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %x 249 ret <8 x float> %div 250} 251 252define <8 x float> @v8f32_no_step2(<8 x float> %x) #3 { 253; SSE-LABEL: v8f32_no_step2: 254; SSE: # BB#0: 255; SSE-NEXT: rcpps %xmm1, %xmm1 256; SSE-NEXT: rcpps %xmm0, %xmm0 257; SSE-NEXT: mulps {{.*}}(%rip), %xmm0 258; SSE-NEXT: mulps {{.*}}(%rip), %xmm1 259; SSE-NEXT: retq 260; 261; AVX-LABEL: v8f32_no_step2: 262; AVX: # BB#0: 263; AVX-NEXT: vrcpps %ymm0, %ymm0 264; AVX-NEXT: vmulps {{.*}}(%rip), %ymm0, %ymm0 265; AVX-NEXT: retq 266 %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x 267 ret <8 x float> %div 268} 269 270attributes #0 = { "unsafe-fp-math"="true" "reciprocal-estimates"="!divf,!vec-divf" } 271attributes #1 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf,vec-divf" } 272attributes #2 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf:2,vec-divf:2" } 273attributes #3 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf:0,vec-divf:0" } 274 275