1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s 2; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s 3 4declare half @llvm.fmuladd.f16(half %a, half %b, half %c) 5declare <2 x half> @llvm.fmuladd.v2f16(<2 x half> %a, <2 x half> %b, <2 x half> %c) 6 7; GCN-LABEL: {{^}}fmuladd_f16 8; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] 9; GCN: buffer_load_ushort v[[B_F16:[0-9]+]] 10; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 11; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], v[[A_F16]] 12; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], v[[B_F16]] 13; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 14; SI: v_mac_f32_e32 v[[C_F32]], v[[B_F32]], v[[A_F32]] 15; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[C_F32]] 16; SI: buffer_store_short v[[R_F16]] 17; VI: v_mac_f16_e32 v[[C_F16]], v[[B_F16]], v[[A_F16]] 18; VI: buffer_store_short v[[C_F16]] 19; GCN: s_endpgm 20define void @fmuladd_f16( 21 half addrspace(1)* %r, 22 half addrspace(1)* %a, 23 half addrspace(1)* %b, 24 half addrspace(1)* %c) { 25 %a.val = load half, half addrspace(1)* %a 26 %b.val = load half, half addrspace(1)* %b 27 %c.val = load half, half addrspace(1)* %c 28 %r.val = call half @llvm.fmuladd.f16(half %a.val, half %b.val, half %c.val) 29 store half %r.val, half addrspace(1)* %r 30 ret void 31} 32 33; GCN-LABEL: {{^}}fmuladd_f16_imm_a 34; GCN: buffer_load_ushort v[[B_F16:[0-9]+]] 35; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 36; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], 0x4200{{$}} 37; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], v[[B_F16]] 38; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 39; SI: v_mac_f32_e32 v[[C_F32]], v[[A_F32]], v[[B_F32]] 40; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[C_F32]] 41; SI: buffer_store_short v[[R_F16]] 42; VI: v_mac_f16_e32 v[[C_F16]], 0x4200, v[[B_F16]] 43; VI: buffer_store_short v[[C_F16]] 44; GCN: s_endpgm 45define void @fmuladd_f16_imm_a( 46 half addrspace(1)* %r, 47 half addrspace(1)* %b, 48 half addrspace(1)* %c) { 49 %b.val = load half, half addrspace(1)* %b 50 %c.val = load half, half addrspace(1)* %c 51 %r.val = call half @llvm.fmuladd.f16(half 3.0, half %b.val, half %c.val) 52 store half %r.val, half addrspace(1)* %r 53 ret void 54} 55 56; GCN-LABEL: {{^}}fmuladd_f16_imm_b 57; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] 58; GCN: buffer_load_ushort v[[C_F16:[0-9]+]] 59; SI: v_cvt_f32_f16_e32 v[[B_F32:[0-9]+]], 0x4200{{$}} 60; SI: v_cvt_f32_f16_e32 v[[A_F32:[0-9]+]], v[[A_F16]] 61; SI: v_cvt_f32_f16_e32 v[[C_F32:[0-9]+]], v[[C_F16]] 62; SI: v_mac_f32_e32 v[[C_F32]], v[[B_F32]], v[[A_F32]] 63; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[C_F32]] 64; SI: buffer_store_short v[[R_F16]] 65; VI: v_mac_f16_e32 v[[C_F16]], 0x4200, v[[A_F16]] 66; VI: buffer_store_short v[[C_F16]] 67; GCN: s_endpgm 68define void @fmuladd_f16_imm_b( 69 half addrspace(1)* %r, 70 half addrspace(1)* %a, 71 half addrspace(1)* %c) { 72 %a.val = load half, half addrspace(1)* %a 73 %c.val = load half, half addrspace(1)* %c 74 %r.val = call half @llvm.fmuladd.f16(half %a.val, half 3.0, half %c.val) 75 store half %r.val, half addrspace(1)* %r 76 ret void 77} 78 79; GCN-LABEL: {{^}}fmuladd_v2f16 80; GCN: buffer_load_dword v[[A_V2_F16:[0-9]+]] 81; GCN: buffer_load_dword v[[B_V2_F16:[0-9]+]] 82; GCN: buffer_load_dword v[[C_V2_F16:[0-9]+]] 83; GCN: v_lshrrev_b32_e32 v[[A_F16_1:[0-9]+]], 16, v[[A_V2_F16]] 84; GCN: v_lshrrev_b32_e32 v[[B_F16_1:[0-9]+]], 16, v[[B_V2_F16]] 85; GCN: v_lshrrev_b32_e32 v[[C_F16_1:[0-9]+]], 16, v[[C_V2_F16]] 86; SI: v_cvt_f32_f16_e32 v[[A_F32_0:[0-9]+]], v[[A_V2_F16]] 87; SI: v_cvt_f32_f16_e32 v[[B_F32_0:[0-9]+]], v[[B_V2_F16]] 88; SI: v_cvt_f32_f16_e32 v[[C_F32_0:[0-9]+]], v[[C_V2_F16]] 89; SI: v_cvt_f32_f16_e32 v[[A_F32_1:[0-9]+]], v[[A_F16_1]] 90; SI: v_cvt_f32_f16_e32 v[[B_F32_1:[0-9]+]], v[[B_F16_1]] 91; SI: v_cvt_f32_f16_e32 v[[C_F32_1:[0-9]+]], v[[C_F16_1]] 92; SI: v_mac_f32_e32 v[[C_F32_0]], v[[B_F32_0]], v[[A_F32_0]] 93; SI: v_cvt_f16_f32_e32 v[[R_F16_0:[0-9]+]], v[[C_F32_0]] 94; SI: v_mac_f32_e32 v[[C_F32_1]], v[[B_F32_1]], v[[A_F32_1]] 95; SI: v_cvt_f16_f32_e32 v[[R_F16_1:[0-9]+]], v[[C_F32_1]] 96; SI: v_and_b32_e32 v[[R_F16_LO:[0-9]+]], 0xffff, v[[R_F16_0]] 97; SI: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[R_F16_1]] 98; VI: v_mac_f16_e32 v[[C_V2_F16]], v[[B_V2_F16]], v[[A_V2_F16]] 99; VI: v_mac_f16_e32 v[[C_F16_1]], v[[B_F16_1]], v[[A_F16_1]] 100; VI: v_and_b32_e32 v[[R_F16_LO:[0-9]+]], 0xffff, v[[C_V2_F16]] 101; VI: v_lshlrev_b32_e32 v[[R_F16_HI:[0-9]+]], 16, v[[C_F16_1]] 102; GCN: v_or_b32_e32 v[[R_V2_F16:[0-9]+]], v[[R_F16_HI]], v[[R_F16_LO]] 103; GCN: buffer_store_dword v[[R_V2_F16]] 104; GCN: s_endpgm 105define void @fmuladd_v2f16( 106 <2 x half> addrspace(1)* %r, 107 <2 x half> addrspace(1)* %a, 108 <2 x half> addrspace(1)* %b, 109 <2 x half> addrspace(1)* %c) { 110 %a.val = load <2 x half>, <2 x half> addrspace(1)* %a 111 %b.val = load <2 x half>, <2 x half> addrspace(1)* %b 112 %c.val = load <2 x half>, <2 x half> addrspace(1)* %c 113 %r.val = call <2 x half> @llvm.fmuladd.v2f16(<2 x half> %a.val, <2 x half> %b.val, <2 x half> %c.val) 114 store <2 x half> %r.val, <2 x half> addrspace(1)* %r 115 ret void 116} 117