1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -global-isel -march=amdgcn -mcpu=tahiti < %s | FileCheck -check-prefix=GFX6 %s 3; RUN: llc -global-isel -march=amdgcn -mcpu=fiji < %s | FileCheck -check-prefix=GFX8 %s 4; RUN: llc -global-isel -march=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefix=GFX9 %s 5; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1010 < %s | FileCheck -check-prefix=GFX10 %s 6; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1100 -amdgpu-enable-delay-alu=0 < %s | FileCheck -check-prefix=GFX10 %s 7 8define float @v_fma_f32(float %x, float %y, float %z) { 9; GFX6-LABEL: v_fma_f32: 10; GFX6: ; %bb.0: 11; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 12; GFX6-NEXT: v_fma_f32 v0, v0, v1, v2 13; GFX6-NEXT: s_setpc_b64 s[30:31] 14; 15; GFX8-LABEL: v_fma_f32: 16; GFX8: ; %bb.0: 17; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 18; GFX8-NEXT: v_fma_f32 v0, v0, v1, v2 19; GFX8-NEXT: s_setpc_b64 s[30:31] 20; 21; GFX9-LABEL: v_fma_f32: 22; GFX9: ; %bb.0: 23; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 24; GFX9-NEXT: v_fma_f32 v0, v0, v1, v2 25; GFX9-NEXT: s_setpc_b64 s[30:31] 26; 27; GFX10-LABEL: v_fma_f32: 28; GFX10: ; %bb.0: 29; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 30; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 31; GFX10-NEXT: v_fma_f32 v0, v0, v1, v2 32; GFX10-NEXT: s_setpc_b64 s[30:31] 33 %fma = call float @llvm.fma.f32(float %x, float %y, float %z) 34 ret float %fma 35} 36 37define <2 x float> @v_fma_v2f32(<2 x float> %x, <2 x float> %y, <2 x float> %z) { 38; GFX6-LABEL: v_fma_v2f32: 39; GFX6: ; %bb.0: 40; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 41; GFX6-NEXT: v_fma_f32 v0, v0, v2, v4 42; GFX6-NEXT: v_fma_f32 v1, v1, v3, v5 43; GFX6-NEXT: s_setpc_b64 s[30:31] 44; 45; GFX8-LABEL: v_fma_v2f32: 46; GFX8: ; %bb.0: 47; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 48; GFX8-NEXT: v_fma_f32 v0, v0, v2, v4 49; GFX8-NEXT: v_fma_f32 v1, v1, v3, v5 50; GFX8-NEXT: s_setpc_b64 s[30:31] 51; 52; GFX9-LABEL: v_fma_v2f32: 53; GFX9: ; %bb.0: 54; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 55; GFX9-NEXT: v_fma_f32 v0, v0, v2, v4 56; GFX9-NEXT: v_fma_f32 v1, v1, v3, v5 57; GFX9-NEXT: s_setpc_b64 s[30:31] 58; 59; GFX10-LABEL: v_fma_v2f32: 60; GFX10: ; %bb.0: 61; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 62; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 63; GFX10-NEXT: v_fma_f32 v0, v0, v2, v4 64; GFX10-NEXT: v_fma_f32 v1, v1, v3, v5 65; GFX10-NEXT: s_setpc_b64 s[30:31] 66 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> %y, <2 x float> %z) 67 ret <2 x float> %fma 68} 69 70define half @v_fma_f16(half %x, half %y, half %z) { 71; GFX6-LABEL: v_fma_f16: 72; GFX6: ; %bb.0: 73; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 74; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 75; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 76; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 77; GFX6-NEXT: v_fma_f32 v0, v0, v1, v2 78; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 79; GFX6-NEXT: s_setpc_b64 s[30:31] 80; 81; GFX8-LABEL: v_fma_f16: 82; GFX8: ; %bb.0: 83; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 84; GFX8-NEXT: v_fma_f16 v0, v0, v1, v2 85; GFX8-NEXT: s_setpc_b64 s[30:31] 86; 87; GFX9-LABEL: v_fma_f16: 88; GFX9: ; %bb.0: 89; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 90; GFX9-NEXT: v_fma_f16 v0, v0, v1, v2 91; GFX9-NEXT: s_setpc_b64 s[30:31] 92; 93; GFX10-LABEL: v_fma_f16: 94; GFX10: ; %bb.0: 95; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 96; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 97; GFX10-NEXT: v_fma_f16 v0, v0, v1, v2 98; GFX10-NEXT: s_setpc_b64 s[30:31] 99 %fma = call half @llvm.fma.f16(half %x, half %y, half %z) 100 ret half %fma 101} 102 103define <2 x half> @v_fma_v2f16(<2 x half> %x, <2 x half> %y, <2 x half> %z) { 104; GFX6-LABEL: v_fma_v2f16: 105; GFX6: ; %bb.0: 106; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 107; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 108; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 109; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v4 110; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 111; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3 112; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v5 113; GFX6-NEXT: v_fma_f32 v0, v0, v2, v4 114; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 115; GFX6-NEXT: v_fma_f32 v1, v1, v3, v5 116; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1 117; GFX6-NEXT: s_setpc_b64 s[30:31] 118; 119; GFX8-LABEL: v_fma_v2f16: 120; GFX8: ; %bb.0: 121; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 122; GFX8-NEXT: v_lshrrev_b32_e32 v3, 16, v0 123; GFX8-NEXT: v_lshrrev_b32_e32 v4, 16, v1 124; GFX8-NEXT: v_lshrrev_b32_e32 v5, 16, v2 125; GFX8-NEXT: v_fma_f16 v0, v0, v1, v2 126; GFX8-NEXT: v_fma_f16 v1, v3, v4, v5 127; GFX8-NEXT: v_mov_b32_e32 v2, 16 128; GFX8-NEXT: v_lshlrev_b32_sdwa v1, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 129; GFX8-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 130; GFX8-NEXT: s_setpc_b64 s[30:31] 131; 132; GFX9-LABEL: v_fma_v2f16: 133; GFX9: ; %bb.0: 134; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 135; GFX9-NEXT: v_pk_fma_f16 v0, v0, v1, v2 136; GFX9-NEXT: s_setpc_b64 s[30:31] 137; 138; GFX10-LABEL: v_fma_v2f16: 139; GFX10: ; %bb.0: 140; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 141; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 142; GFX10-NEXT: v_pk_fma_f16 v0, v0, v1, v2 143; GFX10-NEXT: s_setpc_b64 s[30:31] 144 %fma = call <2 x half> @llvm.fma.v2f16(<2 x half> %x, <2 x half> %y, <2 x half> %z) 145 ret <2 x half> %fma 146} 147 148define <2 x half> @v_fma_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y, <2 x half> %z) { 149; GFX6-LABEL: v_fma_v2f16_fneg_lhs: 150; GFX6: ; %bb.0: 151; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 152; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1 153; GFX6-NEXT: v_and_b32_e32 v0, 0xffff, v0 154; GFX6-NEXT: v_or_b32_e32 v0, v1, v0 155; GFX6-NEXT: v_xor_b32_e32 v0, 0x80008000, v0 156; GFX6-NEXT: v_lshrrev_b32_e32 v1, 16, v0 157; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 158; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 159; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v4 160; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 161; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3 162; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v5 163; GFX6-NEXT: v_fma_f32 v0, v0, v2, v4 164; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 165; GFX6-NEXT: v_fma_f32 v1, v1, v3, v5 166; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1 167; GFX6-NEXT: s_setpc_b64 s[30:31] 168; 169; GFX8-LABEL: v_fma_v2f16_fneg_lhs: 170; GFX8: ; %bb.0: 171; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 172; GFX8-NEXT: v_xor_b32_e32 v0, 0x80008000, v0 173; GFX8-NEXT: v_lshrrev_b32_e32 v3, 16, v0 174; GFX8-NEXT: v_lshrrev_b32_e32 v4, 16, v1 175; GFX8-NEXT: v_lshrrev_b32_e32 v5, 16, v2 176; GFX8-NEXT: v_fma_f16 v0, v0, v1, v2 177; GFX8-NEXT: v_fma_f16 v1, v3, v4, v5 178; GFX8-NEXT: v_mov_b32_e32 v2, 16 179; GFX8-NEXT: v_lshlrev_b32_sdwa v1, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 180; GFX8-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 181; GFX8-NEXT: s_setpc_b64 s[30:31] 182; 183; GFX9-LABEL: v_fma_v2f16_fneg_lhs: 184; GFX9: ; %bb.0: 185; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 186; GFX9-NEXT: v_pk_fma_f16 v0, v0, v1, v2 neg_lo:[1,0,0] neg_hi:[1,0,0] 187; GFX9-NEXT: s_setpc_b64 s[30:31] 188; 189; GFX10-LABEL: v_fma_v2f16_fneg_lhs: 190; GFX10: ; %bb.0: 191; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 192; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 193; GFX10-NEXT: v_pk_fma_f16 v0, v0, v1, v2 neg_lo:[1,0,0] neg_hi:[1,0,0] 194; GFX10-NEXT: s_setpc_b64 s[30:31] 195 %x.fneg = fneg <2 x half> %x 196 %fma = call <2 x half> @llvm.fma.v2f16(<2 x half> %x.fneg, <2 x half> %y, <2 x half> %z) 197 ret <2 x half> %fma 198} 199 200define <2 x half> @v_fma_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y, <2 x half> %z) { 201; GFX6-LABEL: v_fma_v2f16_fneg_rhs: 202; GFX6: ; %bb.0: 203; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 204; GFX6-NEXT: v_lshlrev_b32_e32 v3, 16, v3 205; GFX6-NEXT: v_and_b32_e32 v2, 0xffff, v2 206; GFX6-NEXT: v_or_b32_e32 v2, v3, v2 207; GFX6-NEXT: v_xor_b32_e32 v2, 0x80008000, v2 208; GFX6-NEXT: v_lshrrev_b32_e32 v3, 16, v2 209; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 210; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 211; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v4 212; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 213; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3 214; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v5 215; GFX6-NEXT: v_fma_f32 v0, v0, v2, v4 216; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 217; GFX6-NEXT: v_fma_f32 v1, v1, v3, v5 218; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1 219; GFX6-NEXT: s_setpc_b64 s[30:31] 220; 221; GFX8-LABEL: v_fma_v2f16_fneg_rhs: 222; GFX8: ; %bb.0: 223; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 224; GFX8-NEXT: v_xor_b32_e32 v1, 0x80008000, v1 225; GFX8-NEXT: v_lshrrev_b32_e32 v3, 16, v0 226; GFX8-NEXT: v_lshrrev_b32_e32 v4, 16, v1 227; GFX8-NEXT: v_lshrrev_b32_e32 v5, 16, v2 228; GFX8-NEXT: v_fma_f16 v0, v0, v1, v2 229; GFX8-NEXT: v_fma_f16 v1, v3, v4, v5 230; GFX8-NEXT: v_mov_b32_e32 v2, 16 231; GFX8-NEXT: v_lshlrev_b32_sdwa v1, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 232; GFX8-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 233; GFX8-NEXT: s_setpc_b64 s[30:31] 234; 235; GFX9-LABEL: v_fma_v2f16_fneg_rhs: 236; GFX9: ; %bb.0: 237; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 238; GFX9-NEXT: v_pk_fma_f16 v0, v0, v1, v2 neg_lo:[0,1,0] neg_hi:[0,1,0] 239; GFX9-NEXT: s_setpc_b64 s[30:31] 240; 241; GFX10-LABEL: v_fma_v2f16_fneg_rhs: 242; GFX10: ; %bb.0: 243; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 244; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 245; GFX10-NEXT: v_pk_fma_f16 v0, v0, v1, v2 neg_lo:[0,1,0] neg_hi:[0,1,0] 246; GFX10-NEXT: s_setpc_b64 s[30:31] 247 %y.fneg = fneg <2 x half> %y 248 %fma = call <2 x half> @llvm.fma.v2f16(<2 x half> %x, <2 x half> %y.fneg, <2 x half> %z) 249 ret <2 x half> %fma 250} 251 252define <2 x half> @v_fma_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y, <2 x half> %z) { 253; GFX6-LABEL: v_fma_v2f16_fneg_lhs_rhs: 254; GFX6: ; %bb.0: 255; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 256; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 257; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 258; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v4 259; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 260; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3 261; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v5 262; GFX6-NEXT: v_fma_f32 v0, v0, v2, v4 263; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 264; GFX6-NEXT: v_fma_f32 v1, v1, v3, v5 265; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1 266; GFX6-NEXT: s_setpc_b64 s[30:31] 267; 268; GFX8-LABEL: v_fma_v2f16_fneg_lhs_rhs: 269; GFX8: ; %bb.0: 270; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 271; GFX8-NEXT: v_lshrrev_b32_e32 v3, 16, v0 272; GFX8-NEXT: v_lshrrev_b32_e32 v4, 16, v1 273; GFX8-NEXT: v_lshrrev_b32_e32 v5, 16, v2 274; GFX8-NEXT: v_fma_f16 v0, v0, v1, v2 275; GFX8-NEXT: v_fma_f16 v1, v3, v4, v5 276; GFX8-NEXT: v_mov_b32_e32 v2, 16 277; GFX8-NEXT: v_lshlrev_b32_sdwa v1, v2, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 278; GFX8-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 279; GFX8-NEXT: s_setpc_b64 s[30:31] 280; 281; GFX9-LABEL: v_fma_v2f16_fneg_lhs_rhs: 282; GFX9: ; %bb.0: 283; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 284; GFX9-NEXT: v_pk_fma_f16 v0, v0, v1, v2 285; GFX9-NEXT: s_setpc_b64 s[30:31] 286; 287; GFX10-LABEL: v_fma_v2f16_fneg_lhs_rhs: 288; GFX10: ; %bb.0: 289; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 290; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 291; GFX10-NEXT: v_pk_fma_f16 v0, v0, v1, v2 292; GFX10-NEXT: s_setpc_b64 s[30:31] 293 %x.fneg = fneg <2 x half> %x 294 %y.fneg = fneg <2 x half> %y 295 %fma = call <2 x half> @llvm.fma.v2f16(<2 x half> %x.fneg, <2 x half> %y.fneg, <2 x half> %z) 296 ret <2 x half> %fma 297} 298 299; FIXME: 300; define <3 x half> @v_fma_v3f16(<3 x half> %x, <3 x half> %y, <3 x half> %z) { 301; %fma = call <3 x half> @llvm.fma.v3f16(<3 x half> %x, <3 x half> %y, <3 x half> %z) 302; ret <3 x half> %fma 303; } 304 305define <4 x half> @v_fma_v4f16(<4 x half> %x, <4 x half> %y, <4 x half> %z) { 306; GFX6-LABEL: v_fma_v4f16: 307; GFX6: ; %bb.0: 308; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 309; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0 310; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v4 311; GFX6-NEXT: v_cvt_f32_f16_e32 v8, v8 312; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1 313; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v5 314; GFX6-NEXT: v_cvt_f32_f16_e32 v9, v9 315; GFX6-NEXT: v_fma_f32 v0, v0, v4, v8 316; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2 317; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v6 318; GFX6-NEXT: v_fma_f32 v1, v1, v5, v9 319; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v10 320; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3 321; GFX6-NEXT: v_cvt_f32_f16_e32 v6, v7 322; GFX6-NEXT: v_cvt_f32_f16_e32 v7, v11 323; GFX6-NEXT: v_fma_f32 v2, v2, v4, v5 324; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0 325; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1 326; GFX6-NEXT: v_fma_f32 v3, v3, v6, v7 327; GFX6-NEXT: v_cvt_f16_f32_e32 v2, v2 328; GFX6-NEXT: v_cvt_f16_f32_e32 v3, v3 329; GFX6-NEXT: s_setpc_b64 s[30:31] 330; 331; GFX8-LABEL: v_fma_v4f16: 332; GFX8: ; %bb.0: 333; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 334; GFX8-NEXT: v_lshrrev_b32_e32 v6, 16, v0 335; GFX8-NEXT: v_lshrrev_b32_e32 v8, 16, v2 336; GFX8-NEXT: v_lshrrev_b32_e32 v10, 16, v4 337; GFX8-NEXT: v_lshrrev_b32_e32 v7, 16, v1 338; GFX8-NEXT: v_lshrrev_b32_e32 v9, 16, v3 339; GFX8-NEXT: v_lshrrev_b32_e32 v11, 16, v5 340; GFX8-NEXT: v_fma_f16 v0, v0, v2, v4 341; GFX8-NEXT: v_fma_f16 v2, v6, v8, v10 342; GFX8-NEXT: v_mov_b32_e32 v4, 16 343; GFX8-NEXT: v_fma_f16 v1, v1, v3, v5 344; GFX8-NEXT: v_fma_f16 v3, v7, v9, v11 345; GFX8-NEXT: v_lshlrev_b32_sdwa v2, v4, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 346; GFX8-NEXT: v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 347; GFX8-NEXT: v_lshlrev_b32_sdwa v2, v4, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0 348; GFX8-NEXT: v_or_b32_sdwa v1, v1, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD 349; GFX8-NEXT: s_setpc_b64 s[30:31] 350; 351; GFX9-LABEL: v_fma_v4f16: 352; GFX9: ; %bb.0: 353; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 354; GFX9-NEXT: v_pk_fma_f16 v0, v0, v2, v4 355; GFX9-NEXT: v_pk_fma_f16 v1, v1, v3, v5 356; GFX9-NEXT: s_setpc_b64 s[30:31] 357; 358; GFX10-LABEL: v_fma_v4f16: 359; GFX10: ; %bb.0: 360; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 361; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 362; GFX10-NEXT: v_pk_fma_f16 v0, v0, v2, v4 363; GFX10-NEXT: v_pk_fma_f16 v1, v1, v3, v5 364; GFX10-NEXT: s_setpc_b64 s[30:31] 365 %fma = call <4 x half> @llvm.fma.v4f16(<4 x half> %x, <4 x half> %y, <4 x half> %z) 366 ret <4 x half> %fma 367} 368 369define double @v_fma_f64(double %x, double %y, double %z) { 370; GFX6-LABEL: v_fma_f64: 371; GFX6: ; %bb.0: 372; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 373; GFX6-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 374; GFX6-NEXT: s_setpc_b64 s[30:31] 375; 376; GFX8-LABEL: v_fma_f64: 377; GFX8: ; %bb.0: 378; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 379; GFX8-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 380; GFX8-NEXT: s_setpc_b64 s[30:31] 381; 382; GFX9-LABEL: v_fma_f64: 383; GFX9: ; %bb.0: 384; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 385; GFX9-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 386; GFX9-NEXT: s_setpc_b64 s[30:31] 387; 388; GFX10-LABEL: v_fma_f64: 389; GFX10: ; %bb.0: 390; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 391; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 392; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], v[4:5] 393; GFX10-NEXT: s_setpc_b64 s[30:31] 394 %fma = call double @llvm.fma.f64(double %x, double %y, double %z) 395 ret double %fma 396} 397 398define double @v_fma_f64_fneg_all(double %x, double %y, double %z) { 399; GFX6-LABEL: v_fma_f64_fneg_all: 400; GFX6: ; %bb.0: 401; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 402; GFX6-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 403; GFX6-NEXT: s_setpc_b64 s[30:31] 404; 405; GFX8-LABEL: v_fma_f64_fneg_all: 406; GFX8: ; %bb.0: 407; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 408; GFX8-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 409; GFX8-NEXT: s_setpc_b64 s[30:31] 410; 411; GFX9-LABEL: v_fma_f64_fneg_all: 412; GFX9: ; %bb.0: 413; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 414; GFX9-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 415; GFX9-NEXT: s_setpc_b64 s[30:31] 416; 417; GFX10-LABEL: v_fma_f64_fneg_all: 418; GFX10: ; %bb.0: 419; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 420; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 421; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[2:3], -v[4:5] 422; GFX10-NEXT: s_setpc_b64 s[30:31] 423 %neg.x = fneg double %x 424 %neg.y = fneg double %y 425 %neg.z = fneg double %z 426 %fma = call double @llvm.fma.f64(double %neg.x, double %neg.y, double %neg.z) 427 ret double %fma 428} 429 430define <2 x double> @v_fma_v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z) { 431; GFX6-LABEL: v_fma_v2f64: 432; GFX6: ; %bb.0: 433; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 434; GFX6-NEXT: v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9] 435; GFX6-NEXT: v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11] 436; GFX6-NEXT: s_setpc_b64 s[30:31] 437; 438; GFX8-LABEL: v_fma_v2f64: 439; GFX8: ; %bb.0: 440; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 441; GFX8-NEXT: v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9] 442; GFX8-NEXT: v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11] 443; GFX8-NEXT: s_setpc_b64 s[30:31] 444; 445; GFX9-LABEL: v_fma_v2f64: 446; GFX9: ; %bb.0: 447; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 448; GFX9-NEXT: v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9] 449; GFX9-NEXT: v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11] 450; GFX9-NEXT: s_setpc_b64 s[30:31] 451; 452; GFX10-LABEL: v_fma_v2f64: 453; GFX10: ; %bb.0: 454; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 455; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 456; GFX10-NEXT: v_fma_f64 v[0:1], v[0:1], v[4:5], v[8:9] 457; GFX10-NEXT: v_fma_f64 v[2:3], v[2:3], v[6:7], v[10:11] 458; GFX10-NEXT: s_setpc_b64 s[30:31] 459 %fma = call <2 x double> @llvm.fma.v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z) 460 ret <2 x double> %fma 461} 462 463define float @v_fma_f32_fabs_lhs(float %x, float %y, float %z) { 464; GFX6-LABEL: v_fma_f32_fabs_lhs: 465; GFX6: ; %bb.0: 466; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 467; GFX6-NEXT: v_fma_f32 v0, |v0|, v1, v2 468; GFX6-NEXT: s_setpc_b64 s[30:31] 469; 470; GFX8-LABEL: v_fma_f32_fabs_lhs: 471; GFX8: ; %bb.0: 472; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 473; GFX8-NEXT: v_fma_f32 v0, |v0|, v1, v2 474; GFX8-NEXT: s_setpc_b64 s[30:31] 475; 476; GFX9-LABEL: v_fma_f32_fabs_lhs: 477; GFX9: ; %bb.0: 478; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 479; GFX9-NEXT: v_fma_f32 v0, |v0|, v1, v2 480; GFX9-NEXT: s_setpc_b64 s[30:31] 481; 482; GFX10-LABEL: v_fma_f32_fabs_lhs: 483; GFX10: ; %bb.0: 484; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 485; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 486; GFX10-NEXT: v_fma_f32 v0, |v0|, v1, v2 487; GFX10-NEXT: s_setpc_b64 s[30:31] 488 %fabs.x = call float @llvm.fabs.f32(float %x) 489 %fma = call float @llvm.fma.f32(float %fabs.x, float %y, float %z) 490 ret float %fma 491} 492 493define float @v_fma_f32_fabs_rhs(float %x, float %y, float %z) { 494; GFX6-LABEL: v_fma_f32_fabs_rhs: 495; GFX6: ; %bb.0: 496; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 497; GFX6-NEXT: v_fma_f32 v0, v0, |v1|, v2 498; GFX6-NEXT: s_setpc_b64 s[30:31] 499; 500; GFX8-LABEL: v_fma_f32_fabs_rhs: 501; GFX8: ; %bb.0: 502; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 503; GFX8-NEXT: v_fma_f32 v0, v0, |v1|, v2 504; GFX8-NEXT: s_setpc_b64 s[30:31] 505; 506; GFX9-LABEL: v_fma_f32_fabs_rhs: 507; GFX9: ; %bb.0: 508; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 509; GFX9-NEXT: v_fma_f32 v0, v0, |v1|, v2 510; GFX9-NEXT: s_setpc_b64 s[30:31] 511; 512; GFX10-LABEL: v_fma_f32_fabs_rhs: 513; GFX10: ; %bb.0: 514; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 515; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 516; GFX10-NEXT: v_fma_f32 v0, v0, |v1|, v2 517; GFX10-NEXT: s_setpc_b64 s[30:31] 518 %fabs.y = call float @llvm.fabs.f32(float %y) 519 %fma = call float @llvm.fma.f32(float %x, float %fabs.y, float %z) 520 ret float %fma 521} 522 523define float @v_fma_f32_fabs_lhs_rhs(float %x, float %y, float %z) { 524; GFX6-LABEL: v_fma_f32_fabs_lhs_rhs: 525; GFX6: ; %bb.0: 526; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 527; GFX6-NEXT: v_fma_f32 v0, |v0|, |v1|, v2 528; GFX6-NEXT: s_setpc_b64 s[30:31] 529; 530; GFX8-LABEL: v_fma_f32_fabs_lhs_rhs: 531; GFX8: ; %bb.0: 532; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 533; GFX8-NEXT: v_fma_f32 v0, |v0|, |v1|, v2 534; GFX8-NEXT: s_setpc_b64 s[30:31] 535; 536; GFX9-LABEL: v_fma_f32_fabs_lhs_rhs: 537; GFX9: ; %bb.0: 538; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 539; GFX9-NEXT: v_fma_f32 v0, |v0|, |v1|, v2 540; GFX9-NEXT: s_setpc_b64 s[30:31] 541; 542; GFX10-LABEL: v_fma_f32_fabs_lhs_rhs: 543; GFX10: ; %bb.0: 544; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 545; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 546; GFX10-NEXT: v_fma_f32 v0, |v0|, |v1|, v2 547; GFX10-NEXT: s_setpc_b64 s[30:31] 548 %fabs.x = call float @llvm.fabs.f32(float %x) 549 %fabs.y = call float @llvm.fabs.f32(float %y) 550 %fma = call float @llvm.fma.f32(float %fabs.x, float %fabs.y, float %z) 551 ret float %fma 552} 553 554define amdgpu_ps float @v_fma_f32_sgpr_vgpr_vgpr(float inreg %x, float %y, float %z) { 555; GFX6-LABEL: v_fma_f32_sgpr_vgpr_vgpr: 556; GFX6: ; %bb.0: 557; GFX6-NEXT: v_fma_f32 v0, s0, v0, v1 558; GFX6-NEXT: ; return to shader part epilog 559; 560; GFX8-LABEL: v_fma_f32_sgpr_vgpr_vgpr: 561; GFX8: ; %bb.0: 562; GFX8-NEXT: v_fma_f32 v0, s0, v0, v1 563; GFX8-NEXT: ; return to shader part epilog 564; 565; GFX9-LABEL: v_fma_f32_sgpr_vgpr_vgpr: 566; GFX9: ; %bb.0: 567; GFX9-NEXT: v_fma_f32 v0, s0, v0, v1 568; GFX9-NEXT: ; return to shader part epilog 569; 570; GFX10-LABEL: v_fma_f32_sgpr_vgpr_vgpr: 571; GFX10: ; %bb.0: 572; GFX10-NEXT: v_fma_f32 v0, s0, v0, v1 573; GFX10-NEXT: ; return to shader part epilog 574 %fma = call float @llvm.fma.f32(float %x, float %y, float %z) 575 ret float %fma 576} 577 578define amdgpu_ps float @v_fma_f32_vgpr_sgpr_vgpr(float %x, float inreg %y, float %z) { 579; GFX6-LABEL: v_fma_f32_vgpr_sgpr_vgpr: 580; GFX6: ; %bb.0: 581; GFX6-NEXT: v_fma_f32 v0, v0, s0, v1 582; GFX6-NEXT: ; return to shader part epilog 583; 584; GFX8-LABEL: v_fma_f32_vgpr_sgpr_vgpr: 585; GFX8: ; %bb.0: 586; GFX8-NEXT: v_fma_f32 v0, v0, s0, v1 587; GFX8-NEXT: ; return to shader part epilog 588; 589; GFX9-LABEL: v_fma_f32_vgpr_sgpr_vgpr: 590; GFX9: ; %bb.0: 591; GFX9-NEXT: v_fma_f32 v0, v0, s0, v1 592; GFX9-NEXT: ; return to shader part epilog 593; 594; GFX10-LABEL: v_fma_f32_vgpr_sgpr_vgpr: 595; GFX10: ; %bb.0: 596; GFX10-NEXT: v_fma_f32 v0, s0, v0, v1 597; GFX10-NEXT: ; return to shader part epilog 598 %fma = call float @llvm.fma.f32(float %x, float %y, float %z) 599 ret float %fma 600} 601 602define amdgpu_ps float @v_fma_f32_sgpr_sgpr_sgpr(float inreg %x, float inreg %y, float inreg %z) { 603; GFX6-LABEL: v_fma_f32_sgpr_sgpr_sgpr: 604; GFX6: ; %bb.0: 605; GFX6-NEXT: v_mov_b32_e32 v0, s1 606; GFX6-NEXT: v_mov_b32_e32 v1, s2 607; GFX6-NEXT: v_fma_f32 v0, s0, v0, v1 608; GFX6-NEXT: ; return to shader part epilog 609; 610; GFX8-LABEL: v_fma_f32_sgpr_sgpr_sgpr: 611; GFX8: ; %bb.0: 612; GFX8-NEXT: v_mov_b32_e32 v0, s1 613; GFX8-NEXT: v_mov_b32_e32 v1, s2 614; GFX8-NEXT: v_fma_f32 v0, s0, v0, v1 615; GFX8-NEXT: ; return to shader part epilog 616; 617; GFX9-LABEL: v_fma_f32_sgpr_sgpr_sgpr: 618; GFX9: ; %bb.0: 619; GFX9-NEXT: v_mov_b32_e32 v0, s1 620; GFX9-NEXT: v_mov_b32_e32 v1, s2 621; GFX9-NEXT: v_fma_f32 v0, s0, v0, v1 622; GFX9-NEXT: ; return to shader part epilog 623; 624; GFX10-LABEL: v_fma_f32_sgpr_sgpr_sgpr: 625; GFX10: ; %bb.0: 626; GFX10-NEXT: v_mov_b32_e32 v0, s2 627; GFX10-NEXT: v_fma_f32 v0, s1, s0, v0 628; GFX10-NEXT: ; return to shader part epilog 629 %fma = call float @llvm.fma.f32(float %x, float %y, float %z) 630 ret float %fma 631} 632 633define float @v_fma_f32_fneg_lhs(float %x, float %y, float %z) { 634; GFX6-LABEL: v_fma_f32_fneg_lhs: 635; GFX6: ; %bb.0: 636; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 637; GFX6-NEXT: v_fma_f32 v0, -v0, v1, v2 638; GFX6-NEXT: s_setpc_b64 s[30:31] 639; 640; GFX8-LABEL: v_fma_f32_fneg_lhs: 641; GFX8: ; %bb.0: 642; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 643; GFX8-NEXT: v_fma_f32 v0, -v0, v1, v2 644; GFX8-NEXT: s_setpc_b64 s[30:31] 645; 646; GFX9-LABEL: v_fma_f32_fneg_lhs: 647; GFX9: ; %bb.0: 648; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 649; GFX9-NEXT: v_fma_f32 v0, -v0, v1, v2 650; GFX9-NEXT: s_setpc_b64 s[30:31] 651; 652; GFX10-LABEL: v_fma_f32_fneg_lhs: 653; GFX10: ; %bb.0: 654; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 655; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 656; GFX10-NEXT: v_fma_f32 v0, -v0, v1, v2 657; GFX10-NEXT: s_setpc_b64 s[30:31] 658 %neg.x = fneg float %x 659 %fma = call float @llvm.fma.f32(float %neg.x, float %y, float %z) 660 ret float %fma 661} 662 663define float @v_fma_f32_fneg_rhs(float %x, float %y, float %z) { 664; GFX6-LABEL: v_fma_f32_fneg_rhs: 665; GFX6: ; %bb.0: 666; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 667; GFX6-NEXT: v_fma_f32 v0, v0, -v1, v2 668; GFX6-NEXT: s_setpc_b64 s[30:31] 669; 670; GFX8-LABEL: v_fma_f32_fneg_rhs: 671; GFX8: ; %bb.0: 672; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 673; GFX8-NEXT: v_fma_f32 v0, v0, -v1, v2 674; GFX8-NEXT: s_setpc_b64 s[30:31] 675; 676; GFX9-LABEL: v_fma_f32_fneg_rhs: 677; GFX9: ; %bb.0: 678; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 679; GFX9-NEXT: v_fma_f32 v0, v0, -v1, v2 680; GFX9-NEXT: s_setpc_b64 s[30:31] 681; 682; GFX10-LABEL: v_fma_f32_fneg_rhs: 683; GFX10: ; %bb.0: 684; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 685; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 686; GFX10-NEXT: v_fma_f32 v0, v0, -v1, v2 687; GFX10-NEXT: s_setpc_b64 s[30:31] 688 %neg.y = fneg float %y 689 %fma = call float @llvm.fma.f32(float %x, float %neg.y, float %z) 690 ret float %fma 691} 692 693define float @v_fma_f32_fneg_z(float %x, float %y, float %z) { 694; GFX6-LABEL: v_fma_f32_fneg_z: 695; GFX6: ; %bb.0: 696; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 697; GFX6-NEXT: v_fma_f32 v0, v0, v1, -v2 698; GFX6-NEXT: s_setpc_b64 s[30:31] 699; 700; GFX8-LABEL: v_fma_f32_fneg_z: 701; GFX8: ; %bb.0: 702; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 703; GFX8-NEXT: v_fma_f32 v0, v0, v1, -v2 704; GFX8-NEXT: s_setpc_b64 s[30:31] 705; 706; GFX9-LABEL: v_fma_f32_fneg_z: 707; GFX9: ; %bb.0: 708; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 709; GFX9-NEXT: v_fma_f32 v0, v0, v1, -v2 710; GFX9-NEXT: s_setpc_b64 s[30:31] 711; 712; GFX10-LABEL: v_fma_f32_fneg_z: 713; GFX10: ; %bb.0: 714; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) 715; GFX10-NEXT: s_waitcnt_vscnt null, 0x0 716; GFX10-NEXT: v_fma_f32 v0, v0, v1, -v2 717; GFX10-NEXT: s_setpc_b64 s[30:31] 718 %neg.z = fneg float %z 719 %fma = call float @llvm.fma.f32(float %x, float %y, float %neg.z) 720 ret float %fma 721} 722 723declare half @llvm.fma.f16(half, half, half) #0 724declare float @llvm.fma.f32(float, float, float) #0 725declare double @llvm.fma.f64(double, double, double) #0 726 727declare half @llvm.fabs.f16(half) #0 728declare float @llvm.fabs.f32(float) #0 729 730declare <2 x half> @llvm.fma.v2f16(<2 x half>, <2 x half>, <2 x half>) #0 731declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) #0 732declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) #0 733 734declare <3 x half> @llvm.fma.v3f16(<3 x half>, <3 x half>, <3 x half>) #0 735declare <4 x half> @llvm.fma.v4f16(<4 x half>, <4 x half>, <4 x half>) #0 736 737attributes #0 = { nounwind readnone speculatable willreturn } 738