640 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; REQUIRES: asserts3; RUN: llc < %s -mtriple=powerpc64le -debug-only=isel -o /dev/null 2>&1 | FileCheck %s --check-prefix=FMFDEBUG4; RUN: llc < %s -mtriple=powerpc64le | FileCheck %s --check-prefix=FMF5; RUN: llc < %s -mtriple=powerpc64le -debug-only=isel -o /dev/null 2>&1 -fp-contract=fast -enable-no-nans-fp-math | FileCheck %s --check-prefix=GLOBALDEBUG6; RUN: llc < %s -mtriple=powerpc64le -fp-contract=fast -enable-no-nans-fp-math -enable-no-signed-zeros-fp-math | FileCheck %s --check-prefix=GLOBAL7 8; Test FP transforms using instruction/node-level fast-math-flags.9; We're also checking debug output to verify that FMF is propagated to the newly created nodes.10; The run with the global unsafe param tests the pre-FMF behavior using regular instructions/nodes.11 12declare float @llvm.fma.f32(float, float, float)13declare float @llvm.sqrt.f32(float)14 15; X * Y + Z --> fma(X, Y, Z)16 17; contract bits in fmul is checked.18 19; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_contract1:'20; FMFDEBUG-NOT: fma contract {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}21; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_contract1:'22 23define float @fmul_fadd_contract1(float %x, float %y, float %z) {24; FMF-LABEL: fmul_fadd_contract1:25; FMF: # %bb.0:26; FMF-NEXT: xsmulsp 0, 1, 227; FMF-NEXT: xsaddsp 1, 0, 328; FMF-NEXT: blr29;30; GLOBAL-LABEL: fmul_fadd_contract1:31; GLOBAL: # %bb.0:32; GLOBAL-NEXT: xsmaddasp 3, 1, 233; GLOBAL-NEXT: fmr 1, 334; GLOBAL-NEXT: blr35 %mul = fmul float %x, %y36 %add = fadd contract float %mul, %z37 ret float %add38}39 40; contract bits in fadd is also checked.41 42; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_contract2:'43; FMFDEBUG-NOT: fma contract {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}44; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_contract2:'45 46define float @fmul_fadd_contract2(float %x, float %y, float %z) {47; FMF-LABEL: fmul_fadd_contract2:48; FMF: # %bb.0:49; FMF-NEXT: xsmulsp 0, 1, 250; FMF-NEXT: xsaddsp 1, 0, 351; FMF-NEXT: blr52;53; GLOBAL-LABEL: fmul_fadd_contract2:54; GLOBAL: # %bb.0:55; GLOBAL-NEXT: xsmaddasp 3, 1, 256; GLOBAL-NEXT: fmr 1, 357; GLOBAL-NEXT: blr58 %mul = fmul contract float %x, %y59 %add = fadd float %mul, %z60 ret float %add61}62 63; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_contract3:'64; FMFDEBUG: fma contract {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}65; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_contract3:'66 67define float @fmul_fadd_contract3(float %x, float %y, float %z) {68; FMF-LABEL: fmul_fadd_contract3:69; FMF: # %bb.0:70; FMF-NEXT: xsmaddasp 3, 1, 271; FMF-NEXT: fmr 1, 372; FMF-NEXT: blr73;74; GLOBAL-LABEL: fmul_fadd_contract3:75; GLOBAL: # %bb.0:76; GLOBAL-NEXT: xsmaddasp 3, 1, 277; GLOBAL-NEXT: fmr 1, 378; GLOBAL-NEXT: blr79 %mul = fmul contract float %x, %y80 %add = fadd contract float %mul, %z81 ret float %add82}83 84; Reassociation does NOT imply that FMA contraction is allowed.85 86; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_reassoc1:'87; FMFDEBUG-NOT: fma reassoc {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}88; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_reassoc1:'89 90define float @fmul_fadd_reassoc1(float %x, float %y, float %z) {91; FMF-LABEL: fmul_fadd_reassoc1:92; FMF: # %bb.0:93; FMF-NEXT: xsmulsp 0, 1, 294; FMF-NEXT: xsaddsp 1, 0, 395; FMF-NEXT: blr96;97; GLOBAL-LABEL: fmul_fadd_reassoc1:98; GLOBAL: # %bb.0:99; GLOBAL-NEXT: xsmaddasp 3, 1, 2100; GLOBAL-NEXT: fmr 1, 3101; GLOBAL-NEXT: blr102 %mul = fmul float %x, %y103 %add = fadd reassoc float %mul, %z104 ret float %add105}106 107; This shouldn't change anything - the intermediate fmul result is now also flagged.108; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_reassoc2:'109; FMFDEBUG-NOT: fma reassoc {{t[0-9]+}}, {{t[0-9]+}}110; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_reassoc2:'111 112define float @fmul_fadd_reassoc2(float %x, float %y, float %z) {113; FMF-LABEL: fmul_fadd_reassoc2:114; FMF: # %bb.0:115; FMF-NEXT: xsmulsp 0, 1, 2116; FMF-NEXT: xsaddsp 1, 0, 3117; FMF-NEXT: blr118;119; GLOBAL-LABEL: fmul_fadd_reassoc2:120; GLOBAL: # %bb.0:121; GLOBAL-NEXT: xsmaddasp 3, 1, 2122; GLOBAL-NEXT: fmr 1, 3123; GLOBAL-NEXT: blr124 %mul = fmul reassoc float %x, %y125 %add = fadd reassoc float %mul, %z126 ret float %add127}128 129; The fadd is now fully 'fast', but fmul is not yet.130 131; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_fast1:'132; FMFDEBUG-NOT: fma nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}133; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_fast1:'134 135define float @fmul_fadd_fast1(float %x, float %y, float %z) {136; FMF-LABEL: fmul_fadd_fast1:137; FMF: # %bb.0:138; FMF-NEXT: xsmulsp 0, 1, 2139; FMF-NEXT: xsaddsp 1, 0, 3140; FMF-NEXT: blr141;142; GLOBAL-LABEL: fmul_fadd_fast1:143; GLOBAL: # %bb.0:144; GLOBAL-NEXT: xsmaddasp 3, 1, 2145; GLOBAL-NEXT: fmr 1, 3146; GLOBAL-NEXT: blr147 %mul = fmul float %x, %y148 %add = fadd fast float %mul, %z149 ret float %add150}151 152; This implies that contraction is allowed - the intermediate fmul result is now also flagged.153 154; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fadd_fast2:'155; FMFDEBUG: fma nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}, {{t[0-9]+}}, {{t[0-9]+}}156; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fadd_fast2:'157 158define float @fmul_fadd_fast2(float %x, float %y, float %z) {159; FMF-LABEL: fmul_fadd_fast2:160; FMF: # %bb.0:161; FMF-NEXT: xsmaddasp 3, 1, 2162; FMF-NEXT: fmr 1, 3163; FMF-NEXT: blr164;165; GLOBAL-LABEL: fmul_fadd_fast2:166; GLOBAL: # %bb.0:167; GLOBAL-NEXT: xsmaddasp 3, 1, 2168; GLOBAL-NEXT: fmr 1, 3169; GLOBAL-NEXT: blr170 %mul = fmul fast float %x, %y171 %add = fadd fast float %mul, %z172 ret float %add173}174 175; fma(X, 7.0, X * 42.0) --> X * 49.0176; This is the minimum FMF needed for this transform - the FMA allows reassociation.177 178; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_reassoc1:'179; FMFDEBUG: fmul reassoc {{t[0-9]+}},180; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_reassoc1:'181 182; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_reassoc1:'183; GLOBALDEBUG: fmul reassoc {{t[0-9]+}}184; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_reassoc1:'185 186define float @fmul_fma_reassoc1(float %x) {187; FMF-LABEL: fmul_fma_reassoc1:188; FMF: # %bb.0:189; FMF-NEXT: addis 3, 2, .LCPI7_0@toc@ha190; FMF-NEXT: lfs 0, .LCPI7_0@toc@l(3)191; FMF-NEXT: xsmulsp 1, 1, 0192; FMF-NEXT: blr193;194; GLOBAL-LABEL: fmul_fma_reassoc1:195; GLOBAL: # %bb.0:196; GLOBAL-NEXT: addis 3, 2, .LCPI7_0@toc@ha197; GLOBAL-NEXT: lfs 0, .LCPI7_0@toc@l(3)198; GLOBAL-NEXT: xsmulsp 1, 1, 0199; GLOBAL-NEXT: blr200 %mul = fmul float %x, 42.0201 %fma = call reassoc float @llvm.fma.f32(float %x, float 7.0, float %mul)202 ret float %fma203}204 205; This shouldn't change anything - the intermediate fmul result is now also flagged.206 207; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_reassoc2:'208; FMFDEBUG: fmul reassoc {{t[0-9]+}}209; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_reassoc2:'210 211; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_reassoc2:'212; GLOBALDEBUG: fmul reassoc {{t[0-9]+}}213; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_reassoc2:'214 215define float @fmul_fma_reassoc2(float %x) {216; FMF-LABEL: fmul_fma_reassoc2:217; FMF: # %bb.0:218; FMF-NEXT: addis 3, 2, .LCPI8_0@toc@ha219; FMF-NEXT: lfs 0, .LCPI8_0@toc@l(3)220; FMF-NEXT: xsmulsp 1, 1, 0221; FMF-NEXT: blr222;223; GLOBAL-LABEL: fmul_fma_reassoc2:224; GLOBAL: # %bb.0:225; GLOBAL-NEXT: addis 3, 2, .LCPI8_0@toc@ha226; GLOBAL-NEXT: lfs 0, .LCPI8_0@toc@l(3)227; GLOBAL-NEXT: xsmulsp 1, 1, 0228; GLOBAL-NEXT: blr229 %mul = fmul reassoc float %x, 42.0230 %fma = call reassoc float @llvm.fma.f32(float %x, float 7.0, float %mul)231 ret float %fma232}233 234; The FMA is now fully 'fast'. This implies that reassociation is allowed.235 236; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_fast1:'237; FMFDEBUG: fmul nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}238; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_fast1:'239 240; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_fast1:'241; GLOBALDEBUG: fmul nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}242; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_fast1:'243 244define float @fmul_fma_fast1(float %x) {245; FMF-LABEL: fmul_fma_fast1:246; FMF: # %bb.0:247; FMF-NEXT: addis 3, 2, .LCPI9_0@toc@ha248; FMF-NEXT: lfs 0, .LCPI9_0@toc@l(3)249; FMF-NEXT: xsmulsp 1, 1, 0250; FMF-NEXT: blr251;252; GLOBAL-LABEL: fmul_fma_fast1:253; GLOBAL: # %bb.0:254; GLOBAL-NEXT: addis 3, 2, .LCPI9_0@toc@ha255; GLOBAL-NEXT: lfs 0, .LCPI9_0@toc@l(3)256; GLOBAL-NEXT: xsmulsp 1, 1, 0257; GLOBAL-NEXT: blr258 %mul = fmul float %x, 42.0259 %fma = call fast float @llvm.fma.f32(float %x, float 7.0, float %mul)260 ret float %fma261}262 263; This shouldn't change anything - the intermediate fmul result is now also flagged.264 265; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_fast2:'266; FMFDEBUG: fmul nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}267; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_fast2:'268 269; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fmul_fma_fast2:'270; GLOBALDEBUG: fmul nnan ninf nsz arcp contract afn reassoc {{t[0-9]+}}271; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fmul_fma_fast2:'272 273define float @fmul_fma_fast2(float %x) {274; FMF-LABEL: fmul_fma_fast2:275; FMF: # %bb.0:276; FMF-NEXT: addis 3, 2, .LCPI10_0@toc@ha277; FMF-NEXT: lfs 0, .LCPI10_0@toc@l(3)278; FMF-NEXT: xsmulsp 1, 1, 0279; FMF-NEXT: blr280;281; GLOBAL-LABEL: fmul_fma_fast2:282; GLOBAL: # %bb.0:283; GLOBAL-NEXT: addis 3, 2, .LCPI10_0@toc@ha284; GLOBAL-NEXT: lfs 0, .LCPI10_0@toc@l(3)285; GLOBAL-NEXT: xsmulsp 1, 1, 0286; GLOBAL-NEXT: blr287 %mul = fmul fast float %x, 42.0288 %fma = call fast float @llvm.fma.f32(float %x, float 7.0, float %mul)289 ret float %fma290}291 292; Reduced precision for sqrt is allowed - should use estimate and NR iterations.293 294; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_afn_ieee:'295; FMFDEBUG: fmul ninf afn {{t[0-9]+}}296; FMFDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_afn_ieee:'297 298; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_afn_ieee:'299; GLOBALDEBUG: fmul ninf afn {{t[0-9]+}}300; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_afn_ieee:'301 302define float @sqrt_afn_ieee(float %x) #0 {303; FMF-LABEL: sqrt_afn_ieee:304; FMF: # %bb.0:305; FMF-NEXT: addis 3, 2, .LCPI11_1@toc@ha306; FMF-NEXT: xsabsdp 0, 1307; FMF-NEXT: lfs 2, .LCPI11_1@toc@l(3)308; FMF-NEXT: fcmpu 0, 0, 2309; FMF-NEXT: xxlxor 0, 0, 0310; FMF-NEXT: blt 0, .LBB11_2311; FMF-NEXT: # %bb.1:312; FMF-NEXT: xsrsqrtesp 2, 1313; FMF-NEXT: addis 3, 2, .LCPI11_0@toc@ha314; FMF-NEXT: vspltisw 2, -3315; FMF-NEXT: lfs 0, .LCPI11_0@toc@l(3)316; FMF-NEXT: xsmulsp 1, 1, 2317; FMF-NEXT: xsmulsp 0, 1, 0318; FMF-NEXT: xsmulsp 1, 1, 2319; FMF-NEXT: xvcvsxwdp 2, 34320; FMF-NEXT: xsaddsp 1, 1, 2321; FMF-NEXT: xsmulsp 0, 0, 1322; FMF-NEXT: .LBB11_2:323; FMF-NEXT: fmr 1, 0324; FMF-NEXT: blr325;326; GLOBAL-LABEL: sqrt_afn_ieee:327; GLOBAL: # %bb.0:328; GLOBAL-NEXT: xsrsqrtesp 0, 1329; GLOBAL-NEXT: vspltisw 2, -3330; GLOBAL-NEXT: addis 3, 2, .LCPI11_0@toc@ha331; GLOBAL-NEXT: xvcvsxwdp 3, 34332; GLOBAL-NEXT: xsmulsp 2, 1, 0333; GLOBAL-NEXT: xsabsdp 1, 1334; GLOBAL-NEXT: xsmaddasp 3, 2, 0335; GLOBAL-NEXT: lfs 0, .LCPI11_0@toc@l(3)336; GLOBAL-NEXT: addis 3, 2, .LCPI11_1@toc@ha337; GLOBAL-NEXT: xsmulsp 0, 2, 0338; GLOBAL-NEXT: lfs 2, .LCPI11_1@toc@l(3)339; GLOBAL-NEXT: xssubsp 1, 1, 2340; GLOBAL-NEXT: xxlxor 2, 2, 2341; GLOBAL-NEXT: xsmulsp 0, 0, 3342; GLOBAL-NEXT: fsel 1, 1, 0, 2343; GLOBAL-NEXT: blr344 %rt = call afn ninf float @llvm.sqrt.f32(float %x)345 ret float %rt346}347 348define float @sqrt_afn_ieee_inf(float %x) #0 {349; FMF-LABEL: sqrt_afn_ieee_inf:350; FMF: # %bb.0:351; FMF-NEXT: xssqrtsp 1, 1352; FMF-NEXT: blr353;354; GLOBAL-LABEL: sqrt_afn_ieee_inf:355; GLOBAL: # %bb.0:356; GLOBAL-NEXT: xssqrtsp 1, 1357; GLOBAL-NEXT: blr358 %rt = call afn float @llvm.sqrt.f32(float %x)359 ret float %rt360}361 362; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_afn_preserve_sign:'363; FMFDEBUG: fmul ninf afn {{t[0-9]+}}364; FMFDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_afn_preserve_sign:'365 366; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_afn_preserve_sign:'367; GLOBALDEBUG: fmul ninf afn {{t[0-9]+}}368; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_afn_preserve_sign:'369 370define float @sqrt_afn_preserve_sign(float %x) #1 {371; FMF-LABEL: sqrt_afn_preserve_sign:372; FMF: # %bb.0:373; FMF-NEXT: xxlxor 0, 0, 0374; FMF-NEXT: fcmpu 0, 1, 0375; FMF-NEXT: beq 0, .LBB13_2376; FMF-NEXT: # %bb.1:377; FMF-NEXT: xsrsqrtesp 0, 1378; FMF-NEXT: addis 3, 2, .LCPI13_0@toc@ha379; FMF-NEXT: vspltisw 2, -3380; FMF-NEXT: lfs 2, .LCPI13_0@toc@l(3)381; FMF-NEXT: xsmulsp 1, 1, 0382; FMF-NEXT: xsmulsp 2, 1, 2383; FMF-NEXT: xsmulsp 0, 1, 0384; FMF-NEXT: xvcvsxwdp 1, 34385; FMF-NEXT: xsaddsp 0, 0, 1386; FMF-NEXT: xsmulsp 0, 2, 0387; FMF-NEXT: .LBB13_2:388; FMF-NEXT: fmr 1, 0389; FMF-NEXT: blr390;391; GLOBAL-LABEL: sqrt_afn_preserve_sign:392; GLOBAL: # %bb.0:393; GLOBAL-NEXT: xsrsqrtesp 0, 1394; GLOBAL-NEXT: vspltisw 2, -3395; GLOBAL-NEXT: addis 3, 2, .LCPI13_0@toc@ha396; GLOBAL-NEXT: xvcvsxwdp 3, 34397; GLOBAL-NEXT: xsmulsp 2, 1, 0398; GLOBAL-NEXT: xsmaddasp 3, 2, 0399; GLOBAL-NEXT: lfs 0, .LCPI13_0@toc@l(3)400; GLOBAL-NEXT: xsmulsp 0, 2, 0401; GLOBAL-NEXT: xxlxor 2, 2, 2402; GLOBAL-NEXT: xsmulsp 0, 0, 3403; GLOBAL-NEXT: fsel 2, 1, 2, 0404; GLOBAL-NEXT: xsnegdp 1, 1405; GLOBAL-NEXT: fsel 1, 1, 2, 0406; GLOBAL-NEXT: blr407 %rt = call afn ninf float @llvm.sqrt.f32(float %x)408 ret float %rt409}410 411define float @sqrt_afn_preserve_sign_inf(float %x) #1 {412; FMF-LABEL: sqrt_afn_preserve_sign_inf:413; FMF: # %bb.0:414; FMF-NEXT: xssqrtsp 1, 1415; FMF-NEXT: blr416;417; GLOBAL-LABEL: sqrt_afn_preserve_sign_inf:418; GLOBAL: # %bb.0:419; GLOBAL-NEXT: xssqrtsp 1, 1420; GLOBAL-NEXT: blr421 %rt = call afn float @llvm.sqrt.f32(float %x)422 ret float %rt423}424 425; The call is now fully 'fast'. This implies that approximation is allowed.426 427; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_fast_ieee:'428; FMFDEBUG: fmul ninf contract afn reassoc {{t[0-9]+}}429; FMFDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_fast_ieee:'430 431; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_fast_ieee:'432; GLOBALDEBUG: fmul ninf contract afn reassoc {{t[0-9]+}}433; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_fast_ieee:'434 435define float @sqrt_fast_ieee(float %x) #0 {436; FMF-LABEL: sqrt_fast_ieee:437; FMF: # %bb.0:438; FMF-NEXT: addis 3, 2, .LCPI15_1@toc@ha439; FMF-NEXT: xsabsdp 0, 1440; FMF-NEXT: lfs 2, .LCPI15_1@toc@l(3)441; FMF-NEXT: fcmpu 0, 0, 2442; FMF-NEXT: xxlxor 0, 0, 0443; FMF-NEXT: blt 0, .LBB15_2444; FMF-NEXT: # %bb.1:445; FMF-NEXT: xsrsqrtesp 0, 1446; FMF-NEXT: vspltisw 2, -3447; FMF-NEXT: addis 3, 2, .LCPI15_0@toc@ha448; FMF-NEXT: xvcvsxwdp 2, 34449; FMF-NEXT: xsmulsp 1, 1, 0450; FMF-NEXT: xsmaddasp 2, 1, 0451; FMF-NEXT: lfs 0, .LCPI15_0@toc@l(3)452; FMF-NEXT: xsmulsp 0, 1, 0453; FMF-NEXT: xsmulsp 0, 0, 2454; FMF-NEXT: .LBB15_2:455; FMF-NEXT: fmr 1, 0456; FMF-NEXT: blr457;458; GLOBAL-LABEL: sqrt_fast_ieee:459; GLOBAL: # %bb.0:460; GLOBAL-NEXT: xsrsqrtesp 0, 1461; GLOBAL-NEXT: vspltisw 2, -3462; GLOBAL-NEXT: addis 3, 2, .LCPI15_0@toc@ha463; GLOBAL-NEXT: xvcvsxwdp 3, 34464; GLOBAL-NEXT: xsmulsp 2, 1, 0465; GLOBAL-NEXT: xsabsdp 1, 1466; GLOBAL-NEXT: xsmaddasp 3, 2, 0467; GLOBAL-NEXT: lfs 0, .LCPI15_0@toc@l(3)468; GLOBAL-NEXT: addis 3, 2, .LCPI15_1@toc@ha469; GLOBAL-NEXT: xsmulsp 0, 2, 0470; GLOBAL-NEXT: lfs 2, .LCPI15_1@toc@l(3)471; GLOBAL-NEXT: xssubsp 1, 1, 2472; GLOBAL-NEXT: xxlxor 2, 2, 2473; GLOBAL-NEXT: xsmulsp 0, 0, 3474; GLOBAL-NEXT: fsel 1, 1, 0, 2475; GLOBAL-NEXT: blr476 %rt = call contract reassoc afn ninf float @llvm.sqrt.f32(float %x)477 ret float %rt478}479 480; The call is now fully 'fast'. This implies that approximation is allowed.481 482; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_fast_preserve_sign:'483; FMFDEBUG: fmul ninf contract afn reassoc {{t[0-9]+}}484; FMFDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_fast_preserve_sign:'485 486; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'sqrt_fast_preserve_sign:'487; GLOBALDEBUG: fmul ninf contract afn reassoc {{t[0-9]+}}488; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'sqrt_fast_preserve_sign:'489 490define float @sqrt_fast_preserve_sign(float %x) #1 {491; FMF-LABEL: sqrt_fast_preserve_sign:492; FMF: # %bb.0:493; FMF-NEXT: xxlxor 0, 0, 0494; FMF-NEXT: fcmpu 0, 1, 0495; FMF-NEXT: beq 0, .LBB16_2496; FMF-NEXT: # %bb.1:497; FMF-NEXT: xsrsqrtesp 0, 1498; FMF-NEXT: vspltisw 2, -3499; FMF-NEXT: addis 3, 2, .LCPI16_0@toc@ha500; FMF-NEXT: xvcvsxwdp 2, 34501; FMF-NEXT: xsmulsp 1, 1, 0502; FMF-NEXT: xsmaddasp 2, 1, 0503; FMF-NEXT: lfs 0, .LCPI16_0@toc@l(3)504; FMF-NEXT: xsmulsp 0, 1, 0505; FMF-NEXT: xsmulsp 0, 0, 2506; FMF-NEXT: .LBB16_2:507; FMF-NEXT: fmr 1, 0508; FMF-NEXT: blr509;510; GLOBAL-LABEL: sqrt_fast_preserve_sign:511; GLOBAL: # %bb.0:512; GLOBAL-NEXT: xsrsqrtesp 0, 1513; GLOBAL-NEXT: vspltisw 2, -3514; GLOBAL-NEXT: addis 3, 2, .LCPI16_0@toc@ha515; GLOBAL-NEXT: xvcvsxwdp 3, 34516; GLOBAL-NEXT: xsmulsp 2, 1, 0517; GLOBAL-NEXT: xsmaddasp 3, 2, 0518; GLOBAL-NEXT: lfs 0, .LCPI16_0@toc@l(3)519; GLOBAL-NEXT: xsmulsp 0, 2, 0520; GLOBAL-NEXT: xxlxor 2, 2, 2521; GLOBAL-NEXT: xsmulsp 0, 0, 3522; GLOBAL-NEXT: fsel 2, 1, 2, 0523; GLOBAL-NEXT: xsnegdp 1, 1524; GLOBAL-NEXT: fsel 1, 1, 2, 0525; GLOBAL-NEXT: blr526 %rt = call contract reassoc ninf afn float @llvm.sqrt.f32(float %x)527 ret float %rt528}529 530; fcmp can have fast-math-flags.531 532; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fcmp_nnan:'533; FMFDEBUG: select_cc nnan {{t[0-9]+}}534; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fcmp_nnan:'535 536; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fcmp_nnan:'537; GLOBALDEBUG: select_cc nnan {{t[0-9]+}}538; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fcmp_nnan:'539 540define double @fcmp_nnan(double %a, double %y, double %z) {541; FMF-LABEL: fcmp_nnan:542; FMF: # %bb.0:543; FMF-NEXT: xxlxor 0, 0, 0544; FMF-NEXT: xscmpudp 0, 1, 0545; FMF-NEXT: blt 0, .LBB17_2546; FMF-NEXT: # %bb.1:547; FMF-NEXT: fmr 3, 2548; FMF-NEXT: .LBB17_2:549; FMF-NEXT: fmr 1, 3550; FMF-NEXT: blr551;552; GLOBAL-LABEL: fcmp_nnan:553; GLOBAL: # %bb.0:554; GLOBAL-NEXT: xxlxor 0, 0, 0555; GLOBAL-NEXT: xscmpudp 0, 1, 0556; GLOBAL-NEXT: blt 0, .LBB17_2557; GLOBAL-NEXT: # %bb.1:558; GLOBAL-NEXT: fmr 3, 2559; GLOBAL-NEXT: .LBB17_2:560; GLOBAL-NEXT: fmr 1, 3561; GLOBAL-NEXT: blr562 %cmp = fcmp nnan ult double %a, 0.0563 %z.y = select i1 %cmp, double %z, double %y564 ret double %z.y565}566 567; FP library calls can have fast-math-flags.568 569; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'log2_approx:'570; FMFDEBUG: ch,glue = PPCISD::CALL_NOP {{t[0-9]+}}, TargetGlobalAddress:i64<ptr @log2>571; FMFDEBUG: ch,glue = callseq_end [[T15:t[0-9]+]], TargetConstant:i64<32>, TargetConstant:i64<0>, [[T15]]:1572; FMFDEBUG: f64,ch,glue = CopyFromReg [[T16:t[0-9]+]], Register:f64 $f1, [[T16]]:1573; FMFDEBUG: Type-legalized selection DAG: %bb.0 'log2_approx:'574 575; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'log2_approx:'576; GLOBALDEBUG: ch,glue = PPCISD::CALL_NOP {{t[0-9]+}}, TargetGlobalAddress:i64<ptr @log2>577; GLOBALDEBUG: ch,glue = callseq_end [[T15:t[0-9]+]], TargetConstant:i64<32>, TargetConstant:i64<0>, [[T15]]:1578; GLOBALDEBUG: f64,ch,glue = CopyFromReg [[T16:t[0-9]+]], Register:f64 $f1, [[T16]]:1579; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'log2_approx:'580 581declare double @log2(double)582define double @log2_approx(double %x) nounwind {583; FMF-LABEL: log2_approx:584; FMF: # %bb.0:585; FMF-NEXT: mflr 0586; FMF-NEXT: stdu 1, -32(1)587; FMF-NEXT: std 0, 48(1)588; FMF-NEXT: bl log2589; FMF-NEXT: nop590; FMF-NEXT: addi 1, 1, 32591; FMF-NEXT: ld 0, 16(1)592; FMF-NEXT: mtlr 0593; FMF-NEXT: blr594;595; GLOBAL-LABEL: log2_approx:596; GLOBAL: # %bb.0:597; GLOBAL-NEXT: mflr 0598; GLOBAL-NEXT: stdu 1, -32(1)599; GLOBAL-NEXT: std 0, 48(1)600; GLOBAL-NEXT: bl log2601; GLOBAL-NEXT: nop602; GLOBAL-NEXT: addi 1, 1, 32603; GLOBAL-NEXT: ld 0, 16(1)604; GLOBAL-NEXT: mtlr 0605; GLOBAL-NEXT: blr606 %r = call afn double @log2(double %x)607 ret double %r608}609 610; -(X - Y) --> (Y - X)611 612; FMFDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fneg_fsub_nozeros_1:'613; FMFDEBUG: fsub nsz {{t[0-9]+}}, {{t[0-9]+}}614; FMFDEBUG: Type-legalized selection DAG: %bb.0 'fneg_fsub_nozeros_1:'615 616; GLOBALDEBUG-LABEL: Optimized lowered selection DAG: %bb.0 'fneg_fsub_nozeros_1:'617; GLOBALDEBUG: fsub nsz {{t[0-9]+}}, {{t[0-9]+}}618; GLOBALDEBUG: Type-legalized selection DAG: %bb.0 'fneg_fsub_nozeros_1:'619 620define float @fneg_fsub_nozeros_1(float %x, float %y, float %z) {621; FMF-LABEL: fneg_fsub_nozeros_1:622; FMF: # %bb.0:623; FMF-NEXT: xssubsp 1, 2, 1624; FMF-NEXT: blr625;626; GLOBAL-LABEL: fneg_fsub_nozeros_1:627; GLOBAL: # %bb.0:628; GLOBAL-NEXT: xssubsp 1, 2, 1629; GLOBAL-NEXT: blr630 %neg = fsub float %x, %y631 %add = fsub nsz float 0.0, %neg632 ret float %add633}634 635attributes #0 = { "denormal-fp-math"="ieee,ieee" }636attributes #1 = { "denormal-fp-math"="preserve-sign,preserve-sign" }637;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:638; FMFDEBUG: {{.*}}639; GLOBALDEBUG: {{.*}}640