1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 < %s | FileCheck -check-prefix=GCN %s 3; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx1010 < %s | FileCheck -check-prefix=GFX10 %s 4 5define double @v_constained_fma_f64_fpexcept_strict(double %x, double %y, double %z) #0 { 6; GCN-LABEL: v_constained_fma_f64_fpexcept_strict: 7; GCN: ; %bb.0: 8; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 9; GCN-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 10; GCN-NEXT: s_setpc_b64 s[30:31] 11; 12; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict: 13; GFX10: ; %bb.0: 14; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 15; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 16; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 17; GFX10-NEXT: s_setpc_b64 s[30:31] 18 %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 19 ret double %val 20} 21 22define <2 x double> @v_constained_fma_v2f64_fpexcept_strict(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 { 23; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict: 24; GCN: ; %bb.0: 25; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 26; GCN-NEXT: v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9] 27; GCN-NEXT: v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11] 28; GCN-NEXT: s_setpc_b64 s[30:31] 29; 30; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict: 31; GFX10: ; %bb.0: 32; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 33; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 34; GFX10-NEXT: v_mov_b32_e32 v13, v3 35; GFX10-NEXT: v_mov_b32_e32 v12, v2 36; GFX10-NEXT: v_mov_b32_e32 v15, v1 37; GFX10-NEXT: v_mov_b32_e32 v14, v0 38; GFX10-NEXT: v_fma_f64 v[2:3], v[12:13], v[6:7], v[10:11] 39; GFX10-NEXT: v_fma_f64 v[0:1], v[14:15], v[4:5], v[8:9] 40; GFX10-NEXT: s_setpc_b64 s[30:31] 41 %val = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 42 ret <2 x double> %val 43} 44 45define <3 x double> @v_constained_fma_v3f64_fpexcept_strict(<3 x double> %x, <3 x double> %y, <3 x double> %z) #0 { 46; GCN-LABEL: v_constained_fma_v3f64_fpexcept_strict: 47; GCN: ; %bb.0: 48; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 49; GCN-NEXT: v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13] 50; GCN-NEXT: v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15] 51; GCN-NEXT: v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17] 52; GCN-NEXT: s_setpc_b64 s[30:31] 53; 54; GFX10-LABEL: v_constained_fma_v3f64_fpexcept_strict: 55; GFX10: ; %bb.0: 56; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 57; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 58; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[6:7], v[12:13] 59; GFX10-NEXT: v_fma_f64 v[2:3], v[2:3], v[8:9], v[14:15] 60; GFX10-NEXT: v_fma_f64 v[4:5], v[4:5], v[10:11], v[16:17] 61; GFX10-NEXT: s_setpc_b64 s[30:31] 62 %val = call <3 x double> @llvm.experimental.constrained.fma.v3f64(<3 x double> %x, <3 x double> %y, <3 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 63 ret <3 x double> %val 64} 65 66define <4 x double> @v_constained_fma_v4f64_fpexcept_strict(<4 x double> %x, <4 x double> %y, <4 x double> %z) #0 { 67; GCN-LABEL: v_constained_fma_v4f64_fpexcept_strict: 68; GCN: ; %bb.0: 69; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 70; GCN-NEXT: v_fma_f64 v[0:1], v[0:1], v[8:9], v[16:17] 71; GCN-NEXT: v_fma_f64 v[2:3], v[2:3], v[10:11], v[18:19] 72; GCN-NEXT: v_fma_f64 v[4:5], v[4:5], v[12:13], v[20:21] 73; GCN-NEXT: v_fma_f64 v[6:7], v[6:7], v[14:15], v[22:23] 74; GCN-NEXT: s_setpc_b64 s[30:31] 75; 76; GFX10-LABEL: v_constained_fma_v4f64_fpexcept_strict: 77; GFX10: ; %bb.0: 78; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 79; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 80; GFX10-NEXT: v_mov_b32_e32 v29, v7 81; GFX10-NEXT: v_mov_b32_e32 v28, v6 82; GFX10-NEXT: v_mov_b32_e32 v31, v5 83; GFX10-NEXT: v_mov_b32_e32 v30, v4 84; GFX10-NEXT: v_mov_b32_e32 v25, v3 85; GFX10-NEXT: v_mov_b32_e32 v24, v2 86; GFX10-NEXT: v_mov_b32_e32 v27, v1 87; GFX10-NEXT: v_mov_b32_e32 v26, v0 88; GFX10-NEXT: v_fma_f64 v[4:5], v[30:31], v[12:13], v[20:21] 89; GFX10-NEXT: v_fma_f64 v[6:7], v[28:29], v[14:15], v[22:23] 90; GFX10-NEXT: v_fma_f64 v[2:3], v[24:25], v[10:11], v[18:19] 91; GFX10-NEXT: v_fma_f64 v[0:1], v[26:27], v[8:9], v[16:17] 92; GFX10-NEXT: s_setpc_b64 s[30:31] 93 %val = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %x, <4 x double> %y, <4 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 94 ret <4 x double> %val 95} 96 97define double @v_constained_fma_f64_fpexcept_strict_fneg(double %x, double %y, double %z) #0 { 98; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg: 99; GCN: ; %bb.0: 100; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 101; GCN-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 102; GCN-NEXT: s_setpc_b64 s[30:31] 103; 104; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg: 105; GFX10: ; %bb.0: 106; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 107; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 108; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 109; GFX10-NEXT: s_setpc_b64 s[30:31] 110 %neg.z = fneg double %z 111 %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %neg.z, metadata !"round.tonearest", metadata !"fpexcept.strict") 112 ret double %val 113} 114 115define double @v_constained_fma_f64_fpexcept_strict_fneg_fneg(double %x, double %y, double %z) #0 { 116; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg: 117; GCN: ; %bb.0: 118; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 119; GCN-NEXT: v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5] 120; GCN-NEXT: s_setpc_b64 s[30:31] 121; 122; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fneg_fneg: 123; GFX10: ; %bb.0: 124; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 125; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 126; GFX10-NEXT: v_fma_f64 v[0:1], -v[0:1], -v[2:3], v[4:5] 127; GFX10-NEXT: s_setpc_b64 s[30:31] 128 %neg.x = fneg double %x 129 %neg.y = fneg double %y 130 %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 131 ret double %val 132} 133 134define double @v_constained_fma_f64_fpexcept_strict_fabs_fabs(double %x, double %y, double %z) #0 { 135; GCN-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs: 136; GCN: ; %bb.0: 137; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 138; GCN-NEXT: v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5] 139; GCN-NEXT: s_setpc_b64 s[30:31] 140; 141; GFX10-LABEL: v_constained_fma_f64_fpexcept_strict_fabs_fabs: 142; GFX10: ; %bb.0: 143; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 144; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 145; GFX10-NEXT: v_fma_f64 v[0:1], |v[0:1]|, |v[2:3]|, v[4:5] 146; GFX10-NEXT: s_setpc_b64 s[30:31] 147 %neg.x = call double @llvm.fabs.f64(double %x) 148 %neg.y = call double @llvm.fabs.f64(double %y) 149 %val = call double @llvm.experimental.constrained.fma.f64(double %neg.x, double %neg.y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 150 ret double %val 151} 152 153define <2 x double> @v_constained_fma_v2f64_fpexcept_strict_fneg_fneg(<2 x double> %x, <2 x double> %y, <2 x double> %z) #0 { 154; GCN-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg: 155; GCN: ; %bb.0: 156; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 157; GCN-NEXT: v_fma_f64 v[0:1], -v[0:1], -v[4:5], v[8:9] 158; GCN-NEXT: v_fma_f64 v[2:3], -v[2:3], -v[6:7], v[10:11] 159; GCN-NEXT: s_setpc_b64 s[30:31] 160; 161; GFX10-LABEL: v_constained_fma_v2f64_fpexcept_strict_fneg_fneg: 162; GFX10: ; %bb.0: 163; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 164; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 165; GFX10-NEXT: v_mov_b32_e32 v13, v3 166; GFX10-NEXT: v_mov_b32_e32 v12, v2 167; GFX10-NEXT: v_mov_b32_e32 v15, v1 168; GFX10-NEXT: v_mov_b32_e32 v14, v0 169; GFX10-NEXT: v_fma_f64 v[2:3], -v[12:13], -v[6:7], v[10:11] 170; GFX10-NEXT: v_fma_f64 v[0:1], -v[14:15], -v[4:5], v[8:9] 171; GFX10-NEXT: s_setpc_b64 s[30:31] 172 %neg.x = fneg <2 x double> %x 173 %neg.y = fneg <2 x double> %y 174 %val = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %neg.x, <2 x double> %neg.y, <2 x double> %z, metadata !"round.tonearest", metadata !"fpexcept.strict") 175 ret <2 x double> %val 176} 177 178declare double @llvm.fabs.f64(double) #1 179declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata) #1 180declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata) #1 181declare <3 x double> @llvm.experimental.constrained.fma.v3f64(<3 x double>, <3 x double>, <3 x double>, metadata, metadata) #1 182declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata) #1 183 184attributes #0 = { strictfp } 185attributes #1 = { inaccessiblememonly nounwind willreturn } 186