872 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -denormal-fp-math-f32=preserve-sign < %s | FileCheck -enable-var-scope -check-prefixes=GFX11,GFX11-TRUE16,GFX11-F32FLUSH,GFX11-F32FLUSH-TRUE16 %s3; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-real-true16 -denormal-fp-math-f32=preserve-sign < %s | FileCheck -enable-var-scope -check-prefixes=GFX11,GFX11-FAKE16,GFX11-F32FLUSH,GFX11-F32FLUSH-FAKE16 %s4; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -denormal-fp-math-f32=ieee < %s | FileCheck -enable-var-scope -check-prefixes=GFX11,GFX11-TRUE16,GFX11-F32DENORM,GFX11-F32DENORM-TRUE16 %s5; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-real-true16 -denormal-fp-math-f32=ieee < %s | FileCheck -enable-var-scope -check-prefixes=GFX11,GFX11-FAKE16,GFX11-F32DENORM,GFX11-F32DENORM-FAKE16 %s6; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -denormal-fp-math-f32=preserve-sign < %s | FileCheck -enable-var-scope -check-prefixes=GFX89,GFX9-F32FLUSH %s7; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -denormal-fp-math-f32=ieee < %s | FileCheck -enable-var-scope -check-prefixes=GFX89,GFX9-F32DENORM %s8; RUN: llc -mtriple=amdgcn -mcpu=gfx803 -denormal-fp-math-f32=preserve-sign < %s | FileCheck -enable-var-scope -check-prefixes=GFX89 %s9; RUN: llc -mtriple=amdgcn -mcpu=gfx803 -denormal-fp-math-f32=ieee < %s | FileCheck -enable-var-scope -check-prefixes=GFX89 %s10 11; fold (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)12define float @fadd_fpext_fmul_f16_to_f32(half %x, half %y, float %z) #0 {13; GFX11-TRUE16-LABEL: fadd_fpext_fmul_f16_to_f32:14; GFX11-TRUE16: ; %bb.0: ; %entry15; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)16; GFX11-TRUE16-NEXT: v_mul_f16_e32 v0.l, v0.l, v1.l17; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)18; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l19; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v220; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]21;22; GFX11-FAKE16-LABEL: fadd_fpext_fmul_f16_to_f32:23; GFX11-FAKE16: ; %bb.0: ; %entry24; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)25; GFX11-FAKE16-NEXT: v_mul_f16_e32 v0, v0, v126; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)27; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v028; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v229; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]30;31; GFX9-F32FLUSH-LABEL: fadd_fpext_fmul_f16_to_f32:32; GFX9-F32FLUSH: ; %bb.0: ; %entry33; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)34; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,0]35; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]36;37; GFX9-F32DENORM-LABEL: fadd_fpext_fmul_f16_to_f32:38; GFX9-F32DENORM: ; %bb.0: ; %entry39; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)40; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v0, v0, v141; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v0, v042; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v243; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]44entry:45 %mul = fmul half %x, %y46 %mul.ext = fpext half %mul to float47 %add = fadd float %mul.ext, %z48 ret float %add49}50 51; f16->f64 is not free.52define double @fadd_fpext_fmul_f16_to_f64(half %x, half %y, double %z) #0 {53; GFX11-TRUE16-LABEL: fadd_fpext_fmul_f16_to_f64:54; GFX11-TRUE16: ; %bb.0: ; %entry55; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)56; GFX11-TRUE16-NEXT: v_mul_f16_e32 v0.l, v0.l, v1.l57; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)58; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l59; GFX11-TRUE16-NEXT: v_cvt_f64_f32_e32 v[0:1], v060; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)61; GFX11-TRUE16-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3]62; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]63;64; GFX11-FAKE16-LABEL: fadd_fpext_fmul_f16_to_f64:65; GFX11-FAKE16: ; %bb.0: ; %entry66; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)67; GFX11-FAKE16-NEXT: v_mul_f16_e32 v0, v0, v168; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)69; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v070; GFX11-FAKE16-NEXT: v_cvt_f64_f32_e32 v[0:1], v071; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)72; GFX11-FAKE16-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3]73; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]74;75; GFX89-LABEL: fadd_fpext_fmul_f16_to_f64:76; GFX89: ; %bb.0: ; %entry77; GFX89-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)78; GFX89-NEXT: v_mul_f16_e32 v0, v0, v179; GFX89-NEXT: v_cvt_f32_f16_e32 v0, v080; GFX89-NEXT: v_cvt_f64_f32_e32 v[0:1], v081; GFX89-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3]82; GFX89-NEXT: s_setpc_b64 s[30:31]83entry:84 %mul = fmul half %x, %y85 %mul.ext = fpext half %mul to double86 %add = fadd double %mul.ext, %z87 ret double %add88}89 90; f32->f64 is not free.91define double @fadd_fpext_fmul_f32_to_f64(float %x, float %y, double %z) #0 {92; GFX11-LABEL: fadd_fpext_fmul_f32_to_f64:93; GFX11: ; %bb.0: ; %entry94; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)95; GFX11-NEXT: v_mul_f32_e32 v0, v0, v196; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)97; GFX11-NEXT: v_cvt_f64_f32_e32 v[0:1], v098; GFX11-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3]99; GFX11-NEXT: s_setpc_b64 s[30:31]100;101; GFX89-LABEL: fadd_fpext_fmul_f32_to_f64:102; GFX89: ; %bb.0: ; %entry103; GFX89-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)104; GFX89-NEXT: v_mul_f32_e32 v0, v0, v1105; GFX89-NEXT: v_cvt_f64_f32_e32 v[0:1], v0106; GFX89-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3]107; GFX89-NEXT: s_setpc_b64 s[30:31]108entry:109 %mul = fmul float %x, %y110 %mul.ext = fpext float %mul to double111 %add = fadd double %mul.ext, %z112 ret double %add113}114 115; fold (fadd x, (fpext (fmul y, z))) -> (fma (fpext y), (fpext z), x)116define float @fadd_fpext_fmul_f16_to_f32_commute(half %x, half %y, float %z) #0 {117; GFX11-TRUE16-LABEL: fadd_fpext_fmul_f16_to_f32_commute:118; GFX11-TRUE16: ; %bb.0: ; %entry119; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)120; GFX11-TRUE16-NEXT: v_mul_f16_e32 v0.l, v0.l, v1.l121; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)122; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l123; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v2, v0124; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]125;126; GFX11-FAKE16-LABEL: fadd_fpext_fmul_f16_to_f32_commute:127; GFX11-FAKE16: ; %bb.0: ; %entry128; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)129; GFX11-FAKE16-NEXT: v_mul_f16_e32 v0, v0, v1130; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)131; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0132; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v2, v0133; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]134;135; GFX9-F32FLUSH-LABEL: fadd_fpext_fmul_f16_to_f32_commute:136; GFX9-F32FLUSH: ; %bb.0: ; %entry137; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)138; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,0]139; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]140;141; GFX9-F32DENORM-LABEL: fadd_fpext_fmul_f16_to_f32_commute:142; GFX9-F32DENORM: ; %bb.0: ; %entry143; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)144; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v0, v0, v1145; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v0, v0146; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v2, v0147; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]148entry:149 %mul = fmul half %x, %y150 %mul.ext = fpext half %mul to float151 %add = fadd float %z, %mul.ext152 ret float %add153}154 155; fold (fadd (fma x, y, (fpext (fmul u, v))), z)156; -> (fma x, y, (fma (fpext u), (fpext v), z))157define float @fadd_muladd_fpext_fmul_f16_to_f32(float %x, float %y, half %u, half %v, float %z) #0 {158; GFX11-TRUE16-LABEL: fadd_muladd_fpext_fmul_f16_to_f32:159; GFX11-TRUE16: ; %bb.0: ; %entry160; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)161; GFX11-TRUE16-NEXT: v_mul_f16_e32 v2.l, v2.l, v3.l162; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)163; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]164; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v4165; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]166;167; GFX11-FAKE16-LABEL: fadd_muladd_fpext_fmul_f16_to_f32:168; GFX11-FAKE16: ; %bb.0: ; %entry169; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)170; GFX11-FAKE16-NEXT: v_mul_f16_e32 v2, v2, v3171; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)172; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]173; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v4174; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]175;176; GFX9-F32FLUSH-LABEL: fadd_muladd_fpext_fmul_f16_to_f32:177; GFX9-F32FLUSH: ; %bb.0: ; %entry178; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)179; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v2, v3, v4 op_sel_hi:[1,1,0]180; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1181; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2182; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]183;184; GFX9-F32DENORM-LABEL: fadd_muladd_fpext_fmul_f16_to_f32:185; GFX9-F32DENORM: ; %bb.0: ; %entry186; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)187; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v2, v2, v3188; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v2, v2189; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v2190; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v4191; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]192entry:193 %mul = fmul half %u, %v194 %mul.ext = fpext half %mul to float195 %fma = call float @llvm.fmuladd.f32(float %x, float %y, float %mul.ext)196 %add = fadd float %fma, %z197 ret float %add198}199 200; fold (fadd x, (fma y, z, (fpext (fmul u, v)))201; -> (fma y, z, (fma (fpext u), (fpext v), x))202define float @fadd_muladd_fpext_fmul_f16_to_f32_commute(float %x, float %y, half %u, half %v, float %z) #0 {203; GFX11-TRUE16-LABEL: fadd_muladd_fpext_fmul_f16_to_f32_commute:204; GFX11-TRUE16: ; %bb.0: ; %entry205; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)206; GFX11-TRUE16-NEXT: v_mul_f16_e32 v2.l, v2.l, v3.l207; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)208; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]209; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v4, v0210; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]211;212; GFX11-FAKE16-LABEL: fadd_muladd_fpext_fmul_f16_to_f32_commute:213; GFX11-FAKE16: ; %bb.0: ; %entry214; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)215; GFX11-FAKE16-NEXT: v_mul_f16_e32 v2, v2, v3216; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)217; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]218; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v4, v0219; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]220;221; GFX9-F32FLUSH-LABEL: fadd_muladd_fpext_fmul_f16_to_f32_commute:222; GFX9-F32FLUSH: ; %bb.0: ; %entry223; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)224; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v2, v3, v4 op_sel_hi:[1,1,0]225; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1226; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2227; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]228;229; GFX9-F32DENORM-LABEL: fadd_muladd_fpext_fmul_f16_to_f32_commute:230; GFX9-F32DENORM: ; %bb.0: ; %entry231; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)232; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v2, v2, v3233; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v2, v2234; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v2235; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v4, v0236; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]237entry:238 %mul = fmul half %u, %v239 %mul.ext = fpext half %mul to float240 %fma = call float @llvm.fmuladd.f32(float %x, float %y, float %mul.ext)241 %add = fadd float %z, %fma242 ret float %add243}244 245define float @fadd_fmad_fpext_fmul_f16_to_f32(float %x, float %y, half %u, half %v, float %z) #0 {246; GFX11-TRUE16-LABEL: fadd_fmad_fpext_fmul_f16_to_f32:247; GFX11-TRUE16: ; %bb.0: ; %entry248; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)249; GFX11-TRUE16-NEXT: v_mul_f16_e32 v2.l, v2.l, v3.l250; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)251; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]252; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v4253; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]254;255; GFX11-FAKE16-LABEL: fadd_fmad_fpext_fmul_f16_to_f32:256; GFX11-FAKE16: ; %bb.0: ; %entry257; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)258; GFX11-FAKE16-NEXT: v_mul_f16_e32 v2, v2, v3259; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)260; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]261; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v4262; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]263;264; GFX9-F32FLUSH-LABEL: fadd_fmad_fpext_fmul_f16_to_f32:265; GFX9-F32FLUSH: ; %bb.0: ; %entry266; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)267; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v2, v3, v4 op_sel_hi:[1,1,0]268; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1269; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2270; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]271;272; GFX9-F32DENORM-LABEL: fadd_fmad_fpext_fmul_f16_to_f32:273; GFX9-F32DENORM: ; %bb.0: ; %entry274; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)275; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v2, v2, v3276; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v2, v2277; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v2278; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v4279; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]280entry:281 %mul = fmul half %u, %v282 %mul.ext = fpext half %mul to float283 %mul1 = fmul contract float %x, %y284 %fmad = fadd contract float %mul1, %mul.ext285 %add = fadd float %fmad, %z286 ret float %add287}288 289; fold (fadd (fma x, y, (fpext (fmul u, v))), z)290; -> (fma x, y, (fma (fpext u), (fpext v), z))291define float @fadd_fma_fpext_fmul_f16_to_f32(float %x, float %y, half %u, half %v, float %z) #0 {292; GFX11-TRUE16-LABEL: fadd_fma_fpext_fmul_f16_to_f32:293; GFX11-TRUE16: ; %bb.0: ; %entry294; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)295; GFX11-TRUE16-NEXT: v_mul_f16_e32 v2.l, v2.l, v3.l296; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)297; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]298; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v4299; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]300;301; GFX11-FAKE16-LABEL: fadd_fma_fpext_fmul_f16_to_f32:302; GFX11-FAKE16: ; %bb.0: ; %entry303; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)304; GFX11-FAKE16-NEXT: v_mul_f16_e32 v2, v2, v3305; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)306; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]307; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v4308; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]309;310; GFX9-F32FLUSH-LABEL: fadd_fma_fpext_fmul_f16_to_f32:311; GFX9-F32FLUSH: ; %bb.0: ; %entry312; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)313; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v2, v3, v4 op_sel_hi:[1,1,0]314; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1315; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2316; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]317;318; GFX9-F32DENORM-LABEL: fadd_fma_fpext_fmul_f16_to_f32:319; GFX9-F32DENORM: ; %bb.0: ; %entry320; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)321; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v2, v2, v3322; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v2, v2323; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v2324; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v4325; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]326entry:327 %mul = fmul contract half %u, %v328 %mul.ext = fpext half %mul to float329 %fma = call float @llvm.fma.f32(float %x, float %y, float %mul.ext)330 %add = fadd float %fma, %z331 ret float %add332}333 334define float @fadd_fma_fpext_fmul_f16_to_f32_commute(float %x, float %y, half %u, half %v, float %z) #0 {335; GFX11-TRUE16-LABEL: fadd_fma_fpext_fmul_f16_to_f32_commute:336; GFX11-TRUE16: ; %bb.0: ; %entry337; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)338; GFX11-TRUE16-NEXT: v_mul_f16_e32 v2.l, v2.l, v3.l339; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)340; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]341; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v4, v0342; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]343;344; GFX11-FAKE16-LABEL: fadd_fma_fpext_fmul_f16_to_f32_commute:345; GFX11-FAKE16: ; %bb.0: ; %entry346; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)347; GFX11-FAKE16-NEXT: v_mul_f16_e32 v2, v2, v3348; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)349; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[0,0,1]350; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v4, v0351; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]352;353; GFX9-F32FLUSH-LABEL: fadd_fma_fpext_fmul_f16_to_f32_commute:354; GFX9-F32FLUSH: ; %bb.0: ; %entry355; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)356; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v2, v3, v4 op_sel_hi:[1,1,0]357; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1358; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2359; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]360;361; GFX9-F32DENORM-LABEL: fadd_fma_fpext_fmul_f16_to_f32_commute:362; GFX9-F32DENORM: ; %bb.0: ; %entry363; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)364; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v2, v2, v3365; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v2, v2366; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v2367; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v4, v0368; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]369entry:370 %mul = fmul contract half %u, %v371 %mul.ext = fpext half %mul to float372 %fma = call float @llvm.fma.f32(float %x, float %y, float %mul.ext)373 %add = fadd float %z, %fma374 ret float %add375}376 377; fold (fadd x, (fpext (fma y, z, (fmul u, v)))378; -> (fma (fpext y), (fpext z), (fma (fpext u), (fpext v), x))379define float @fadd_fpext_fmuladd_f16_to_f32(float %x, half %y, half %z, half %u, half %v) #0 {380; GFX11-TRUE16-LABEL: fadd_fpext_fmuladd_f16_to_f32:381; GFX11-TRUE16: ; %bb.0: ; %entry382; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)383; GFX11-TRUE16-NEXT: v_mul_f16_e32 v1.h, v3.l, v4.l384; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)385; GFX11-TRUE16-NEXT: v_fmac_f16_e32 v1.h, v1.l, v2.l386; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h387; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)388; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1389; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]390;391; GFX11-FAKE16-LABEL: fadd_fpext_fmuladd_f16_to_f32:392; GFX11-FAKE16: ; %bb.0: ; %entry393; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)394; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4395; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)396; GFX11-FAKE16-NEXT: v_fmac_f16_e32 v3, v1, v2397; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v3398; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)399; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v1400; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]401;402; GFX9-F32FLUSH-LABEL: fadd_fpext_fmuladd_f16_to_f32:403; GFX9-F32FLUSH: ; %bb.0: ; %entry404; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)405; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v3, v4, v0 op_sel_hi:[1,1,0]406; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v1, v2, v0 op_sel_hi:[1,1,0]407; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]408;409; GFX9-F32DENORM-LABEL: fadd_fpext_fmuladd_f16_to_f32:410; GFX9-F32DENORM: ; %bb.0: ; %entry411; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)412; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v3, v3, v4413; GFX9-F32DENORM-NEXT: v_fma_f16 v1, v1, v2, v3414; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v1, v1415; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v1416; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]417entry:418 %mul = fmul contract half %u, %v419 %fma = call half @llvm.fmuladd.f16(half %y, half %z, half %mul)420 %ext.fma = fpext half %fma to float421 %add = fadd float %x, %ext.fma422 ret float %add423}424 425define float @fadd_fpext_fma_f16_to_f32(float %x, half %y, half %z, half %u, half %v) #0 {426; GFX11-TRUE16-LABEL: fadd_fpext_fma_f16_to_f32:427; GFX11-TRUE16: ; %bb.0: ; %entry428; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)429; GFX11-TRUE16-NEXT: v_mul_f16_e32 v1.h, v3.l, v4.l430; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)431; GFX11-TRUE16-NEXT: v_fmac_f16_e32 v1.h, v1.l, v2.l432; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h433; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)434; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v0, v1435; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]436;437; GFX11-FAKE16-LABEL: fadd_fpext_fma_f16_to_f32:438; GFX11-FAKE16: ; %bb.0: ; %entry439; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)440; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4441; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)442; GFX11-FAKE16-NEXT: v_fmac_f16_e32 v3, v1, v2443; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v3444; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)445; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v0, v1446; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]447;448; GFX9-F32FLUSH-LABEL: fadd_fpext_fma_f16_to_f32:449; GFX9-F32FLUSH: ; %bb.0: ; %entry450; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)451; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v3, v4, v0 op_sel_hi:[1,1,0]452; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v1, v2, v0 op_sel_hi:[1,1,0]453; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]454;455; GFX9-F32DENORM-LABEL: fadd_fpext_fma_f16_to_f32:456; GFX9-F32DENORM: ; %bb.0: ; %entry457; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)458; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v3, v3, v4459; GFX9-F32DENORM-NEXT: v_fma_f16 v1, v1, v2, v3460; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v1, v1461; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v0, v1462; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]463entry:464 %mul = fmul contract half %u, %v465 %fma = call half @llvm.fma.f16(half %y, half %z, half %mul)466 %ext.fma = fpext half %fma to float467 %add = fadd float %x, %ext.fma468 ret float %add469}470 471define float @fadd_fpext_fma_f16_to_f32_commute(float %x, half %y, half %z, half %u, half %v) #0 {472; GFX11-TRUE16-LABEL: fadd_fpext_fma_f16_to_f32_commute:473; GFX11-TRUE16: ; %bb.0: ; %entry474; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)475; GFX11-TRUE16-NEXT: v_mul_f16_e32 v1.h, v3.l, v4.l476; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)477; GFX11-TRUE16-NEXT: v_fmac_f16_e32 v1.h, v1.l, v2.l478; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h479; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)480; GFX11-TRUE16-NEXT: v_add_f32_e32 v0, v1, v0481; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]482;483; GFX11-FAKE16-LABEL: fadd_fpext_fma_f16_to_f32_commute:484; GFX11-FAKE16: ; %bb.0: ; %entry485; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)486; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4487; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)488; GFX11-FAKE16-NEXT: v_fmac_f16_e32 v3, v1, v2489; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v3490; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)491; GFX11-FAKE16-NEXT: v_add_f32_e32 v0, v1, v0492; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]493;494; GFX9-F32FLUSH-LABEL: fadd_fpext_fma_f16_to_f32_commute:495; GFX9-F32FLUSH: ; %bb.0: ; %entry496; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)497; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v3, v4, v0 op_sel_hi:[1,1,0]498; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v1, v2, v0 op_sel_hi:[1,1,0]499; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]500;501; GFX9-F32DENORM-LABEL: fadd_fpext_fma_f16_to_f32_commute:502; GFX9-F32DENORM: ; %bb.0: ; %entry503; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)504; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v3, v3, v4505; GFX9-F32DENORM-NEXT: v_fma_f16 v1, v1, v2, v3506; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v1, v1507; GFX9-F32DENORM-NEXT: v_add_f32_e32 v0, v1, v0508; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]509entry:510 %mul = fmul contract half %u, %v511 %fma = call half @llvm.fma.f16(half %y, half %z, half %mul)512 %ext.fma = fpext half %fma to float513 %add = fadd float %ext.fma, %x514 ret float %add515}516 517; fold (fsub (fpext (fmul x, y)), z)518; -> (fma (fpext x), (fpext y), (fneg z))519define float @fsub_fpext_fmul_f16_to_f32(half %x, half %y, float %z) #0 {520; GFX11-TRUE16-LABEL: fsub_fpext_fmul_f16_to_f32:521; GFX11-TRUE16: ; %bb.0: ; %entry522; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)523; GFX11-TRUE16-NEXT: v_mul_f16_e32 v0.l, v0.l, v1.l524; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)525; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l526; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v2527; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]528;529; GFX11-FAKE16-LABEL: fsub_fpext_fmul_f16_to_f32:530; GFX11-FAKE16: ; %bb.0: ; %entry531; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)532; GFX11-FAKE16-NEXT: v_mul_f16_e32 v0, v0, v1533; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)534; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0535; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v2536; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]537;538; GFX9-F32FLUSH-LABEL: fsub_fpext_fmul_f16_to_f32:539; GFX9-F32FLUSH: ; %bb.0: ; %entry540; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)541; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v0, v1, -v2 op_sel_hi:[1,1,0]542; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]543;544; GFX9-F32DENORM-LABEL: fsub_fpext_fmul_f16_to_f32:545; GFX9-F32DENORM: ; %bb.0: ; %entry546; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)547; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v0, v0, v1548; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v0, v0549; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v2550; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]551entry:552 %mul = fmul half %x, %y553 %mul.ext = fpext half %mul to float554 %add = fsub float %mul.ext, %z555 ret float %add556}557 558; fold (fsub x, (fpext (fmul y, z)))559; -> (fma (fneg (fpext y)), (fpext z), x)560define float @fsub_fpext_fmul_f16_to_f32_commute(float %x, half %y, half %z) #0 {561; GFX11-F32FLUSH-LABEL: fsub_fpext_fmul_f16_to_f32_commute:562; GFX11-F32FLUSH: ; %bb.0: ; %entry563; GFX11-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)564; GFX11-F32FLUSH-NEXT: v_fma_mix_f32 v0, -v1, v2, v0 op_sel_hi:[1,1,0]565; GFX11-F32FLUSH-NEXT: s_setpc_b64 s[30:31]566;567; GFX11-F32DENORM-TRUE16-LABEL: fsub_fpext_fmul_f16_to_f32_commute:568; GFX11-F32DENORM-TRUE16: ; %bb.0: ; %entry569; GFX11-F32DENORM-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)570; GFX11-F32DENORM-TRUE16-NEXT: v_mul_f16_e32 v1.l, v1.l, v2.l571; GFX11-F32DENORM-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)572; GFX11-F32DENORM-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l573; GFX11-F32DENORM-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v1574; GFX11-F32DENORM-TRUE16-NEXT: s_setpc_b64 s[30:31]575;576; GFX11-F32DENORM-FAKE16-LABEL: fsub_fpext_fmul_f16_to_f32_commute:577; GFX11-F32DENORM-FAKE16: ; %bb.0: ; %entry578; GFX11-F32DENORM-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)579; GFX11-F32DENORM-FAKE16-NEXT: v_mul_f16_e32 v1, v1, v2580; GFX11-F32DENORM-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)581; GFX11-F32DENORM-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1582; GFX11-F32DENORM-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v1583; GFX11-F32DENORM-FAKE16-NEXT: s_setpc_b64 s[30:31]584;585; GFX9-F32FLUSH-LABEL: fsub_fpext_fmul_f16_to_f32_commute:586; GFX9-F32FLUSH: ; %bb.0: ; %entry587; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)588; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, -v1, v2, v0 op_sel_hi:[1,1,0]589; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]590;591; GFX9-F32DENORM-LABEL: fsub_fpext_fmul_f16_to_f32_commute:592; GFX9-F32DENORM: ; %bb.0: ; %entry593; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)594; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v1, v1, v2595; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v1, v1596; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v1597; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]598entry:599 %mul = fmul contract half %y, %z600 %mul.ext = fpext half %mul to float601 %add = fsub contract float %x, %mul.ext602 ret float %add603}604 605; fold (fsub (fpext (fneg (fmul, x, y))), z)606; -> (fneg (fma (fpext x), (fpext y), z))607define float @fsub_fpext_fneg_fmul_f16_to_f32(half %x, half %y, float %z) #0 {608; GFX11-TRUE16-LABEL: fsub_fpext_fneg_fmul_f16_to_f32:609; GFX11-TRUE16: ; %bb.0: ; %entry610; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)611; GFX11-TRUE16-NEXT: v_mul_f16_e64 v0.l, v0.l, -v1.l612; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)613; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l614; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v2615; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]616;617; GFX11-FAKE16-LABEL: fsub_fpext_fneg_fmul_f16_to_f32:618; GFX11-FAKE16: ; %bb.0: ; %entry619; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)620; GFX11-FAKE16-NEXT: v_mul_f16_e64 v0, v0, -v1621; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)622; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0623; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v2624; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]625;626; GFX9-F32FLUSH-LABEL: fsub_fpext_fneg_fmul_f16_to_f32:627; GFX9-F32FLUSH: ; %bb.0: ; %entry628; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)629; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v0, -v1, -v2 op_sel_hi:[1,1,0]630; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]631;632; GFX9-F32DENORM-LABEL: fsub_fpext_fneg_fmul_f16_to_f32:633; GFX9-F32DENORM: ; %bb.0: ; %entry634; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)635; GFX9-F32DENORM-NEXT: v_mul_f16_e64 v0, v0, -v1636; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v0, v0637; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v2638; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]639entry:640 %mul = fmul half %x, %y641 %neg.mul = fsub half -0.0, %mul642 %neg.mul.ext = fpext half %neg.mul to float643 %add = fsub float %neg.mul.ext, %z644 ret float %add645}646 647; fold (fsub (fneg (fpext (fmul, x, y))), z)648; -> (fneg (fma (fpext x)), (fpext y), z)649define float @fsub_fneg_fpext_fmul_f16_to_f32(half %x, half %y, float %z) #0 {650; GFX11-TRUE16-LABEL: fsub_fneg_fpext_fmul_f16_to_f32:651; GFX11-TRUE16: ; %bb.0: ; %entry652; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)653; GFX11-TRUE16-NEXT: v_mul_f16_e64 v0.l, v0.l, -v1.l654; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)655; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l656; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v2657; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]658;659; GFX11-FAKE16-LABEL: fsub_fneg_fpext_fmul_f16_to_f32:660; GFX11-FAKE16: ; %bb.0: ; %entry661; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)662; GFX11-FAKE16-NEXT: v_mul_f16_e64 v0, v0, -v1663; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)664; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0665; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v2666; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]667;668; GFX9-F32FLUSH-LABEL: fsub_fneg_fpext_fmul_f16_to_f32:669; GFX9-F32FLUSH: ; %bb.0: ; %entry670; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)671; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, v0, -v1, -v2 op_sel_hi:[1,1,0]672; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]673;674; GFX9-F32DENORM-LABEL: fsub_fneg_fpext_fmul_f16_to_f32:675; GFX9-F32DENORM: ; %bb.0: ; %entry676; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)677; GFX9-F32DENORM-NEXT: v_mul_f16_e64 v0, v0, -v1678; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v0, v0679; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v2680; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]681entry:682 %mul = fmul half %x, %y683 %mul.ext = fpext half %mul to float684 %neg.mul.ext = fneg float %mul.ext685 %add = fsub float %neg.mul.ext, %z686 ret float %add687}688 689; fold (fsub (fmad x, y, (fpext (fmul u, v))), z)690; -> (fmad x, y (fmad (fpext u), (fpext v), (fneg z)))691define float @fsub_muladd_fpext_mul_f16_to_f32(float %x, float %y, float %z, half %u, half %v) #0 {692; GFX11-TRUE16-LABEL: fsub_muladd_fpext_mul_f16_to_f32:693; GFX11-TRUE16: ; %bb.0: ; %entry694; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)695; GFX11-TRUE16-NEXT: v_mul_f16_e32 v3.l, v3.l, v4.l696; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)697; GFX11-TRUE16-NEXT: v_fma_mix_f32 v0, v0, v1, v3 op_sel_hi:[0,0,1]698; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v2699; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]700;701; GFX11-FAKE16-LABEL: fsub_muladd_fpext_mul_f16_to_f32:702; GFX11-FAKE16: ; %bb.0: ; %entry703; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)704; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4705; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)706; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v3 op_sel_hi:[0,0,1]707; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v2708; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]709;710; GFX9-F32FLUSH-LABEL: fsub_muladd_fpext_mul_f16_to_f32:711; GFX9-F32FLUSH: ; %bb.0: ; %entry712; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)713; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v2, v3, v4, -v2 op_sel_hi:[1,1,0]714; GFX9-F32FLUSH-NEXT: v_mac_f32_e32 v2, v0, v1715; GFX9-F32FLUSH-NEXT: v_mov_b32_e32 v0, v2716; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]717;718; GFX9-F32DENORM-LABEL: fsub_muladd_fpext_mul_f16_to_f32:719; GFX9-F32DENORM: ; %bb.0: ; %entry720; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)721; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v3, v3, v4722; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v3, v3723; GFX9-F32DENORM-NEXT: v_fma_f32 v0, v0, v1, v3724; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v2725; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]726entry:727 %mul = fmul reassoc half %u, %v728 %mul.ext = fpext half %mul to float729 %fma = call float @llvm.fmuladd.f32(float %x, float %y, float %mul.ext)730 %add = fsub reassoc float %fma, %z731 ret float %add732}733 734; fold (fsub (fpext (fmad x, y, (fmul u, v))), z)735; -> (fmad (fpext x), (fpext y),736; (fmad (fpext u), (fpext v), (fneg z)))737define float @fsub_fpext_muladd_mul_f16_to_f32(half %x, half %y, float %z, half %u, half %v) #0 {738; GFX11-TRUE16-LABEL: fsub_fpext_muladd_mul_f16_to_f32:739; GFX11-TRUE16: ; %bb.0: ; %entry740; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)741; GFX11-TRUE16-NEXT: v_mul_f16_e32 v0.h, v3.l, v4.l742; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)743; GFX11-TRUE16-NEXT: v_fmac_f16_e32 v0.h, v0.l, v1.l744; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h745; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)746; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v2747; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]748;749; GFX11-FAKE16-LABEL: fsub_fpext_muladd_mul_f16_to_f32:750; GFX11-FAKE16: ; %bb.0: ; %entry751; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)752; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4753; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)754; GFX11-FAKE16-NEXT: v_fmac_f16_e32 v3, v0, v1755; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v3756; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)757; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v2758; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]759;760; GFX89-LABEL: fsub_fpext_muladd_mul_f16_to_f32:761; GFX89: ; %bb.0: ; %entry762; GFX89-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)763; GFX89-NEXT: v_mul_f16_e32 v3, v3, v4764; GFX89-NEXT: v_fma_f16 v0, v0, v1, v3765; GFX89-NEXT: v_cvt_f32_f16_e32 v0, v0766; GFX89-NEXT: v_sub_f32_e32 v0, v0, v2767; GFX89-NEXT: s_setpc_b64 s[30:31]768entry:769 %mul = fmul half %u, %v770 %fma = call half @llvm.fmuladd.f16(half %x, half %y, half %mul)771 %fma.ext = fpext half %fma to float772 %add = fsub float %fma.ext, %z773 ret float %add774}775 776; fold (fsub x, (fmad y, z, (fpext (fmul u, v))))777; -> (fmad (fneg y), z, (fmad (fneg (fpext u)), (fpext v), x))778define float @fsub_muladd_fpext_mul_f16_to_f32_commute(float %x, float %y, float %z, half %u, half %v) #0 {779; GFX11-TRUE16-LABEL: fsub_muladd_fpext_mul_f16_to_f32_commute:780; GFX11-TRUE16: ; %bb.0: ; %entry781; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)782; GFX11-TRUE16-NEXT: v_mul_f16_e32 v3.l, v3.l, v4.l783; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)784; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, v1, v2, v3 op_sel_hi:[0,0,1]785; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v1786; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]787;788; GFX11-FAKE16-LABEL: fsub_muladd_fpext_mul_f16_to_f32_commute:789; GFX11-FAKE16: ; %bb.0: ; %entry790; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)791; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4792; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)793; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, v2, v3 op_sel_hi:[0,0,1]794; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v1795; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]796;797; GFX9-F32FLUSH-LABEL: fsub_muladd_fpext_mul_f16_to_f32_commute:798; GFX9-F32FLUSH: ; %bb.0: ; %entry799; GFX9-F32FLUSH-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)800; GFX9-F32FLUSH-NEXT: v_mad_mix_f32 v0, -v3, v4, v0 op_sel_hi:[1,1,0]801; GFX9-F32FLUSH-NEXT: v_mad_f32 v0, -v1, v2, v0802; GFX9-F32FLUSH-NEXT: s_setpc_b64 s[30:31]803;804; GFX9-F32DENORM-LABEL: fsub_muladd_fpext_mul_f16_to_f32_commute:805; GFX9-F32DENORM: ; %bb.0: ; %entry806; GFX9-F32DENORM-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)807; GFX9-F32DENORM-NEXT: v_mul_f16_e32 v3, v3, v4808; GFX9-F32DENORM-NEXT: v_cvt_f32_f16_e32 v3, v3809; GFX9-F32DENORM-NEXT: v_fma_f32 v1, v1, v2, v3810; GFX9-F32DENORM-NEXT: v_sub_f32_e32 v0, v0, v1811; GFX9-F32DENORM-NEXT: s_setpc_b64 s[30:31]812entry:813 %mul = fmul reassoc half %u, %v814 %mul.ext = fpext half %mul to float815 %fma = call float @llvm.fmuladd.f32(float %y, float %z, float %mul.ext)816 %add = fsub reassoc float %x, %fma817 ret float %add818}819 820; fold (fsub x, (fpext (fma y, z, (fmul u, v))))821; -> (fma (fneg (fpext y)), (fpext z),822; (fma (fneg (fpext u)), (fpext v), x))823define float @fsub_fpext_muladd_mul_f16_to_f32_commute(float %x, half %y, half %z, half %u, half %v) #0 {824; GFX11-TRUE16-LABEL: fsub_fpext_muladd_mul_f16_to_f32_commute:825; GFX11-TRUE16: ; %bb.0: ; %entry826; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)827; GFX11-TRUE16-NEXT: v_mul_f16_e32 v1.h, v3.l, v4.l828; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)829; GFX11-TRUE16-NEXT: v_fmac_f16_e32 v1.h, v1.l, v2.l830; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h831; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)832; GFX11-TRUE16-NEXT: v_sub_f32_e32 v0, v0, v1833; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]834;835; GFX11-FAKE16-LABEL: fsub_fpext_muladd_mul_f16_to_f32_commute:836; GFX11-FAKE16: ; %bb.0: ; %entry837; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)838; GFX11-FAKE16-NEXT: v_mul_f16_e32 v3, v3, v4839; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)840; GFX11-FAKE16-NEXT: v_fmac_f16_e32 v3, v1, v2841; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v3842; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)843; GFX11-FAKE16-NEXT: v_sub_f32_e32 v0, v0, v1844; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]845;846; GFX89-LABEL: fsub_fpext_muladd_mul_f16_to_f32_commute:847; GFX89: ; %bb.0: ; %entry848; GFX89-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)849; GFX89-NEXT: v_mul_f16_e32 v3, v3, v4850; GFX89-NEXT: v_fma_f16 v1, v1, v2, v3851; GFX89-NEXT: v_cvt_f32_f16_e32 v1, v1852; GFX89-NEXT: v_sub_f32_e32 v0, v0, v1853; GFX89-NEXT: s_setpc_b64 s[30:31]854entry:855 %mul = fmul half %u, %v856 %fma = call half @llvm.fmuladd.f16(half %y, half %z, half %mul)857 %fma.ext = fpext half %fma to float858 %add = fsub float %x, %fma.ext859 ret float %add860}861 862declare float @llvm.fmuladd.f32(float, float, float) #0863declare float @llvm.fma.f32(float, float, float) #0864declare half @llvm.fmuladd.f16(half, half, half) #0865declare half @llvm.fma.f16(half, half, half) #0866 867attributes #0 = { nounwind readnone speculatable }868;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:869; GFX11-F32DENORM: {{.*}}870; GFX11-F32FLUSH-FAKE16: {{.*}}871; GFX11-F32FLUSH-TRUE16: {{.*}}872