3844 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52 3; Test with buggy fract, shouldn't match4; RUN: opt -S -mtriple=amdgcn-amd-amdpal -mcpu=tahiti -amdgpu-codegenprepare %s | FileCheck -check-prefixes=IR,GFX6-IR %s5 6; Working fract, but no f167; RUN: opt -S -mtriple=amdgcn-amd-amdpal -mcpu=kaveri -amdgpu-codegenprepare %s | FileCheck -check-prefixes=IR,IR-FRACT,GFX7-IR %s8 9; Working fract and f16 support10; RUN: opt -S -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 -amdgpu-codegenprepare %s | FileCheck -check-prefixes=IR,IR-FRACT,IR-LEGALF16 %s11; RUN: opt -S -mtriple=amdgcn-amd-amdpal -mcpu=gfx1100 -amdgpu-codegenprepare %s | FileCheck -check-prefixes=IR,IR-FRACT,IR-LEGALF16 %s12 13; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=tahiti < %s | FileCheck -check-prefixes=GCN,GFX6 %s14; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=kaveri < %s | FileCheck -check-prefixes=GCN,GFX7 %s15; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 < %s | FileCheck -check-prefixes=GCN,GFX8 %s16; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1100 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GCN,GFX11,GFX11-TRUE16 %s17; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GCN,GFX11,GFX11-FAKE16 %s18; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GFX12,GFX12-TRUE16 %s19; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX12,GFX12-FAKE16 %s20 21; Test patterns to match v_fract_* instructions.22 23; Expansion as it appears in the library with the extra output for24; floor. We can fold in the nan check into the instruction, but the25; inf check must remain.26define float @safe_math_fract_f32(float %x, ptr addrspace(1) writeonly captures(none) %ip) {27; GFX6-IR-LABEL: define float @safe_math_fract_f32(28; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0:[0-9]+]] {29; GFX6-IR-NEXT: [[ENTRY:.*:]]30; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])31; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]32; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)33; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+0034; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]35; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])36; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF000000000000037; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]38; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 439; GFX6-IR-NEXT: ret float [[COND6]]40;41; IR-FRACT-LABEL: define float @safe_math_fract_f32(42; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0:[0-9]+]] {43; IR-FRACT-NEXT: [[ENTRY:.*:]]44; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])45; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])46; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])47; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF000000000000048; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]49; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 450; IR-FRACT-NEXT: ret float [[COND6]]51;52; GFX6-LABEL: safe_math_fract_f32:53; GFX6: ; %bb.0: ; %entry54; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)55; GFX6-NEXT: v_floor_f32_e32 v3, v056; GFX6-NEXT: v_sub_f32_e32 v4, v0, v357; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v458; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v059; GFX6-NEXT: s_mov_b32 s8, 0x7f80000060; GFX6-NEXT: s_mov_b32 s6, 061; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v0, vcc62; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s863; GFX6-NEXT: s_mov_b32 s7, 0xf00064; GFX6-NEXT: s_mov_b32 s4, s665; GFX6-NEXT: s_mov_b32 s5, s666; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc67; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr6468; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)69; GFX6-NEXT: s_setpc_b64 s[30:31]70;71; GFX7-LABEL: safe_math_fract_f32:72; GFX7: ; %bb.0: ; %entry73; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)74; GFX7-NEXT: s_mov_b32 s8, 0x7f80000075; GFX7-NEXT: s_mov_b32 s6, 076; GFX7-NEXT: v_fract_f32_e32 v4, v077; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s878; GFX7-NEXT: s_mov_b32 s7, 0xf00079; GFX7-NEXT: s_mov_b32 s4, s680; GFX7-NEXT: s_mov_b32 s5, s681; GFX7-NEXT: v_floor_f32_e32 v3, v082; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc83; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr6484; GFX7-NEXT: s_waitcnt vmcnt(0)85; GFX7-NEXT: s_setpc_b64 s[30:31]86;87; GFX8-LABEL: safe_math_fract_f32:88; GFX8: ; %bb.0: ; %entry89; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)90; GFX8-NEXT: s_mov_b32 s4, 0x7f80000091; GFX8-NEXT: v_fract_f32_e32 v4, v092; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s493; GFX8-NEXT: v_floor_f32_e32 v3, v094; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc95; GFX8-NEXT: global_store_dword v[1:2], v3, off96; GFX8-NEXT: s_waitcnt vmcnt(0)97; GFX8-NEXT: s_setpc_b64 s[30:31]98;99; GFX11-LABEL: safe_math_fract_f32:100; GFX11: ; %bb.0: ; %entry101; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)102; GFX11-NEXT: v_fract_f32_e32 v3, v0103; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|104; GFX11-NEXT: v_floor_f32_e32 v4, v0105; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)106; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo107; GFX11-NEXT: global_store_b32 v[1:2], v4, off108; GFX11-NEXT: s_setpc_b64 s[30:31]109;110; GFX12-LABEL: safe_math_fract_f32:111; GFX12: ; %bb.0: ; %entry112; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0113; GFX12-NEXT: s_wait_expcnt 0x0114; GFX12-NEXT: s_wait_samplecnt 0x0115; GFX12-NEXT: s_wait_bvhcnt 0x0116; GFX12-NEXT: s_wait_kmcnt 0x0117; GFX12-NEXT: v_fract_f32_e32 v3, v0118; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|119; GFX12-NEXT: v_floor_f32_e32 v4, v0120; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)121; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)122; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo123; GFX12-NEXT: global_store_b32 v[1:2], v4, off124; GFX12-NEXT: s_setpc_b64 s[30:31]125entry:126 %floor = tail call float @llvm.floor.f32(float %x)127 %sub = fsub float %x, %floor128 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)129 %uno = fcmp uno float %x, 0.000000e+00130 %cond = select i1 %uno, float %x, float %min131 %fabs = tail call float @llvm.fabs.f32(float %x)132 %cmpinf = fcmp oeq float %fabs, 0x7FF0000000000000133 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond134 store float %floor, ptr addrspace(1) %ip, align 4135 ret float %cond6136}137 138define float @safe_math_fract_f32_swap(float %x, ptr addrspace(1) writeonly captures(none) %ip) {139; GFX6-IR-LABEL: define float @safe_math_fract_f32_swap(140; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {141; GFX6-IR-NEXT: [[ENTRY:.*:]]142; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])143; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]144; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)145; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp ord float [[X]], 0.000000e+00146; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[MIN]], float [[X]]147; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])148; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000149; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]150; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 4151; GFX6-IR-NEXT: ret float [[COND6]]152;153; IR-FRACT-LABEL: define float @safe_math_fract_f32_swap(154; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {155; IR-FRACT-NEXT: [[ENTRY:.*:]]156; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])157; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])158; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])159; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000160; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]161; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 4162; IR-FRACT-NEXT: ret float [[COND6]]163;164; GFX6-LABEL: safe_math_fract_f32_swap:165; GFX6: ; %bb.0: ; %entry166; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)167; GFX6-NEXT: v_floor_f32_e32 v3, v0168; GFX6-NEXT: v_sub_f32_e32 v4, v0, v3169; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4170; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v0171; GFX6-NEXT: s_mov_b32 s8, 0x7f800000172; GFX6-NEXT: s_mov_b32 s6, 0173; GFX6-NEXT: v_cndmask_b32_e32 v4, v0, v4, vcc174; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s8175; GFX6-NEXT: s_mov_b32 s7, 0xf000176; GFX6-NEXT: s_mov_b32 s4, s6177; GFX6-NEXT: s_mov_b32 s5, s6178; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc179; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64180; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)181; GFX6-NEXT: s_setpc_b64 s[30:31]182;183; GFX7-LABEL: safe_math_fract_f32_swap:184; GFX7: ; %bb.0: ; %entry185; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)186; GFX7-NEXT: s_mov_b32 s8, 0x7f800000187; GFX7-NEXT: s_mov_b32 s6, 0188; GFX7-NEXT: v_fract_f32_e32 v4, v0189; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s8190; GFX7-NEXT: s_mov_b32 s7, 0xf000191; GFX7-NEXT: s_mov_b32 s4, s6192; GFX7-NEXT: s_mov_b32 s5, s6193; GFX7-NEXT: v_floor_f32_e32 v3, v0194; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc195; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64196; GFX7-NEXT: s_waitcnt vmcnt(0)197; GFX7-NEXT: s_setpc_b64 s[30:31]198;199; GFX8-LABEL: safe_math_fract_f32_swap:200; GFX8: ; %bb.0: ; %entry201; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)202; GFX8-NEXT: s_mov_b32 s4, 0x7f800000203; GFX8-NEXT: v_fract_f32_e32 v4, v0204; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4205; GFX8-NEXT: v_floor_f32_e32 v3, v0206; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc207; GFX8-NEXT: global_store_dword v[1:2], v3, off208; GFX8-NEXT: s_waitcnt vmcnt(0)209; GFX8-NEXT: s_setpc_b64 s[30:31]210;211; GFX11-LABEL: safe_math_fract_f32_swap:212; GFX11: ; %bb.0: ; %entry213; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)214; GFX11-NEXT: v_fract_f32_e32 v3, v0215; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|216; GFX11-NEXT: v_floor_f32_e32 v4, v0217; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)218; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo219; GFX11-NEXT: global_store_b32 v[1:2], v4, off220; GFX11-NEXT: s_setpc_b64 s[30:31]221;222; GFX12-LABEL: safe_math_fract_f32_swap:223; GFX12: ; %bb.0: ; %entry224; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0225; GFX12-NEXT: s_wait_expcnt 0x0226; GFX12-NEXT: s_wait_samplecnt 0x0227; GFX12-NEXT: s_wait_bvhcnt 0x0228; GFX12-NEXT: s_wait_kmcnt 0x0229; GFX12-NEXT: v_fract_f32_e32 v3, v0230; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|231; GFX12-NEXT: v_floor_f32_e32 v4, v0232; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)233; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)234; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo235; GFX12-NEXT: global_store_b32 v[1:2], v4, off236; GFX12-NEXT: s_setpc_b64 s[30:31]237entry:238 %floor = tail call float @llvm.floor.f32(float %x)239 %sub = fsub float %x, %floor240 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)241 %uno = fcmp ord float %x, 0.000000e+00242 %cond = select i1 %uno, float %min, float %x243 %fabs = tail call float @llvm.fabs.f32(float %x)244 %cmpinf = fcmp oeq float %fabs, 0x7FF0000000000000245 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond246 store float %floor, ptr addrspace(1) %ip, align 4247 ret float %cond6248}249 250define float @safe_math_fract_f32_noinf_check(float %x, ptr addrspace(1) writeonly captures(none) %ip) {251; GFX6-IR-LABEL: define float @safe_math_fract_f32_noinf_check(252; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {253; GFX6-IR-NEXT: [[ENTRY:.*:]]254; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])255; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]256; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)257; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+00258; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]259; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 4260; GFX6-IR-NEXT: ret float [[COND]]261;262; IR-FRACT-LABEL: define float @safe_math_fract_f32_noinf_check(263; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {264; IR-FRACT-NEXT: [[ENTRY:.*:]]265; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])266; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])267; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 4268; IR-FRACT-NEXT: ret float [[COND]]269;270; GFX6-LABEL: safe_math_fract_f32_noinf_check:271; GFX6: ; %bb.0: ; %entry272; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)273; GFX6-NEXT: v_floor_f32_e32 v3, v0274; GFX6-NEXT: v_sub_f32_e32 v4, v0, v3275; GFX6-NEXT: s_mov_b32 s6, 0276; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4277; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v0278; GFX6-NEXT: s_mov_b32 s7, 0xf000279; GFX6-NEXT: s_mov_b32 s4, s6280; GFX6-NEXT: s_mov_b32 s5, s6281; GFX6-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc282; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64283; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)284; GFX6-NEXT: s_setpc_b64 s[30:31]285;286; GFX7-LABEL: safe_math_fract_f32_noinf_check:287; GFX7: ; %bb.0: ; %entry288; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)289; GFX7-NEXT: s_mov_b32 s6, 0290; GFX7-NEXT: s_mov_b32 s7, 0xf000291; GFX7-NEXT: s_mov_b32 s4, s6292; GFX7-NEXT: s_mov_b32 s5, s6293; GFX7-NEXT: v_floor_f32_e32 v3, v0294; GFX7-NEXT: v_fract_f32_e32 v0, v0295; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64296; GFX7-NEXT: s_waitcnt vmcnt(0)297; GFX7-NEXT: s_setpc_b64 s[30:31]298;299; GFX8-LABEL: safe_math_fract_f32_noinf_check:300; GFX8: ; %bb.0: ; %entry301; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)302; GFX8-NEXT: v_floor_f32_e32 v3, v0303; GFX8-NEXT: v_fract_f32_e32 v0, v0304; GFX8-NEXT: global_store_dword v[1:2], v3, off305; GFX8-NEXT: s_waitcnt vmcnt(0)306; GFX8-NEXT: s_setpc_b64 s[30:31]307;308; GFX11-LABEL: safe_math_fract_f32_noinf_check:309; GFX11: ; %bb.0: ; %entry310; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)311; GFX11-NEXT: v_floor_f32_e32 v3, v0312; GFX11-NEXT: v_fract_f32_e32 v0, v0313; GFX11-NEXT: global_store_b32 v[1:2], v3, off314; GFX11-NEXT: s_setpc_b64 s[30:31]315;316; GFX12-LABEL: safe_math_fract_f32_noinf_check:317; GFX12: ; %bb.0: ; %entry318; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0319; GFX12-NEXT: s_wait_expcnt 0x0320; GFX12-NEXT: s_wait_samplecnt 0x0321; GFX12-NEXT: s_wait_bvhcnt 0x0322; GFX12-NEXT: s_wait_kmcnt 0x0323; GFX12-NEXT: v_floor_f32_e32 v3, v0324; GFX12-NEXT: v_fract_f32_e32 v0, v0325; GFX12-NEXT: global_store_b32 v[1:2], v3, off326; GFX12-NEXT: s_setpc_b64 s[30:31]327entry:328 %floor = tail call float @llvm.floor.f32(float %x)329 %sub = fsub float %x, %floor330 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)331 %uno = fcmp uno float %x, 0.000000e+00332 %cond = select i1 %uno, float %x, float %min333 store float %floor, ptr addrspace(1) %ip, align 4334 ret float %cond335}336 337; Cannot match fract without a nan check or no-nans.338define float @no_nan_check_math_fract_f32(float %x, ptr addrspace(1) writeonly captures(none) %ip) {339; IR-LABEL: define float @no_nan_check_math_fract_f32(340; IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0:[0-9]+]] {341; IR-NEXT: [[ENTRY:.*:]]342; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])343; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]344; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)345; IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])346; IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000347; IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[MIN]]348; IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 4349; IR-NEXT: ret float [[COND6]]350;351; GFX6-LABEL: no_nan_check_math_fract_f32:352; GFX6: ; %bb.0: ; %entry353; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)354; GFX6-NEXT: v_floor_f32_e32 v3, v0355; GFX6-NEXT: v_sub_f32_e32 v4, v0, v3356; GFX6-NEXT: s_mov_b32 s8, 0x7f800000357; GFX6-NEXT: s_mov_b32 s6, 0358; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4359; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s8360; GFX6-NEXT: s_mov_b32 s7, 0xf000361; GFX6-NEXT: s_mov_b32 s4, s6362; GFX6-NEXT: s_mov_b32 s5, s6363; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc364; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64365; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)366; GFX6-NEXT: s_setpc_b64 s[30:31]367;368; GFX7-LABEL: no_nan_check_math_fract_f32:369; GFX7: ; %bb.0: ; %entry370; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)371; GFX7-NEXT: v_floor_f32_e32 v3, v0372; GFX7-NEXT: v_sub_f32_e32 v4, v0, v3373; GFX7-NEXT: s_mov_b32 s8, 0x7f800000374; GFX7-NEXT: s_mov_b32 s6, 0375; GFX7-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4376; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s8377; GFX7-NEXT: s_mov_b32 s7, 0xf000378; GFX7-NEXT: s_mov_b32 s4, s6379; GFX7-NEXT: s_mov_b32 s5, s6380; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc381; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64382; GFX7-NEXT: s_waitcnt vmcnt(0)383; GFX7-NEXT: s_setpc_b64 s[30:31]384;385; GFX8-LABEL: no_nan_check_math_fract_f32:386; GFX8: ; %bb.0: ; %entry387; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)388; GFX8-NEXT: v_floor_f32_e32 v3, v0389; GFX8-NEXT: v_sub_f32_e32 v4, v0, v3390; GFX8-NEXT: s_mov_b32 s4, 0x7f800000391; GFX8-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4392; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4393; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc394; GFX8-NEXT: global_store_dword v[1:2], v3, off395; GFX8-NEXT: s_waitcnt vmcnt(0)396; GFX8-NEXT: s_setpc_b64 s[30:31]397;398; GFX11-LABEL: no_nan_check_math_fract_f32:399; GFX11: ; %bb.0: ; %entry400; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)401; GFX11-NEXT: v_floor_f32_e32 v3, v0402; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|403; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)404; GFX11-NEXT: v_sub_f32_e32 v4, v0, v3405; GFX11-NEXT: global_store_b32 v[1:2], v3, off406; GFX11-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v4407; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc_lo408; GFX11-NEXT: s_setpc_b64 s[30:31]409;410; GFX12-LABEL: no_nan_check_math_fract_f32:411; GFX12: ; %bb.0: ; %entry412; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0413; GFX12-NEXT: s_wait_expcnt 0x0414; GFX12-NEXT: s_wait_samplecnt 0x0415; GFX12-NEXT: s_wait_bvhcnt 0x0416; GFX12-NEXT: s_wait_kmcnt 0x0417; GFX12-NEXT: v_floor_f32_e32 v3, v0418; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|419; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_1)420; GFX12-NEXT: v_sub_f32_e32 v4, v0, v3421; GFX12-NEXT: global_store_b32 v[1:2], v3, off422; GFX12-NEXT: v_min_num_f32_e32 v4, 0x3f7fffff, v4423; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)424; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc_lo425; GFX12-NEXT: s_setpc_b64 s[30:31]426entry:427 %floor = tail call float @llvm.floor.f32(float %x)428 %sub = fsub float %x, %floor429 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)430 %fabs = tail call float @llvm.fabs.f32(float %x)431 %cmpinf = fcmp oeq float %fabs, 0x7FF0000000000000432 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %min433 store float %floor, ptr addrspace(1) %ip, align 4434 ret float %cond6435}436 437define float @basic_fract_f32_nonans(float nofpclass(nan) %x) {438; GFX6-IR-LABEL: define float @basic_fract_f32_nonans(439; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {440; GFX6-IR-NEXT: [[ENTRY:.*:]]441; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])442; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]443; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)444; GFX6-IR-NEXT: ret float [[MIN]]445;446; IR-FRACT-LABEL: define float @basic_fract_f32_nonans(447; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {448; IR-FRACT-NEXT: [[ENTRY:.*:]]449; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])450; IR-FRACT-NEXT: ret float [[MIN]]451;452; GFX6-LABEL: basic_fract_f32_nonans:453; GFX6: ; %bb.0: ; %entry454; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)455; GFX6-NEXT: v_floor_f32_e32 v1, v0456; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1457; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0458; GFX6-NEXT: s_setpc_b64 s[30:31]459;460; GFX7-LABEL: basic_fract_f32_nonans:461; GFX7: ; %bb.0: ; %entry462; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)463; GFX7-NEXT: v_fract_f32_e32 v0, v0464; GFX7-NEXT: s_setpc_b64 s[30:31]465;466; GFX8-LABEL: basic_fract_f32_nonans:467; GFX8: ; %bb.0: ; %entry468; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)469; GFX8-NEXT: v_fract_f32_e32 v0, v0470; GFX8-NEXT: s_setpc_b64 s[30:31]471;472; GFX11-LABEL: basic_fract_f32_nonans:473; GFX11: ; %bb.0: ; %entry474; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)475; GFX11-NEXT: v_fract_f32_e32 v0, v0476; GFX11-NEXT: s_setpc_b64 s[30:31]477;478; GFX12-LABEL: basic_fract_f32_nonans:479; GFX12: ; %bb.0: ; %entry480; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0481; GFX12-NEXT: s_wait_expcnt 0x0482; GFX12-NEXT: s_wait_samplecnt 0x0483; GFX12-NEXT: s_wait_bvhcnt 0x0484; GFX12-NEXT: s_wait_kmcnt 0x0485; GFX12-NEXT: v_fract_f32_e32 v0, v0486; GFX12-NEXT: s_setpc_b64 s[30:31]487entry:488 %floor = tail call float @llvm.floor.f32(float %x)489 %sub = fsub float %x, %floor490 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)491 ret float %min492}493 494define float @basic_fract_f32_flags_minnum(float %x) {495; IR-LABEL: define float @basic_fract_f32_flags_minnum(496; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {497; IR-NEXT: [[ENTRY:.*:]]498; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])499; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]500; IR-NEXT: [[MIN:%.*]] = tail call nsz float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)501; IR-NEXT: ret float [[MIN]]502;503; GFX6-LABEL: basic_fract_f32_flags_minnum:504; GFX6: ; %bb.0: ; %entry505; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)506; GFX6-NEXT: v_floor_f32_e32 v1, v0507; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1508; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0509; GFX6-NEXT: s_setpc_b64 s[30:31]510;511; GFX7-LABEL: basic_fract_f32_flags_minnum:512; GFX7: ; %bb.0: ; %entry513; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)514; GFX7-NEXT: v_floor_f32_e32 v1, v0515; GFX7-NEXT: v_sub_f32_e32 v0, v0, v1516; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0517; GFX7-NEXT: s_setpc_b64 s[30:31]518;519; GFX8-LABEL: basic_fract_f32_flags_minnum:520; GFX8: ; %bb.0: ; %entry521; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)522; GFX8-NEXT: v_floor_f32_e32 v1, v0523; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1524; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0525; GFX8-NEXT: s_setpc_b64 s[30:31]526;527; GFX11-LABEL: basic_fract_f32_flags_minnum:528; GFX11: ; %bb.0: ; %entry529; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)530; GFX11-NEXT: v_floor_f32_e32 v1, v0531; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)532; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1533; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0534; GFX11-NEXT: s_setpc_b64 s[30:31]535;536; GFX12-LABEL: basic_fract_f32_flags_minnum:537; GFX12: ; %bb.0: ; %entry538; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0539; GFX12-NEXT: s_wait_expcnt 0x0540; GFX12-NEXT: s_wait_samplecnt 0x0541; GFX12-NEXT: s_wait_bvhcnt 0x0542; GFX12-NEXT: s_wait_kmcnt 0x0543; GFX12-NEXT: v_floor_f32_e32 v1, v0544; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)545; GFX12-NEXT: v_sub_f32_e32 v0, v0, v1546; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v0547; GFX12-NEXT: s_setpc_b64 s[30:31]548entry:549 %floor = tail call float @llvm.floor.f32(float %x)550 %sub = fsub float %x, %floor551 %min = tail call nsz float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)552 ret float %min553}554 555define float @basic_fract_f32_flags_fsub(float nofpclass(nan) %x) {556; GFX6-IR-LABEL: define float @basic_fract_f32_flags_fsub(557; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {558; GFX6-IR-NEXT: [[ENTRY:.*:]]559; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])560; GFX6-IR-NEXT: [[SUB:%.*]] = fsub nsz float [[X]], [[FLOOR]]561; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)562; GFX6-IR-NEXT: ret float [[MIN]]563;564; IR-FRACT-LABEL: define float @basic_fract_f32_flags_fsub(565; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {566; IR-FRACT-NEXT: [[ENTRY:.*:]]567; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])568; IR-FRACT-NEXT: ret float [[MIN]]569;570; GFX6-LABEL: basic_fract_f32_flags_fsub:571; GFX6: ; %bb.0: ; %entry572; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)573; GFX6-NEXT: v_floor_f32_e32 v1, v0574; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1575; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0576; GFX6-NEXT: s_setpc_b64 s[30:31]577;578; GFX7-LABEL: basic_fract_f32_flags_fsub:579; GFX7: ; %bb.0: ; %entry580; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)581; GFX7-NEXT: v_fract_f32_e32 v0, v0582; GFX7-NEXT: s_setpc_b64 s[30:31]583;584; GFX8-LABEL: basic_fract_f32_flags_fsub:585; GFX8: ; %bb.0: ; %entry586; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)587; GFX8-NEXT: v_fract_f32_e32 v0, v0588; GFX8-NEXT: s_setpc_b64 s[30:31]589;590; GFX11-LABEL: basic_fract_f32_flags_fsub:591; GFX11: ; %bb.0: ; %entry592; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)593; GFX11-NEXT: v_fract_f32_e32 v0, v0594; GFX11-NEXT: s_setpc_b64 s[30:31]595;596; GFX12-LABEL: basic_fract_f32_flags_fsub:597; GFX12: ; %bb.0: ; %entry598; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0599; GFX12-NEXT: s_wait_expcnt 0x0600; GFX12-NEXT: s_wait_samplecnt 0x0601; GFX12-NEXT: s_wait_bvhcnt 0x0602; GFX12-NEXT: s_wait_kmcnt 0x0603; GFX12-NEXT: v_fract_f32_e32 v0, v0604; GFX12-NEXT: s_setpc_b64 s[30:31]605entry:606 %floor = tail call float @llvm.floor.f32(float %x)607 %sub = fsub nsz float %x, %floor608 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)609 ret float %min610}611 612define <2 x float> @basic_fract_v2f32_nonans(<2 x float> nofpclass(nan) %x) {613; GFX6-IR-LABEL: define <2 x float> @basic_fract_v2f32_nonans(614; GFX6-IR-SAME: <2 x float> nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {615; GFX6-IR-NEXT: [[ENTRY:.*:]]616; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x float> @llvm.floor.v2f32(<2 x float> [[X]])617; GFX6-IR-NEXT: [[SUB:%.*]] = fsub <2 x float> [[X]], [[FLOOR]]618; GFX6-IR-NEXT: [[MIN:%.*]] = tail call <2 x float> @llvm.minnum.v2f32(<2 x float> [[SUB]], <2 x float> splat (float 0x3FEFFFFFE0000000))619; GFX6-IR-NEXT: ret <2 x float> [[MIN]]620;621; IR-FRACT-LABEL: define <2 x float> @basic_fract_v2f32_nonans(622; IR-FRACT-SAME: <2 x float> nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {623; IR-FRACT-NEXT: [[ENTRY:.*:]]624; IR-FRACT-NEXT: [[TMP0:%.*]] = extractelement <2 x float> [[X]], i64 0625; IR-FRACT-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[X]], i64 1626; IR-FRACT-NEXT: [[TMP2:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[TMP0]])627; IR-FRACT-NEXT: [[TMP3:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[TMP1]])628; IR-FRACT-NEXT: [[TMP4:%.*]] = insertelement <2 x float> poison, float [[TMP2]], i64 0629; IR-FRACT-NEXT: [[MIN:%.*]] = insertelement <2 x float> [[TMP4]], float [[TMP3]], i64 1630; IR-FRACT-NEXT: ret <2 x float> [[MIN]]631;632; GFX6-LABEL: basic_fract_v2f32_nonans:633; GFX6: ; %bb.0: ; %entry634; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)635; GFX6-NEXT: v_floor_f32_e32 v2, v0636; GFX6-NEXT: v_floor_f32_e32 v3, v1637; GFX6-NEXT: v_sub_f32_e32 v1, v1, v3638; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2639; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0640; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v1641; GFX6-NEXT: s_setpc_b64 s[30:31]642;643; GFX7-LABEL: basic_fract_v2f32_nonans:644; GFX7: ; %bb.0: ; %entry645; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)646; GFX7-NEXT: v_fract_f32_e32 v0, v0647; GFX7-NEXT: v_fract_f32_e32 v1, v1648; GFX7-NEXT: s_setpc_b64 s[30:31]649;650; GFX8-LABEL: basic_fract_v2f32_nonans:651; GFX8: ; %bb.0: ; %entry652; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)653; GFX8-NEXT: v_fract_f32_e32 v0, v0654; GFX8-NEXT: v_fract_f32_e32 v1, v1655; GFX8-NEXT: s_setpc_b64 s[30:31]656;657; GFX11-LABEL: basic_fract_v2f32_nonans:658; GFX11: ; %bb.0: ; %entry659; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)660; GFX11-NEXT: v_fract_f32_e32 v0, v0661; GFX11-NEXT: v_fract_f32_e32 v1, v1662; GFX11-NEXT: s_setpc_b64 s[30:31]663;664; GFX12-LABEL: basic_fract_v2f32_nonans:665; GFX12: ; %bb.0: ; %entry666; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0667; GFX12-NEXT: s_wait_expcnt 0x0668; GFX12-NEXT: s_wait_samplecnt 0x0669; GFX12-NEXT: s_wait_bvhcnt 0x0670; GFX12-NEXT: s_wait_kmcnt 0x0671; GFX12-NEXT: v_fract_f32_e32 v0, v0672; GFX12-NEXT: v_fract_f32_e32 v1, v1673; GFX12-NEXT: s_setpc_b64 s[30:31]674entry:675 %floor = tail call <2 x float> @llvm.floor.v2f32(<2 x float> %x)676 %sub = fsub <2 x float> %x, %floor677 %min = tail call <2 x float> @llvm.minnum.v2f32(<2 x float> %sub, <2 x float> <float 0x3FEFFFFFE0000000, float 0x3FEFFFFFE0000000>)678 ret <2 x float> %min679}680 681define float @basic_fract_f32_multi_use_fsub_nonans(float nofpclass(nan) %x, ptr addrspace(1) %ptr) {682; GFX6-IR-LABEL: define float @basic_fract_f32_multi_use_fsub_nonans(683; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {684; GFX6-IR-NEXT: [[ENTRY:.*:]]685; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])686; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]687; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)688; GFX6-IR-NEXT: store float [[SUB]], ptr addrspace(1) [[PTR]], align 4689; GFX6-IR-NEXT: ret float [[MIN]]690;691; IR-FRACT-LABEL: define float @basic_fract_f32_multi_use_fsub_nonans(692; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]], ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {693; IR-FRACT-NEXT: [[ENTRY:.*:]]694; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])695; IR-FRACT-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]696; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])697; IR-FRACT-NEXT: store float [[SUB]], ptr addrspace(1) [[PTR]], align 4698; IR-FRACT-NEXT: ret float [[MIN]]699;700; GFX6-LABEL: basic_fract_f32_multi_use_fsub_nonans:701; GFX6: ; %bb.0: ; %entry702; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)703; GFX6-NEXT: v_floor_f32_e32 v3, v0704; GFX6-NEXT: s_mov_b32 s6, 0705; GFX6-NEXT: v_sub_f32_e32 v3, v0, v3706; GFX6-NEXT: s_mov_b32 s7, 0xf000707; GFX6-NEXT: s_mov_b32 s4, s6708; GFX6-NEXT: s_mov_b32 s5, s6709; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v3710; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64711; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)712; GFX6-NEXT: s_setpc_b64 s[30:31]713;714; GFX7-LABEL: basic_fract_f32_multi_use_fsub_nonans:715; GFX7: ; %bb.0: ; %entry716; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)717; GFX7-NEXT: s_mov_b32 s6, 0718; GFX7-NEXT: v_floor_f32_e32 v3, v0719; GFX7-NEXT: s_mov_b32 s7, 0xf000720; GFX7-NEXT: s_mov_b32 s4, s6721; GFX7-NEXT: s_mov_b32 s5, s6722; GFX7-NEXT: v_sub_f32_e32 v3, v0, v3723; GFX7-NEXT: v_fract_f32_e32 v0, v0724; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr64725; GFX7-NEXT: s_waitcnt vmcnt(0)726; GFX7-NEXT: s_setpc_b64 s[30:31]727;728; GFX8-LABEL: basic_fract_f32_multi_use_fsub_nonans:729; GFX8: ; %bb.0: ; %entry730; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)731; GFX8-NEXT: v_floor_f32_e32 v3, v0732; GFX8-NEXT: v_sub_f32_e32 v3, v0, v3733; GFX8-NEXT: v_fract_f32_e32 v0, v0734; GFX8-NEXT: global_store_dword v[1:2], v3, off735; GFX8-NEXT: s_waitcnt vmcnt(0)736; GFX8-NEXT: s_setpc_b64 s[30:31]737;738; GFX11-LABEL: basic_fract_f32_multi_use_fsub_nonans:739; GFX11: ; %bb.0: ; %entry740; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)741; GFX11-NEXT: v_floor_f32_e32 v3, v0742; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)743; GFX11-NEXT: v_sub_f32_e32 v3, v0, v3744; GFX11-NEXT: v_fract_f32_e32 v0, v0745; GFX11-NEXT: global_store_b32 v[1:2], v3, off746; GFX11-NEXT: s_setpc_b64 s[30:31]747;748; GFX12-LABEL: basic_fract_f32_multi_use_fsub_nonans:749; GFX12: ; %bb.0: ; %entry750; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0751; GFX12-NEXT: s_wait_expcnt 0x0752; GFX12-NEXT: s_wait_samplecnt 0x0753; GFX12-NEXT: s_wait_bvhcnt 0x0754; GFX12-NEXT: s_wait_kmcnt 0x0755; GFX12-NEXT: v_floor_f32_e32 v3, v0756; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1)757; GFX12-NEXT: v_sub_f32_e32 v3, v0, v3758; GFX12-NEXT: v_fract_f32_e32 v0, v0759; GFX12-NEXT: global_store_b32 v[1:2], v3, off760; GFX12-NEXT: s_setpc_b64 s[30:31]761entry:762 %floor = tail call float @llvm.floor.f32(float %x)763 %sub = fsub float %x, %floor764 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)765 store float %sub, ptr addrspace(1) %ptr766 ret float %min767}768 769define float @nnan_minnum_fract_f32(float %x) {770; GFX6-IR-LABEL: define float @nnan_minnum_fract_f32(771; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {772; GFX6-IR-NEXT: [[ENTRY:.*:]]773; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])774; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]775; GFX6-IR-NEXT: [[MIN:%.*]] = tail call nnan float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)776; GFX6-IR-NEXT: ret float [[MIN]]777;778; IR-FRACT-LABEL: define float @nnan_minnum_fract_f32(779; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {780; IR-FRACT-NEXT: [[ENTRY:.*:]]781; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])782; IR-FRACT-NEXT: ret float [[MIN]]783;784; GFX6-LABEL: nnan_minnum_fract_f32:785; GFX6: ; %bb.0: ; %entry786; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)787; GFX6-NEXT: v_floor_f32_e32 v1, v0788; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1789; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0790; GFX6-NEXT: s_setpc_b64 s[30:31]791;792; GFX7-LABEL: nnan_minnum_fract_f32:793; GFX7: ; %bb.0: ; %entry794; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)795; GFX7-NEXT: v_fract_f32_e32 v0, v0796; GFX7-NEXT: s_setpc_b64 s[30:31]797;798; GFX8-LABEL: nnan_minnum_fract_f32:799; GFX8: ; %bb.0: ; %entry800; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)801; GFX8-NEXT: v_fract_f32_e32 v0, v0802; GFX8-NEXT: s_setpc_b64 s[30:31]803;804; GFX11-LABEL: nnan_minnum_fract_f32:805; GFX11: ; %bb.0: ; %entry806; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)807; GFX11-NEXT: v_fract_f32_e32 v0, v0808; GFX11-NEXT: s_setpc_b64 s[30:31]809;810; GFX12-LABEL: nnan_minnum_fract_f32:811; GFX12: ; %bb.0: ; %entry812; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0813; GFX12-NEXT: s_wait_expcnt 0x0814; GFX12-NEXT: s_wait_samplecnt 0x0815; GFX12-NEXT: s_wait_bvhcnt 0x0816; GFX12-NEXT: s_wait_kmcnt 0x0817; GFX12-NEXT: v_fract_f32_e32 v0, v0818; GFX12-NEXT: s_setpc_b64 s[30:31]819entry:820 %floor = tail call float @llvm.floor.f32(float %x)821 %sub = fsub float %x, %floor822 %min = tail call nnan float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)823 ret float %min824}825 826; TODO: Could match if we checked isKnownNeverNaN on the minnum src827; instead of the pattern input source.828define float @nnan_fsub_fract_f32(float %x) {829; IR-LABEL: define float @nnan_fsub_fract_f32(830; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {831; IR-NEXT: [[ENTRY:.*:]]832; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])833; IR-NEXT: [[SUB:%.*]] = fsub nnan float [[X]], [[FLOOR]]834; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)835; IR-NEXT: ret float [[MIN]]836;837; GFX6-LABEL: nnan_fsub_fract_f32:838; GFX6: ; %bb.0: ; %entry839; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)840; GFX6-NEXT: v_floor_f32_e32 v1, v0841; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1842; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0843; GFX6-NEXT: s_setpc_b64 s[30:31]844;845; GFX7-LABEL: nnan_fsub_fract_f32:846; GFX7: ; %bb.0: ; %entry847; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)848; GFX7-NEXT: v_floor_f32_e32 v1, v0849; GFX7-NEXT: v_sub_f32_e32 v0, v0, v1850; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0851; GFX7-NEXT: s_setpc_b64 s[30:31]852;853; GFX8-LABEL: nnan_fsub_fract_f32:854; GFX8: ; %bb.0: ; %entry855; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)856; GFX8-NEXT: v_floor_f32_e32 v1, v0857; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1858; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0859; GFX8-NEXT: s_setpc_b64 s[30:31]860;861; GFX11-LABEL: nnan_fsub_fract_f32:862; GFX11: ; %bb.0: ; %entry863; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)864; GFX11-NEXT: v_floor_f32_e32 v1, v0865; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)866; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1867; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0868; GFX11-NEXT: s_setpc_b64 s[30:31]869;870; GFX12-LABEL: nnan_fsub_fract_f32:871; GFX12: ; %bb.0: ; %entry872; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0873; GFX12-NEXT: s_wait_expcnt 0x0874; GFX12-NEXT: s_wait_samplecnt 0x0875; GFX12-NEXT: s_wait_bvhcnt 0x0876; GFX12-NEXT: s_wait_kmcnt 0x0877; GFX12-NEXT: v_floor_f32_e32 v1, v0878; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)879; GFX12-NEXT: v_sub_f32_e32 v0, v0, v1880; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v0881; GFX12-NEXT: s_setpc_b64 s[30:31]882entry:883 %floor = tail call float @llvm.floor.f32(float %x)884 %sub = fsub nnan float %x, %floor885 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)886 ret float %min887}888 889define float @nnan_floor_fract_f32(float %x) {890; IR-LABEL: define float @nnan_floor_fract_f32(891; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {892; IR-NEXT: [[ENTRY:.*:]]893; IR-NEXT: [[FLOOR:%.*]] = tail call nnan float @llvm.floor.f32(float [[X]])894; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]895; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)896; IR-NEXT: ret float [[MIN]]897;898; GFX6-LABEL: nnan_floor_fract_f32:899; GFX6: ; %bb.0: ; %entry900; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)901; GFX6-NEXT: v_floor_f32_e32 v1, v0902; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1903; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0904; GFX6-NEXT: s_setpc_b64 s[30:31]905;906; GFX7-LABEL: nnan_floor_fract_f32:907; GFX7: ; %bb.0: ; %entry908; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)909; GFX7-NEXT: v_floor_f32_e32 v1, v0910; GFX7-NEXT: v_sub_f32_e32 v0, v0, v1911; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0912; GFX7-NEXT: s_setpc_b64 s[30:31]913;914; GFX8-LABEL: nnan_floor_fract_f32:915; GFX8: ; %bb.0: ; %entry916; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)917; GFX8-NEXT: v_floor_f32_e32 v1, v0918; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1919; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0920; GFX8-NEXT: s_setpc_b64 s[30:31]921;922; GFX11-LABEL: nnan_floor_fract_f32:923; GFX11: ; %bb.0: ; %entry924; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)925; GFX11-NEXT: v_floor_f32_e32 v1, v0926; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)927; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1928; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0929; GFX11-NEXT: s_setpc_b64 s[30:31]930;931; GFX12-LABEL: nnan_floor_fract_f32:932; GFX12: ; %bb.0: ; %entry933; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0934; GFX12-NEXT: s_wait_expcnt 0x0935; GFX12-NEXT: s_wait_samplecnt 0x0936; GFX12-NEXT: s_wait_bvhcnt 0x0937; GFX12-NEXT: s_wait_kmcnt 0x0938; GFX12-NEXT: v_floor_f32_e32 v1, v0939; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)940; GFX12-NEXT: v_sub_f32_e32 v0, v0, v1941; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v0942; GFX12-NEXT: s_setpc_b64 s[30:31]943entry:944 %floor = tail call nnan float @llvm.floor.f32(float %x)945 %sub = fsub float %x, %floor946 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)947 ret float %min948}949 950define float @nnan_src_fract_f32(float nofpclass(nan) %x) {951; GFX6-IR-LABEL: define float @nnan_src_fract_f32(952; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {953; GFX6-IR-NEXT: [[ENTRY:.*:]]954; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])955; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]956; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)957; GFX6-IR-NEXT: ret float [[MIN]]958;959; IR-FRACT-LABEL: define float @nnan_src_fract_f32(960; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {961; IR-FRACT-NEXT: [[ENTRY:.*:]]962; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])963; IR-FRACT-NEXT: ret float [[MIN]]964;965; GFX6-LABEL: nnan_src_fract_f32:966; GFX6: ; %bb.0: ; %entry967; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)968; GFX6-NEXT: v_floor_f32_e32 v1, v0969; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1970; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v0971; GFX6-NEXT: s_setpc_b64 s[30:31]972;973; GFX7-LABEL: nnan_src_fract_f32:974; GFX7: ; %bb.0: ; %entry975; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)976; GFX7-NEXT: v_fract_f32_e32 v0, v0977; GFX7-NEXT: s_setpc_b64 s[30:31]978;979; GFX8-LABEL: nnan_src_fract_f32:980; GFX8: ; %bb.0: ; %entry981; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)982; GFX8-NEXT: v_fract_f32_e32 v0, v0983; GFX8-NEXT: s_setpc_b64 s[30:31]984;985; GFX11-LABEL: nnan_src_fract_f32:986; GFX11: ; %bb.0: ; %entry987; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)988; GFX11-NEXT: v_fract_f32_e32 v0, v0989; GFX11-NEXT: s_setpc_b64 s[30:31]990;991; GFX12-LABEL: nnan_src_fract_f32:992; GFX12: ; %bb.0: ; %entry993; GFX12-NEXT: s_wait_loadcnt_dscnt 0x0994; GFX12-NEXT: s_wait_expcnt 0x0995; GFX12-NEXT: s_wait_samplecnt 0x0996; GFX12-NEXT: s_wait_bvhcnt 0x0997; GFX12-NEXT: s_wait_kmcnt 0x0998; GFX12-NEXT: v_fract_f32_e32 v0, v0999; GFX12-NEXT: s_setpc_b64 s[30:31]1000entry:1001 %floor = tail call float @llvm.floor.f32(float %x)1002 %sub = fsub float %x, %floor1003 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1004 ret float %min1005}1006 1007; Negative test1008define float @not_fract_f32_wrong_const(float nofpclass(nan) %x) {1009; IR-LABEL: define float @not_fract_f32_wrong_const(1010; IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1011; IR-NEXT: [[ENTRY:.*:]]1012; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1013; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1014; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFC0000000)1015; IR-NEXT: ret float [[MIN]]1016;1017; GFX6-LABEL: not_fract_f32_wrong_const:1018; GFX6: ; %bb.0: ; %entry1019; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1020; GFX6-NEXT: v_floor_f32_e32 v1, v01021; GFX6-NEXT: v_sub_f32_e32 v0, v0, v11022; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7ffffe, v01023; GFX6-NEXT: s_setpc_b64 s[30:31]1024;1025; GFX7-LABEL: not_fract_f32_wrong_const:1026; GFX7: ; %bb.0: ; %entry1027; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1028; GFX7-NEXT: v_floor_f32_e32 v1, v01029; GFX7-NEXT: v_sub_f32_e32 v0, v0, v11030; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7ffffe, v01031; GFX7-NEXT: s_setpc_b64 s[30:31]1032;1033; GFX8-LABEL: not_fract_f32_wrong_const:1034; GFX8: ; %bb.0: ; %entry1035; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1036; GFX8-NEXT: v_floor_f32_e32 v1, v01037; GFX8-NEXT: v_sub_f32_e32 v0, v0, v11038; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7ffffe, v01039; GFX8-NEXT: s_setpc_b64 s[30:31]1040;1041; GFX11-LABEL: not_fract_f32_wrong_const:1042; GFX11: ; %bb.0: ; %entry1043; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1044; GFX11-NEXT: v_floor_f32_e32 v1, v01045; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1046; GFX11-NEXT: v_sub_f32_e32 v0, v0, v11047; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7ffffe, v01048; GFX11-NEXT: s_setpc_b64 s[30:31]1049;1050; GFX12-LABEL: not_fract_f32_wrong_const:1051; GFX12: ; %bb.0: ; %entry1052; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01053; GFX12-NEXT: s_wait_expcnt 0x01054; GFX12-NEXT: s_wait_samplecnt 0x01055; GFX12-NEXT: s_wait_bvhcnt 0x01056; GFX12-NEXT: s_wait_kmcnt 0x01057; GFX12-NEXT: v_floor_f32_e32 v1, v01058; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1059; GFX12-NEXT: v_sub_f32_e32 v0, v0, v11060; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7ffffe, v01061; GFX12-NEXT: s_setpc_b64 s[30:31]1062entry:1063 %floor = tail call float @llvm.floor.f32(float %x)1064 %sub = fsub float %x, %floor1065 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFC0000000)1066 ret float %min1067}1068 1069; Negative test1070define float @not_fract_f32_swapped_fsub(float nofpclass(nan) %x) {1071; IR-LABEL: define float @not_fract_f32_swapped_fsub(1072; IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1073; IR-NEXT: [[ENTRY:.*:]]1074; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1075; IR-NEXT: [[SUB:%.*]] = fsub float [[FLOOR]], [[X]]1076; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1077; IR-NEXT: ret float [[MIN]]1078;1079; GFX6-LABEL: not_fract_f32_swapped_fsub:1080; GFX6: ; %bb.0: ; %entry1081; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1082; GFX6-NEXT: v_floor_f32_e32 v1, v01083; GFX6-NEXT: v_sub_f32_e32 v0, v1, v01084; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01085; GFX6-NEXT: s_setpc_b64 s[30:31]1086;1087; GFX7-LABEL: not_fract_f32_swapped_fsub:1088; GFX7: ; %bb.0: ; %entry1089; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1090; GFX7-NEXT: v_floor_f32_e32 v1, v01091; GFX7-NEXT: v_sub_f32_e32 v0, v1, v01092; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01093; GFX7-NEXT: s_setpc_b64 s[30:31]1094;1095; GFX8-LABEL: not_fract_f32_swapped_fsub:1096; GFX8: ; %bb.0: ; %entry1097; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1098; GFX8-NEXT: v_floor_f32_e32 v1, v01099; GFX8-NEXT: v_sub_f32_e32 v0, v1, v01100; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01101; GFX8-NEXT: s_setpc_b64 s[30:31]1102;1103; GFX11-LABEL: not_fract_f32_swapped_fsub:1104; GFX11: ; %bb.0: ; %entry1105; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1106; GFX11-NEXT: v_floor_f32_e32 v1, v01107; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1108; GFX11-NEXT: v_sub_f32_e32 v0, v1, v01109; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01110; GFX11-NEXT: s_setpc_b64 s[30:31]1111;1112; GFX12-LABEL: not_fract_f32_swapped_fsub:1113; GFX12: ; %bb.0: ; %entry1114; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01115; GFX12-NEXT: s_wait_expcnt 0x01116; GFX12-NEXT: s_wait_samplecnt 0x01117; GFX12-NEXT: s_wait_bvhcnt 0x01118; GFX12-NEXT: s_wait_kmcnt 0x01119; GFX12-NEXT: v_floor_f32_e32 v1, v01120; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1121; GFX12-NEXT: v_sub_f32_e32 v0, v1, v01122; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v01123; GFX12-NEXT: s_setpc_b64 s[30:31]1124entry:1125 %floor = tail call float @llvm.floor.f32(float %x)1126 %sub = fsub float %floor, %x1127 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1128 ret float %min1129}1130 1131; Negative test1132define float @not_fract_f32_not_floor(float nofpclass(nan) %x) {1133; IR-LABEL: define float @not_fract_f32_not_floor(1134; IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1135; IR-NEXT: [[ENTRY:.*:]]1136; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.trunc.f32(float [[X]])1137; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1138; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1139; IR-NEXT: ret float [[MIN]]1140;1141; GFX6-LABEL: not_fract_f32_not_floor:1142; GFX6: ; %bb.0: ; %entry1143; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1144; GFX6-NEXT: v_trunc_f32_e32 v1, v01145; GFX6-NEXT: v_sub_f32_e32 v0, v0, v11146; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01147; GFX6-NEXT: s_setpc_b64 s[30:31]1148;1149; GFX7-LABEL: not_fract_f32_not_floor:1150; GFX7: ; %bb.0: ; %entry1151; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1152; GFX7-NEXT: v_trunc_f32_e32 v1, v01153; GFX7-NEXT: v_sub_f32_e32 v0, v0, v11154; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01155; GFX7-NEXT: s_setpc_b64 s[30:31]1156;1157; GFX8-LABEL: not_fract_f32_not_floor:1158; GFX8: ; %bb.0: ; %entry1159; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1160; GFX8-NEXT: v_trunc_f32_e32 v1, v01161; GFX8-NEXT: v_sub_f32_e32 v0, v0, v11162; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01163; GFX8-NEXT: s_setpc_b64 s[30:31]1164;1165; GFX11-LABEL: not_fract_f32_not_floor:1166; GFX11: ; %bb.0: ; %entry1167; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1168; GFX11-NEXT: v_trunc_f32_e32 v1, v01169; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1170; GFX11-NEXT: v_sub_f32_e32 v0, v0, v11171; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01172; GFX11-NEXT: s_setpc_b64 s[30:31]1173;1174; GFX12-LABEL: not_fract_f32_not_floor:1175; GFX12: ; %bb.0: ; %entry1176; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01177; GFX12-NEXT: s_wait_expcnt 0x01178; GFX12-NEXT: s_wait_samplecnt 0x01179; GFX12-NEXT: s_wait_bvhcnt 0x01180; GFX12-NEXT: s_wait_kmcnt 0x01181; GFX12-NEXT: v_trunc_f32_e32 v1, v01182; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1183; GFX12-NEXT: v_sub_f32_e32 v0, v0, v11184; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v01185; GFX12-NEXT: s_setpc_b64 s[30:31]1186entry:1187 %floor = tail call float @llvm.trunc.f32(float %x)1188 %sub = fsub float %x, %floor1189 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1190 ret float %min1191}1192 1193; Negative test1194define float @not_fract_f32_different_floor(float %x, float %y) {1195; IR-LABEL: define float @not_fract_f32_different_floor(1196; IR-SAME: float [[X:%.*]], float [[Y:%.*]]) #[[ATTR0]] {1197; IR-NEXT: [[ENTRY:.*:]]1198; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[Y]])1199; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1200; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1201; IR-NEXT: ret float [[MIN]]1202;1203; GFX6-LABEL: not_fract_f32_different_floor:1204; GFX6: ; %bb.0: ; %entry1205; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1206; GFX6-NEXT: v_floor_f32_e32 v1, v11207; GFX6-NEXT: v_sub_f32_e32 v0, v0, v11208; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01209; GFX6-NEXT: s_setpc_b64 s[30:31]1210;1211; GFX7-LABEL: not_fract_f32_different_floor:1212; GFX7: ; %bb.0: ; %entry1213; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1214; GFX7-NEXT: v_floor_f32_e32 v1, v11215; GFX7-NEXT: v_sub_f32_e32 v0, v0, v11216; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01217; GFX7-NEXT: s_setpc_b64 s[30:31]1218;1219; GFX8-LABEL: not_fract_f32_different_floor:1220; GFX8: ; %bb.0: ; %entry1221; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1222; GFX8-NEXT: v_floor_f32_e32 v1, v11223; GFX8-NEXT: v_sub_f32_e32 v0, v0, v11224; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01225; GFX8-NEXT: s_setpc_b64 s[30:31]1226;1227; GFX11-LABEL: not_fract_f32_different_floor:1228; GFX11: ; %bb.0: ; %entry1229; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1230; GFX11-NEXT: v_floor_f32_e32 v1, v11231; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1232; GFX11-NEXT: v_sub_f32_e32 v0, v0, v11233; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v01234; GFX11-NEXT: s_setpc_b64 s[30:31]1235;1236; GFX12-LABEL: not_fract_f32_different_floor:1237; GFX12: ; %bb.0: ; %entry1238; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01239; GFX12-NEXT: s_wait_expcnt 0x01240; GFX12-NEXT: s_wait_samplecnt 0x01241; GFX12-NEXT: s_wait_bvhcnt 0x01242; GFX12-NEXT: s_wait_kmcnt 0x01243; GFX12-NEXT: v_floor_f32_e32 v1, v11244; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1245; GFX12-NEXT: v_sub_f32_e32 v0, v0, v11246; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v01247; GFX12-NEXT: s_setpc_b64 s[30:31]1248entry:1249 %floor = tail call float @llvm.floor.f32(float %y)1250 %sub = fsub float %x, %floor1251 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1252 ret float %min1253}1254 1255; Negative test1256define float @not_fract_f32_maxnum(float nofpclass(nan) %x) {1257; IR-LABEL: define float @not_fract_f32_maxnum(1258; IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1259; IR-NEXT: [[ENTRY:.*:]]1260; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1261; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1262; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.maxnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1263; IR-NEXT: ret float [[MIN]]1264;1265; GFX6-LABEL: not_fract_f32_maxnum:1266; GFX6: ; %bb.0: ; %entry1267; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1268; GFX6-NEXT: v_floor_f32_e32 v1, v01269; GFX6-NEXT: v_sub_f32_e32 v0, v0, v11270; GFX6-NEXT: v_max_f32_e32 v0, 0x3f7fffff, v01271; GFX6-NEXT: s_setpc_b64 s[30:31]1272;1273; GFX7-LABEL: not_fract_f32_maxnum:1274; GFX7: ; %bb.0: ; %entry1275; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1276; GFX7-NEXT: v_floor_f32_e32 v1, v01277; GFX7-NEXT: v_sub_f32_e32 v0, v0, v11278; GFX7-NEXT: v_max_f32_e32 v0, 0x3f7fffff, v01279; GFX7-NEXT: s_setpc_b64 s[30:31]1280;1281; GFX8-LABEL: not_fract_f32_maxnum:1282; GFX8: ; %bb.0: ; %entry1283; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1284; GFX8-NEXT: v_floor_f32_e32 v1, v01285; GFX8-NEXT: v_sub_f32_e32 v0, v0, v11286; GFX8-NEXT: v_max_f32_e32 v0, 0x3f7fffff, v01287; GFX8-NEXT: s_setpc_b64 s[30:31]1288;1289; GFX11-LABEL: not_fract_f32_maxnum:1290; GFX11: ; %bb.0: ; %entry1291; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1292; GFX11-NEXT: v_floor_f32_e32 v1, v01293; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1294; GFX11-NEXT: v_sub_f32_e32 v0, v0, v11295; GFX11-NEXT: v_max_f32_e32 v0, 0x3f7fffff, v01296; GFX11-NEXT: s_setpc_b64 s[30:31]1297;1298; GFX12-LABEL: not_fract_f32_maxnum:1299; GFX12: ; %bb.0: ; %entry1300; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01301; GFX12-NEXT: s_wait_expcnt 0x01302; GFX12-NEXT: s_wait_samplecnt 0x01303; GFX12-NEXT: s_wait_bvhcnt 0x01304; GFX12-NEXT: s_wait_kmcnt 0x01305; GFX12-NEXT: v_floor_f32_e32 v1, v01306; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)1307; GFX12-NEXT: v_sub_f32_e32 v0, v0, v11308; GFX12-NEXT: v_max_num_f32_e32 v0, 0x3f7fffff, v01309; GFX12-NEXT: s_setpc_b64 s[30:31]1310entry:1311 %floor = tail call float @llvm.floor.f32(float %x)1312 %sub = fsub float %x, %floor1313 %min = tail call float @llvm.maxnum.f32(float %sub, float 0x3FEFFFFFE0000000)1314 ret float %min1315}1316 1317define float @fcmp_uno_check_is_nan_f32(float %x) {1318; IR-LABEL: define float @fcmp_uno_check_is_nan_f32(1319; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {1320; IR-NEXT: [[ENTRY:.*:]]1321; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1322; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1323; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1324; IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0x7FF80000000000001325; IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]1326; IR-NEXT: ret float [[COND]]1327;1328; GCN-LABEL: fcmp_uno_check_is_nan_f32:1329; GCN: ; %bb.0: ; %entry1330; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1331; GCN-NEXT: s_setpc_b64 s[30:31]1332;1333; GFX12-LABEL: fcmp_uno_check_is_nan_f32:1334; GFX12: ; %bb.0: ; %entry1335; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01336; GFX12-NEXT: s_wait_expcnt 0x01337; GFX12-NEXT: s_wait_samplecnt 0x01338; GFX12-NEXT: s_wait_bvhcnt 0x01339; GFX12-NEXT: s_wait_kmcnt 0x01340; GFX12-NEXT: s_setpc_b64 s[30:31]1341entry:1342 %floor = tail call float @llvm.floor.f32(float %x)1343 %sub = fsub float %x, %floor1344 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1345 %uno = fcmp uno float %x, 0x7FF80000000000001346 %cond = select i1 %uno, float %x, float %min1347 ret float %cond1348}1349 1350; No inf check1351define float @select_nan_fract_f32(float %x) {1352; GFX6-IR-LABEL: define float @select_nan_fract_f32(1353; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {1354; GFX6-IR-NEXT: [[ENTRY:.*:]]1355; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1356; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1357; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1358; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+001359; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]1360; GFX6-IR-NEXT: ret float [[COND]]1361;1362; IR-FRACT-LABEL: define float @select_nan_fract_f32(1363; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {1364; IR-FRACT-NEXT: [[ENTRY:.*:]]1365; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])1366; IR-FRACT-NEXT: ret float [[COND]]1367;1368; GFX6-LABEL: select_nan_fract_f32:1369; GFX6: ; %bb.0: ; %entry1370; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1371; GFX6-NEXT: v_floor_f32_e32 v1, v01372; GFX6-NEXT: v_sub_f32_e32 v1, v0, v11373; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11374; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v01375; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc1376; GFX6-NEXT: s_setpc_b64 s[30:31]1377;1378; GFX7-LABEL: select_nan_fract_f32:1379; GFX7: ; %bb.0: ; %entry1380; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1381; GFX7-NEXT: v_fract_f32_e32 v0, v01382; GFX7-NEXT: s_setpc_b64 s[30:31]1383;1384; GFX8-LABEL: select_nan_fract_f32:1385; GFX8: ; %bb.0: ; %entry1386; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1387; GFX8-NEXT: v_fract_f32_e32 v0, v01388; GFX8-NEXT: s_setpc_b64 s[30:31]1389;1390; GFX11-LABEL: select_nan_fract_f32:1391; GFX11: ; %bb.0: ; %entry1392; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1393; GFX11-NEXT: v_fract_f32_e32 v0, v01394; GFX11-NEXT: s_setpc_b64 s[30:31]1395;1396; GFX12-LABEL: select_nan_fract_f32:1397; GFX12: ; %bb.0: ; %entry1398; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01399; GFX12-NEXT: s_wait_expcnt 0x01400; GFX12-NEXT: s_wait_samplecnt 0x01401; GFX12-NEXT: s_wait_bvhcnt 0x01402; GFX12-NEXT: s_wait_kmcnt 0x01403; GFX12-NEXT: v_fract_f32_e32 v0, v01404; GFX12-NEXT: s_setpc_b64 s[30:31]1405entry:1406 %floor = tail call float @llvm.floor.f32(float %x)1407 %sub = fsub float %x, %floor1408 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1409 %uno = fcmp uno float %x, 0.000000e+001410 %cond = select i1 %uno, float %x, float %min1411 ret float %cond1412}1413 1414define float @commuted_select_nan_fract_f32(float %x) {1415; GFX6-IR-LABEL: define float @commuted_select_nan_fract_f32(1416; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {1417; GFX6-IR-NEXT: [[ENTRY:.*:]]1418; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1419; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1420; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1421; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp ord float [[X]], 0.000000e+001422; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[MIN]], float [[X]]1423; GFX6-IR-NEXT: ret float [[COND]]1424;1425; IR-FRACT-LABEL: define float @commuted_select_nan_fract_f32(1426; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {1427; IR-FRACT-NEXT: [[ENTRY:.*:]]1428; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])1429; IR-FRACT-NEXT: ret float [[COND]]1430;1431; GFX6-LABEL: commuted_select_nan_fract_f32:1432; GFX6: ; %bb.0: ; %entry1433; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1434; GFX6-NEXT: v_floor_f32_e32 v1, v01435; GFX6-NEXT: v_sub_f32_e32 v1, v0, v11436; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11437; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v01438; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc1439; GFX6-NEXT: s_setpc_b64 s[30:31]1440;1441; GFX7-LABEL: commuted_select_nan_fract_f32:1442; GFX7: ; %bb.0: ; %entry1443; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1444; GFX7-NEXT: v_fract_f32_e32 v0, v01445; GFX7-NEXT: s_setpc_b64 s[30:31]1446;1447; GFX8-LABEL: commuted_select_nan_fract_f32:1448; GFX8: ; %bb.0: ; %entry1449; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1450; GFX8-NEXT: v_fract_f32_e32 v0, v01451; GFX8-NEXT: s_setpc_b64 s[30:31]1452;1453; GFX11-LABEL: commuted_select_nan_fract_f32:1454; GFX11: ; %bb.0: ; %entry1455; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1456; GFX11-NEXT: v_fract_f32_e32 v0, v01457; GFX11-NEXT: s_setpc_b64 s[30:31]1458;1459; GFX12-LABEL: commuted_select_nan_fract_f32:1460; GFX12: ; %bb.0: ; %entry1461; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01462; GFX12-NEXT: s_wait_expcnt 0x01463; GFX12-NEXT: s_wait_samplecnt 0x01464; GFX12-NEXT: s_wait_bvhcnt 0x01465; GFX12-NEXT: s_wait_kmcnt 0x01466; GFX12-NEXT: v_fract_f32_e32 v0, v01467; GFX12-NEXT: s_setpc_b64 s[30:31]1468entry:1469 %floor = tail call float @llvm.floor.f32(float %x)1470 %sub = fsub float %x, %floor1471 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1472 %uno = fcmp ord float %x, 0.000000e+001473 %cond = select i1 %uno, float %min, float %x1474 ret float %cond1475}1476 1477define float @wrong_commuted_nan_select_f32(float %x) {1478; IR-LABEL: define float @wrong_commuted_nan_select_f32(1479; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {1480; IR-NEXT: [[ENTRY:.*:]]1481; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])1482; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]1483; IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)1484; IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+001485; IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[MIN]], float [[X]]1486; IR-NEXT: ret float [[COND]]1487;1488; GFX6-LABEL: wrong_commuted_nan_select_f32:1489; GFX6: ; %bb.0: ; %entry1490; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1491; GFX6-NEXT: v_floor_f32_e32 v1, v01492; GFX6-NEXT: v_sub_f32_e32 v1, v0, v11493; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11494; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v01495; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc1496; GFX6-NEXT: s_setpc_b64 s[30:31]1497;1498; GFX7-LABEL: wrong_commuted_nan_select_f32:1499; GFX7: ; %bb.0: ; %entry1500; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1501; GFX7-NEXT: v_floor_f32_e32 v1, v01502; GFX7-NEXT: v_sub_f32_e32 v1, v0, v11503; GFX7-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11504; GFX7-NEXT: v_cmp_u_f32_e32 vcc, v0, v01505; GFX7-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc1506; GFX7-NEXT: s_setpc_b64 s[30:31]1507;1508; GFX8-LABEL: wrong_commuted_nan_select_f32:1509; GFX8: ; %bb.0: ; %entry1510; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1511; GFX8-NEXT: v_floor_f32_e32 v1, v01512; GFX8-NEXT: v_sub_f32_e32 v1, v0, v11513; GFX8-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11514; GFX8-NEXT: v_cmp_u_f32_e32 vcc, v0, v01515; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc1516; GFX8-NEXT: s_setpc_b64 s[30:31]1517;1518; GFX11-LABEL: wrong_commuted_nan_select_f32:1519; GFX11: ; %bb.0: ; %entry1520; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1521; GFX11-NEXT: v_floor_f32_e32 v1, v01522; GFX11-NEXT: v_cmp_u_f32_e32 vcc_lo, v0, v01523; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)1524; GFX11-NEXT: v_sub_f32_e32 v1, v0, v11525; GFX11-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v11526; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)1527; GFX11-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo1528; GFX11-NEXT: s_setpc_b64 s[30:31]1529;1530; GFX12-LABEL: wrong_commuted_nan_select_f32:1531; GFX12: ; %bb.0: ; %entry1532; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01533; GFX12-NEXT: s_wait_expcnt 0x01534; GFX12-NEXT: s_wait_samplecnt 0x01535; GFX12-NEXT: s_wait_bvhcnt 0x01536; GFX12-NEXT: s_wait_kmcnt 0x01537; GFX12-NEXT: v_floor_f32_e32 v1, v01538; GFX12-NEXT: v_cmp_u_f32_e32 vcc_lo, v0, v01539; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)1540; GFX12-NEXT: v_sub_f32_e32 v1, v0, v11541; GFX12-NEXT: v_min_num_f32_e32 v1, 0x3f7fffff, v11542; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)1543; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1)1544; GFX12-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo1545; GFX12-NEXT: s_setpc_b64 s[30:31]1546entry:1547 %floor = tail call float @llvm.floor.f32(float %x)1548 %sub = fsub float %x, %floor1549 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)1550 %uno = fcmp uno float %x, 0.000000e+001551 %cond = select i1 %uno, float %min, float %x1552 ret float %cond1553}1554 1555define half @basic_fract_f16_nonan(half nofpclass(nan) %x) {1556; GFX6-IR-LABEL: define half @basic_fract_f16_nonan(1557; GFX6-IR-SAME: half nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1558; GFX6-IR-NEXT: [[ENTRY:.*:]]1559; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])1560; GFX6-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]1561; GFX6-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)1562; GFX6-IR-NEXT: ret half [[MIN]]1563;1564; GFX7-IR-LABEL: define half @basic_fract_f16_nonan(1565; GFX7-IR-SAME: half nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1566; GFX7-IR-NEXT: [[ENTRY:.*:]]1567; GFX7-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])1568; GFX7-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]1569; GFX7-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)1570; GFX7-IR-NEXT: ret half [[MIN]]1571;1572; IR-LEGALF16-LABEL: define half @basic_fract_f16_nonan(1573; IR-LEGALF16-SAME: half nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1574; IR-LEGALF16-NEXT: [[ENTRY:.*:]]1575; IR-LEGALF16-NEXT: [[MIN:%.*]] = call nnan half @llvm.amdgcn.fract.f16(half [[X]])1576; IR-LEGALF16-NEXT: ret half [[MIN]]1577;1578; GFX6-LABEL: basic_fract_f16_nonan:1579; GFX6: ; %bb.0: ; %entry1580; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1581; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v01582; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v01583; GFX6-NEXT: v_floor_f32_e32 v1, v01584; GFX6-NEXT: v_sub_f32_e32 v0, v0, v11585; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fe000, v01586; GFX6-NEXT: s_setpc_b64 s[30:31]1587;1588; GFX7-LABEL: basic_fract_f16_nonan:1589; GFX7: ; %bb.0: ; %entry1590; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1591; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v01592; GFX7-NEXT: v_cvt_f32_f16_e32 v0, v01593; GFX7-NEXT: v_floor_f32_e32 v1, v01594; GFX7-NEXT: v_sub_f32_e32 v0, v0, v11595; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fe000, v01596; GFX7-NEXT: s_setpc_b64 s[30:31]1597;1598; GFX8-LABEL: basic_fract_f16_nonan:1599; GFX8: ; %bb.0: ; %entry1600; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1601; GFX8-NEXT: v_fract_f16_e32 v0, v01602; GFX8-NEXT: s_setpc_b64 s[30:31]1603;1604; GFX11-TRUE16-LABEL: basic_fract_f16_nonan:1605; GFX11-TRUE16: ; %bb.0: ; %entry1606; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1607; GFX11-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1608; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]1609;1610; GFX11-FAKE16-LABEL: basic_fract_f16_nonan:1611; GFX11-FAKE16: ; %bb.0: ; %entry1612; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1613; GFX11-FAKE16-NEXT: v_fract_f16_e32 v0, v01614; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]1615;1616; GFX12-TRUE16-LABEL: basic_fract_f16_nonan:1617; GFX12-TRUE16: ; %bb.0: ; %entry1618; GFX12-TRUE16-NEXT: s_wait_loadcnt_dscnt 0x01619; GFX12-TRUE16-NEXT: s_wait_expcnt 0x01620; GFX12-TRUE16-NEXT: s_wait_samplecnt 0x01621; GFX12-TRUE16-NEXT: s_wait_bvhcnt 0x01622; GFX12-TRUE16-NEXT: s_wait_kmcnt 0x01623; GFX12-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1624; GFX12-TRUE16-NEXT: s_setpc_b64 s[30:31]1625;1626; GFX12-FAKE16-LABEL: basic_fract_f16_nonan:1627; GFX12-FAKE16: ; %bb.0: ; %entry1628; GFX12-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x01629; GFX12-FAKE16-NEXT: s_wait_expcnt 0x01630; GFX12-FAKE16-NEXT: s_wait_samplecnt 0x01631; GFX12-FAKE16-NEXT: s_wait_bvhcnt 0x01632; GFX12-FAKE16-NEXT: s_wait_kmcnt 0x01633; GFX12-FAKE16-NEXT: v_fract_f16_e32 v0, v01634; GFX12-FAKE16-NEXT: s_setpc_b64 s[30:31]1635entry:1636 %floor = tail call half @llvm.floor.f16(half %x)1637 %sub = fsub half %x, %floor1638 %min = tail call half @llvm.minnum.f16(half %sub, half 0xH3BFF)1639 ret half %min1640}1641 1642define <2 x half> @basic_fract_v2f16_nonan(<2 x half> nofpclass(nan) %x) {1643; GFX6-IR-LABEL: define <2 x half> @basic_fract_v2f16_nonan(1644; GFX6-IR-SAME: <2 x half> nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1645; GFX6-IR-NEXT: [[ENTRY:.*:]]1646; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x half> @llvm.floor.v2f16(<2 x half> [[X]])1647; GFX6-IR-NEXT: [[SUB:%.*]] = fsub <2 x half> [[X]], [[FLOOR]]1648; GFX6-IR-NEXT: [[MIN:%.*]] = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> [[SUB]], <2 x half> splat (half 0xH3BFF))1649; GFX6-IR-NEXT: ret <2 x half> [[MIN]]1650;1651; GFX7-IR-LABEL: define <2 x half> @basic_fract_v2f16_nonan(1652; GFX7-IR-SAME: <2 x half> nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1653; GFX7-IR-NEXT: [[ENTRY:.*:]]1654; GFX7-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x half> @llvm.floor.v2f16(<2 x half> [[X]])1655; GFX7-IR-NEXT: [[SUB:%.*]] = fsub <2 x half> [[X]], [[FLOOR]]1656; GFX7-IR-NEXT: [[MIN:%.*]] = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> [[SUB]], <2 x half> splat (half 0xH3BFF))1657; GFX7-IR-NEXT: ret <2 x half> [[MIN]]1658;1659; IR-LEGALF16-LABEL: define <2 x half> @basic_fract_v2f16_nonan(1660; IR-LEGALF16-SAME: <2 x half> nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1661; IR-LEGALF16-NEXT: [[ENTRY:.*:]]1662; IR-LEGALF16-NEXT: [[TMP0:%.*]] = extractelement <2 x half> [[X]], i64 01663; IR-LEGALF16-NEXT: [[TMP1:%.*]] = extractelement <2 x half> [[X]], i64 11664; IR-LEGALF16-NEXT: [[TMP2:%.*]] = call nnan half @llvm.amdgcn.fract.f16(half [[TMP0]])1665; IR-LEGALF16-NEXT: [[TMP3:%.*]] = call nnan half @llvm.amdgcn.fract.f16(half [[TMP1]])1666; IR-LEGALF16-NEXT: [[TMP4:%.*]] = insertelement <2 x half> poison, half [[TMP2]], i64 01667; IR-LEGALF16-NEXT: [[MIN:%.*]] = insertelement <2 x half> [[TMP4]], half [[TMP3]], i64 11668; IR-LEGALF16-NEXT: ret <2 x half> [[MIN]]1669;1670; GFX6-LABEL: basic_fract_v2f16_nonan:1671; GFX6: ; %bb.0: ; %entry1672; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1673; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v01674; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v11675; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v01676; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v11677; GFX6-NEXT: v_floor_f32_e32 v2, v01678; GFX6-NEXT: v_floor_f32_e32 v3, v11679; GFX6-NEXT: v_sub_f32_e32 v1, v1, v31680; GFX6-NEXT: v_sub_f32_e32 v0, v0, v21681; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fe000, v01682; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fe000, v11683; GFX6-NEXT: s_setpc_b64 s[30:31]1684;1685; GFX7-LABEL: basic_fract_v2f16_nonan:1686; GFX7: ; %bb.0: ; %entry1687; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1688; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v01689; GFX7-NEXT: v_cvt_f16_f32_e32 v1, v11690; GFX7-NEXT: v_cvt_f32_f16_e32 v0, v01691; GFX7-NEXT: v_cvt_f32_f16_e32 v1, v11692; GFX7-NEXT: v_floor_f32_e32 v2, v01693; GFX7-NEXT: v_floor_f32_e32 v3, v11694; GFX7-NEXT: v_sub_f32_e32 v1, v1, v31695; GFX7-NEXT: v_sub_f32_e32 v0, v0, v21696; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fe000, v01697; GFX7-NEXT: v_min_f32_e32 v1, 0x3f7fe000, v11698; GFX7-NEXT: s_setpc_b64 s[30:31]1699;1700; GFX8-LABEL: basic_fract_v2f16_nonan:1701; GFX8: ; %bb.0: ; %entry1702; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1703; GFX8-NEXT: v_fract_f16_e32 v1, v01704; GFX8-NEXT: v_fract_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_11705; GFX8-NEXT: v_pack_b32_f16 v0, v1, v01706; GFX8-NEXT: s_setpc_b64 s[30:31]1707;1708; GFX11-TRUE16-LABEL: basic_fract_v2f16_nonan:1709; GFX11-TRUE16: ; %bb.0: ; %entry1710; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1711; GFX11-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1712; GFX11-TRUE16-NEXT: v_fract_f16_e32 v0.h, v0.h1713; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)1714; GFX11-TRUE16-NEXT: v_pack_b32_f16 v0, v0.l, v0.h1715; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]1716;1717; GFX11-FAKE16-LABEL: basic_fract_v2f16_nonan:1718; GFX11-FAKE16: ; %bb.0: ; %entry1719; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1720; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v1, 16, v01721; GFX11-FAKE16-NEXT: v_fract_f16_e32 v0, v01722; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)1723; GFX11-FAKE16-NEXT: v_fract_f16_e32 v1, v11724; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v11725; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]1726;1727; GFX12-TRUE16-LABEL: basic_fract_v2f16_nonan:1728; GFX12-TRUE16: ; %bb.0: ; %entry1729; GFX12-TRUE16-NEXT: s_wait_loadcnt_dscnt 0x01730; GFX12-TRUE16-NEXT: s_wait_expcnt 0x01731; GFX12-TRUE16-NEXT: s_wait_samplecnt 0x01732; GFX12-TRUE16-NEXT: s_wait_bvhcnt 0x01733; GFX12-TRUE16-NEXT: s_wait_kmcnt 0x01734; GFX12-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1735; GFX12-TRUE16-NEXT: v_fract_f16_e32 v0.h, v0.h1736; GFX12-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)1737; GFX12-TRUE16-NEXT: v_pack_b32_f16 v0, v0.l, v0.h1738; GFX12-TRUE16-NEXT: s_setpc_b64 s[30:31]1739;1740; GFX12-FAKE16-LABEL: basic_fract_v2f16_nonan:1741; GFX12-FAKE16: ; %bb.0: ; %entry1742; GFX12-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x01743; GFX12-FAKE16-NEXT: s_wait_expcnt 0x01744; GFX12-FAKE16-NEXT: s_wait_samplecnt 0x01745; GFX12-FAKE16-NEXT: s_wait_bvhcnt 0x01746; GFX12-FAKE16-NEXT: s_wait_kmcnt 0x01747; GFX12-FAKE16-NEXT: v_lshrrev_b32_e32 v1, 16, v01748; GFX12-FAKE16-NEXT: v_fract_f16_e32 v0, v01749; GFX12-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)1750; GFX12-FAKE16-NEXT: v_fract_f16_e32 v1, v11751; GFX12-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v11752; GFX12-FAKE16-NEXT: s_setpc_b64 s[30:31]1753entry:1754 %floor = tail call <2 x half> @llvm.floor.v2f16(<2 x half> %x)1755 %sub = fsub <2 x half> %x, %floor1756 %min = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> %sub, <2 x half> <half 0xH3BFF, half 0xH3BFF>)1757 ret <2 x half> %min1758}1759 1760define double @basic_fract_f64_nanans(double nofpclass(nan) %x) {1761; GFX6-IR-LABEL: define double @basic_fract_f64_nanans(1762; GFX6-IR-SAME: double nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1763; GFX6-IR-NEXT: [[ENTRY:.*:]]1764; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call double @llvm.floor.f64(double [[X]])1765; GFX6-IR-NEXT: [[SUB:%.*]] = fsub double [[X]], [[FLOOR]]1766; GFX6-IR-NEXT: [[MIN:%.*]] = tail call double @llvm.minnum.f64(double [[SUB]], double 0x3FEFFFFFFFFFFFFF)1767; GFX6-IR-NEXT: ret double [[MIN]]1768;1769; IR-FRACT-LABEL: define double @basic_fract_f64_nanans(1770; IR-FRACT-SAME: double nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {1771; IR-FRACT-NEXT: [[ENTRY:.*:]]1772; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan double @llvm.amdgcn.fract.f64(double [[X]])1773; IR-FRACT-NEXT: ret double [[MIN]]1774;1775; GFX6-LABEL: basic_fract_f64_nanans:1776; GFX6: ; %bb.0: ; %entry1777; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1778; GFX6-NEXT: v_fract_f64_e32 v[2:3], v[0:1]1779; GFX6-NEXT: v_mov_b32_e32 v4, -11780; GFX6-NEXT: v_mov_b32_e32 v5, 0x3fefffff1781; GFX6-NEXT: v_min_f64 v[2:3], v[2:3], v[4:5]1782; GFX6-NEXT: v_cmp_class_f64_e64 vcc, v[0:1], 31783; GFX6-NEXT: s_mov_b32 s4, -11784; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v0, vcc1785; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v1, vcc1786; GFX6-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]1787; GFX6-NEXT: s_mov_b32 s5, 0x3fefffff1788; GFX6-NEXT: v_add_f64 v[0:1], v[0:1], -v[2:3]1789; GFX6-NEXT: v_min_f64 v[0:1], v[0:1], s[4:5]1790; GFX6-NEXT: s_setpc_b64 s[30:31]1791;1792; GFX7-LABEL: basic_fract_f64_nanans:1793; GFX7: ; %bb.0: ; %entry1794; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1795; GFX7-NEXT: v_fract_f64_e32 v[0:1], v[0:1]1796; GFX7-NEXT: s_setpc_b64 s[30:31]1797;1798; GFX8-LABEL: basic_fract_f64_nanans:1799; GFX8: ; %bb.0: ; %entry1800; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1801; GFX8-NEXT: v_fract_f64_e32 v[0:1], v[0:1]1802; GFX8-NEXT: s_setpc_b64 s[30:31]1803;1804; GFX11-LABEL: basic_fract_f64_nanans:1805; GFX11: ; %bb.0: ; %entry1806; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1807; GFX11-NEXT: v_fract_f64_e32 v[0:1], v[0:1]1808; GFX11-NEXT: s_setpc_b64 s[30:31]1809;1810; GFX12-LABEL: basic_fract_f64_nanans:1811; GFX12: ; %bb.0: ; %entry1812; GFX12-NEXT: s_wait_loadcnt_dscnt 0x01813; GFX12-NEXT: s_wait_expcnt 0x01814; GFX12-NEXT: s_wait_samplecnt 0x01815; GFX12-NEXT: s_wait_bvhcnt 0x01816; GFX12-NEXT: s_wait_kmcnt 0x01817; GFX12-NEXT: v_fract_f64_e32 v[0:1], v[0:1]1818; GFX12-NEXT: s_setpc_b64 s[30:31]1819entry:1820 %floor = tail call double @llvm.floor.f64(double %x)1821 %sub = fsub double %x, %floor1822 %min = tail call double @llvm.minnum.f64(double %sub, double 0x3FEFFFFFFFFFFFFF)1823 ret double %min1824}1825 1826define half @safe_math_fract_f16_noinf_check(half %x, ptr addrspace(1) writeonly captures(none) %ip) {1827; GFX6-IR-LABEL: define half @safe_math_fract_f16_noinf_check(1828; GFX6-IR-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {1829; GFX6-IR-NEXT: [[ENTRY:.*:]]1830; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])1831; GFX6-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]1832; GFX6-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)1833; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], 0xH00001834; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], half [[X]], half [[MIN]]1835; GFX6-IR-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 41836; GFX6-IR-NEXT: ret half [[COND]]1837;1838; GFX7-IR-LABEL: define half @safe_math_fract_f16_noinf_check(1839; GFX7-IR-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {1840; GFX7-IR-NEXT: [[ENTRY:.*:]]1841; GFX7-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])1842; GFX7-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]1843; GFX7-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)1844; GFX7-IR-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], 0xH00001845; GFX7-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], half [[X]], half [[MIN]]1846; GFX7-IR-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 41847; GFX7-IR-NEXT: ret half [[COND]]1848;1849; IR-LEGALF16-LABEL: define half @safe_math_fract_f16_noinf_check(1850; IR-LEGALF16-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {1851; IR-LEGALF16-NEXT: [[ENTRY:.*:]]1852; IR-LEGALF16-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])1853; IR-LEGALF16-NEXT: [[COND:%.*]] = call half @llvm.amdgcn.fract.f16(half [[X]])1854; IR-LEGALF16-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 41855; IR-LEGALF16-NEXT: ret half [[COND]]1856;1857; GFX6-LABEL: safe_math_fract_f16_noinf_check:1858; GFX6: ; %bb.0: ; %entry1859; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1860; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v01861; GFX6-NEXT: s_mov_b32 s6, 01862; GFX6-NEXT: s_mov_b32 s7, 0xf0001863; GFX6-NEXT: s_mov_b32 s4, s61864; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v01865; GFX6-NEXT: s_mov_b32 s5, s61866; GFX6-NEXT: v_floor_f32_e32 v3, v01867; GFX6-NEXT: v_sub_f32_e32 v4, v0, v31868; GFX6-NEXT: v_cvt_f16_f32_e32 v3, v31869; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fe000, v41870; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v01871; GFX6-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc1872; GFX6-NEXT: buffer_store_short v3, v[1:2], s[4:7], 0 addr641873; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)1874; GFX6-NEXT: s_setpc_b64 s[30:31]1875;1876; GFX7-LABEL: safe_math_fract_f16_noinf_check:1877; GFX7: ; %bb.0: ; %entry1878; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1879; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v01880; GFX7-NEXT: s_mov_b32 s6, 01881; GFX7-NEXT: s_mov_b32 s7, 0xf0001882; GFX7-NEXT: s_mov_b32 s4, s61883; GFX7-NEXT: v_cvt_f32_f16_e32 v0, v01884; GFX7-NEXT: s_mov_b32 s5, s61885; GFX7-NEXT: v_floor_f32_e32 v3, v01886; GFX7-NEXT: v_sub_f32_e32 v4, v0, v31887; GFX7-NEXT: v_cvt_f16_f32_e32 v3, v31888; GFX7-NEXT: v_min_f32_e32 v4, 0x3f7fe000, v41889; GFX7-NEXT: v_cmp_u_f32_e32 vcc, v0, v01890; GFX7-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc1891; GFX7-NEXT: buffer_store_short v3, v[1:2], s[4:7], 0 addr641892; GFX7-NEXT: s_waitcnt vmcnt(0)1893; GFX7-NEXT: s_setpc_b64 s[30:31]1894;1895; GFX8-LABEL: safe_math_fract_f16_noinf_check:1896; GFX8: ; %bb.0: ; %entry1897; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1898; GFX8-NEXT: v_floor_f16_e32 v3, v01899; GFX8-NEXT: v_fract_f16_e32 v0, v01900; GFX8-NEXT: global_store_short v[1:2], v3, off1901; GFX8-NEXT: s_waitcnt vmcnt(0)1902; GFX8-NEXT: s_setpc_b64 s[30:31]1903;1904; GFX11-TRUE16-LABEL: safe_math_fract_f16_noinf_check:1905; GFX11-TRUE16: ; %bb.0: ; %entry1906; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1907; GFX11-TRUE16-NEXT: v_floor_f16_e32 v0.h, v0.l1908; GFX11-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1909; GFX11-TRUE16-NEXT: global_store_d16_hi_b16 v[1:2], v0, off1910; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]1911;1912; GFX11-FAKE16-LABEL: safe_math_fract_f16_noinf_check:1913; GFX11-FAKE16: ; %bb.0: ; %entry1914; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1915; GFX11-FAKE16-NEXT: v_floor_f16_e32 v3, v01916; GFX11-FAKE16-NEXT: v_fract_f16_e32 v0, v01917; GFX11-FAKE16-NEXT: global_store_b16 v[1:2], v3, off1918; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]1919;1920; GFX12-TRUE16-LABEL: safe_math_fract_f16_noinf_check:1921; GFX12-TRUE16: ; %bb.0: ; %entry1922; GFX12-TRUE16-NEXT: s_wait_loadcnt_dscnt 0x01923; GFX12-TRUE16-NEXT: s_wait_expcnt 0x01924; GFX12-TRUE16-NEXT: s_wait_samplecnt 0x01925; GFX12-TRUE16-NEXT: s_wait_bvhcnt 0x01926; GFX12-TRUE16-NEXT: s_wait_kmcnt 0x01927; GFX12-TRUE16-NEXT: v_floor_f16_e32 v0.h, v0.l1928; GFX12-TRUE16-NEXT: v_fract_f16_e32 v0.l, v0.l1929; GFX12-TRUE16-NEXT: global_store_d16_hi_b16 v[1:2], v0, off1930; GFX12-TRUE16-NEXT: s_setpc_b64 s[30:31]1931;1932; GFX12-FAKE16-LABEL: safe_math_fract_f16_noinf_check:1933; GFX12-FAKE16: ; %bb.0: ; %entry1934; GFX12-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x01935; GFX12-FAKE16-NEXT: s_wait_expcnt 0x01936; GFX12-FAKE16-NEXT: s_wait_samplecnt 0x01937; GFX12-FAKE16-NEXT: s_wait_bvhcnt 0x01938; GFX12-FAKE16-NEXT: s_wait_kmcnt 0x01939; GFX12-FAKE16-NEXT: v_floor_f16_e32 v3, v01940; GFX12-FAKE16-NEXT: v_fract_f16_e32 v0, v01941; GFX12-FAKE16-NEXT: global_store_b16 v[1:2], v3, off1942; GFX12-FAKE16-NEXT: s_setpc_b64 s[30:31]1943entry:1944 %floor = tail call half @llvm.floor.f16(half %x)1945 %sub = fsub half %x, %floor1946 %min = tail call half @llvm.minnum.f16(half %sub, half 0xH3BFF)1947 %uno = fcmp uno half %x, 0.000000e+001948 %cond = select i1 %uno, half %x, half %min1949 store half %floor, ptr addrspace(1) %ip, align 41950 ret half %cond1951}1952 1953define double @safe_math_fract_f64_noinf_check(double %x, ptr addrspace(1) writeonly captures(none) %ip) {1954; GFX6-IR-LABEL: define double @safe_math_fract_f64_noinf_check(1955; GFX6-IR-SAME: double [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {1956; GFX6-IR-NEXT: [[ENTRY:.*:]]1957; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call double @llvm.floor.f64(double [[X]])1958; GFX6-IR-NEXT: [[SUB:%.*]] = fsub double [[X]], [[FLOOR]]1959; GFX6-IR-NEXT: [[MIN:%.*]] = tail call double @llvm.minnum.f64(double [[SUB]], double 0x3FEFFFFFFFFFFFFF)1960; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno double [[X]], 0.000000e+001961; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], double [[X]], double [[MIN]]1962; GFX6-IR-NEXT: store double [[FLOOR]], ptr addrspace(1) [[IP]], align 41963; GFX6-IR-NEXT: ret double [[COND]]1964;1965; IR-FRACT-LABEL: define double @safe_math_fract_f64_noinf_check(1966; IR-FRACT-SAME: double [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {1967; IR-FRACT-NEXT: [[ENTRY:.*:]]1968; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call double @llvm.floor.f64(double [[X]])1969; IR-FRACT-NEXT: [[COND:%.*]] = call double @llvm.amdgcn.fract.f64(double [[X]])1970; IR-FRACT-NEXT: store double [[FLOOR]], ptr addrspace(1) [[IP]], align 41971; IR-FRACT-NEXT: ret double [[COND]]1972;1973; GFX6-LABEL: safe_math_fract_f64_noinf_check:1974; GFX6: ; %bb.0: ; %entry1975; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)1976; GFX6-NEXT: v_fract_f64_e32 v[4:5], v[0:1]1977; GFX6-NEXT: v_mov_b32_e32 v6, -11978; GFX6-NEXT: v_mov_b32_e32 v7, 0x3fefffff1979; GFX6-NEXT: v_min_f64 v[4:5], v[4:5], v[6:7]1980; GFX6-NEXT: v_cmp_class_f64_e64 vcc, v[0:1], 31981; GFX6-NEXT: s_mov_b32 s8, -11982; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v0, vcc1983; GFX6-NEXT: v_cndmask_b32_e32 v5, v5, v1, vcc1984; GFX6-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]1985; GFX6-NEXT: s_mov_b32 s9, 0x3fefffff1986; GFX6-NEXT: v_add_f64 v[6:7], v[0:1], -v[4:5]1987; GFX6-NEXT: v_cmp_u_f64_e32 vcc, v[0:1], v[0:1]1988; GFX6-NEXT: v_min_f64 v[6:7], v[6:7], s[8:9]1989; GFX6-NEXT: s_mov_b32 s6, 01990; GFX6-NEXT: s_mov_b32 s7, 0xf0001991; GFX6-NEXT: s_mov_b32 s4, s61992; GFX6-NEXT: s_mov_b32 s5, s61993; GFX6-NEXT: v_cndmask_b32_e32 v0, v6, v0, vcc1994; GFX6-NEXT: v_cndmask_b32_e32 v1, v7, v1, vcc1995; GFX6-NEXT: buffer_store_dwordx2 v[4:5], v[2:3], s[4:7], 0 addr641996; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)1997; GFX6-NEXT: s_setpc_b64 s[30:31]1998;1999; GFX7-LABEL: safe_math_fract_f64_noinf_check:2000; GFX7: ; %bb.0: ; %entry2001; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2002; GFX7-NEXT: v_floor_f64_e32 v[4:5], v[0:1]2003; GFX7-NEXT: v_fract_f64_e32 v[0:1], v[0:1]2004; GFX7-NEXT: s_mov_b32 s6, 02005; GFX7-NEXT: s_mov_b32 s7, 0xf0002006; GFX7-NEXT: s_mov_b32 s4, s62007; GFX7-NEXT: s_mov_b32 s5, s62008; GFX7-NEXT: buffer_store_dwordx2 v[4:5], v[2:3], s[4:7], 0 addr642009; GFX7-NEXT: s_waitcnt vmcnt(0)2010; GFX7-NEXT: s_setpc_b64 s[30:31]2011;2012; GFX8-LABEL: safe_math_fract_f64_noinf_check:2013; GFX8: ; %bb.0: ; %entry2014; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2015; GFX8-NEXT: v_floor_f64_e32 v[4:5], v[0:1]2016; GFX8-NEXT: v_fract_f64_e32 v[0:1], v[0:1]2017; GFX8-NEXT: global_store_dwordx2 v[2:3], v[4:5], off2018; GFX8-NEXT: s_waitcnt vmcnt(0)2019; GFX8-NEXT: s_setpc_b64 s[30:31]2020;2021; GFX11-LABEL: safe_math_fract_f64_noinf_check:2022; GFX11: ; %bb.0: ; %entry2023; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2024; GFX11-NEXT: v_floor_f64_e32 v[4:5], v[0:1]2025; GFX11-NEXT: v_fract_f64_e32 v[0:1], v[0:1]2026; GFX11-NEXT: global_store_b64 v[2:3], v[4:5], off2027; GFX11-NEXT: s_setpc_b64 s[30:31]2028;2029; GFX12-LABEL: safe_math_fract_f64_noinf_check:2030; GFX12: ; %bb.0: ; %entry2031; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02032; GFX12-NEXT: s_wait_expcnt 0x02033; GFX12-NEXT: s_wait_samplecnt 0x02034; GFX12-NEXT: s_wait_bvhcnt 0x02035; GFX12-NEXT: s_wait_kmcnt 0x02036; GFX12-NEXT: v_floor_f64_e32 v[4:5], v[0:1]2037; GFX12-NEXT: v_fract_f64_e32 v[0:1], v[0:1]2038; GFX12-NEXT: global_store_b64 v[2:3], v[4:5], off2039; GFX12-NEXT: s_setpc_b64 s[30:31]2040entry:2041 %floor = tail call double @llvm.floor.f64(double %x)2042 %sub = fsub double %x, %floor2043 %min = tail call double @llvm.minnum.f64(double %sub, double 0x3FEFFFFFFFFFFFFF)2044 %uno = fcmp uno double %x, 0.000000e+002045 %cond = select i1 %uno, double %x, double %min2046 store double %floor, ptr addrspace(1) %ip, align 42047 ret double %cond2048}2049 2050define float @select_nan_fract_f32_flags_select(float %x) {2051; GFX6-IR-LABEL: define float @select_nan_fract_f32_flags_select(2052; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {2053; GFX6-IR-NEXT: [[ENTRY:.*:]]2054; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])2055; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]2056; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)2057; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+002058; GFX6-IR-NEXT: [[COND:%.*]] = select nsz i1 [[UNO]], float [[X]], float [[MIN]]2059; GFX6-IR-NEXT: ret float [[COND]]2060;2061; IR-FRACT-LABEL: define float @select_nan_fract_f32_flags_select(2062; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {2063; IR-FRACT-NEXT: [[ENTRY:.*:]]2064; IR-FRACT-NEXT: [[COND:%.*]] = call nsz float @llvm.amdgcn.fract.f32(float [[X]])2065; IR-FRACT-NEXT: ret float [[COND]]2066;2067; GFX6-LABEL: select_nan_fract_f32_flags_select:2068; GFX6: ; %bb.0: ; %entry2069; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2070; GFX6-NEXT: v_floor_f32_e32 v1, v02071; GFX6-NEXT: v_sub_f32_e32 v1, v0, v12072; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v12073; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v02074; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc2075; GFX6-NEXT: s_setpc_b64 s[30:31]2076;2077; GFX7-LABEL: select_nan_fract_f32_flags_select:2078; GFX7: ; %bb.0: ; %entry2079; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2080; GFX7-NEXT: v_fract_f32_e32 v0, v02081; GFX7-NEXT: s_setpc_b64 s[30:31]2082;2083; GFX8-LABEL: select_nan_fract_f32_flags_select:2084; GFX8: ; %bb.0: ; %entry2085; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2086; GFX8-NEXT: v_fract_f32_e32 v0, v02087; GFX8-NEXT: s_setpc_b64 s[30:31]2088;2089; GFX11-LABEL: select_nan_fract_f32_flags_select:2090; GFX11: ; %bb.0: ; %entry2091; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2092; GFX11-NEXT: v_fract_f32_e32 v0, v02093; GFX11-NEXT: s_setpc_b64 s[30:31]2094;2095; GFX12-LABEL: select_nan_fract_f32_flags_select:2096; GFX12: ; %bb.0: ; %entry2097; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02098; GFX12-NEXT: s_wait_expcnt 0x02099; GFX12-NEXT: s_wait_samplecnt 0x02100; GFX12-NEXT: s_wait_bvhcnt 0x02101; GFX12-NEXT: s_wait_kmcnt 0x02102; GFX12-NEXT: v_fract_f32_e32 v0, v02103; GFX12-NEXT: s_setpc_b64 s[30:31]2104entry:2105 %floor = tail call float @llvm.floor.f32(float %x)2106 %sub = fsub float %x, %floor2107 %min = tail call float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)2108 %uno = fcmp uno float %x, 0.000000e+002109 %cond = select nsz i1 %uno, float %x, float %min2110 ret float %cond2111}2112 2113define float @select_nan_fract_f32_flags_minnum(float %x) {2114; GFX6-IR-LABEL: define float @select_nan_fract_f32_flags_minnum(2115; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {2116; GFX6-IR-NEXT: [[ENTRY:.*:]]2117; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])2118; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]2119; GFX6-IR-NEXT: [[MIN:%.*]] = tail call nsz float @llvm.minnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)2120; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+002121; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]2122; GFX6-IR-NEXT: ret float [[COND]]2123;2124; IR-FRACT-LABEL: define float @select_nan_fract_f32_flags_minnum(2125; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {2126; IR-FRACT-NEXT: [[ENTRY:.*:]]2127; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])2128; IR-FRACT-NEXT: ret float [[COND]]2129;2130; GFX6-LABEL: select_nan_fract_f32_flags_minnum:2131; GFX6: ; %bb.0: ; %entry2132; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2133; GFX6-NEXT: v_floor_f32_e32 v1, v02134; GFX6-NEXT: v_sub_f32_e32 v1, v0, v12135; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v12136; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v02137; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc2138; GFX6-NEXT: s_setpc_b64 s[30:31]2139;2140; GFX7-LABEL: select_nan_fract_f32_flags_minnum:2141; GFX7: ; %bb.0: ; %entry2142; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2143; GFX7-NEXT: v_fract_f32_e32 v0, v02144; GFX7-NEXT: s_setpc_b64 s[30:31]2145;2146; GFX8-LABEL: select_nan_fract_f32_flags_minnum:2147; GFX8: ; %bb.0: ; %entry2148; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2149; GFX8-NEXT: v_fract_f32_e32 v0, v02150; GFX8-NEXT: s_setpc_b64 s[30:31]2151;2152; GFX11-LABEL: select_nan_fract_f32_flags_minnum:2153; GFX11: ; %bb.0: ; %entry2154; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2155; GFX11-NEXT: v_fract_f32_e32 v0, v02156; GFX11-NEXT: s_setpc_b64 s[30:31]2157;2158; GFX12-LABEL: select_nan_fract_f32_flags_minnum:2159; GFX12: ; %bb.0: ; %entry2160; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02161; GFX12-NEXT: s_wait_expcnt 0x02162; GFX12-NEXT: s_wait_samplecnt 0x02163; GFX12-NEXT: s_wait_bvhcnt 0x02164; GFX12-NEXT: s_wait_kmcnt 0x02165; GFX12-NEXT: v_fract_f32_e32 v0, v02166; GFX12-NEXT: s_setpc_b64 s[30:31]2167entry:2168 %floor = tail call float @llvm.floor.f32(float %x)2169 %sub = fsub float %x, %floor2170 %min = tail call nsz float @llvm.minnum.f32(float %sub, float 0x3FEFFFFFE0000000)2171 %uno = fcmp uno float %x, 0.000000e+002172 %cond = select i1 %uno, float %x, float %min2173 ret float %cond2174}2175 2176define <2 x float> @safe_math_fract_v2f32(<2 x float> %x, ptr addrspace(1) writeonly captures(none) %ip) {2177; GFX6-IR-LABEL: define <2 x float> @safe_math_fract_v2f32(2178; GFX6-IR-SAME: <2 x float> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2179; GFX6-IR-NEXT: [[ENTRY:.*:]]2180; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x float> @llvm.floor.v2f32(<2 x float> [[X]])2181; GFX6-IR-NEXT: [[SUB:%.*]] = fsub <2 x float> [[X]], [[FLOOR]]2182; GFX6-IR-NEXT: [[MIN:%.*]] = tail call <2 x float> @llvm.minnum.v2f32(<2 x float> [[SUB]], <2 x float> splat (float 0x3FEFFFFFE0000000))2183; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno <2 x float> [[X]], zeroinitializer2184; GFX6-IR-NEXT: [[COND:%.*]] = select <2 x i1> [[UNO]], <2 x float> [[X]], <2 x float> [[MIN]]2185; GFX6-IR-NEXT: [[FABS:%.*]] = tail call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])2186; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x float> [[FABS]], splat (float 0x7FF0000000000000)2187; GFX6-IR-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x float> zeroinitializer, <2 x float> [[COND]]2188; GFX6-IR-NEXT: store <2 x float> [[FLOOR]], ptr addrspace(1) [[IP]], align 42189; GFX6-IR-NEXT: ret <2 x float> [[COND6]]2190;2191; IR-FRACT-LABEL: define <2 x float> @safe_math_fract_v2f32(2192; IR-FRACT-SAME: <2 x float> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2193; IR-FRACT-NEXT: [[ENTRY:.*:]]2194; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call <2 x float> @llvm.floor.v2f32(<2 x float> [[X]])2195; IR-FRACT-NEXT: [[TMP0:%.*]] = extractelement <2 x float> [[X]], i64 02196; IR-FRACT-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[X]], i64 12197; IR-FRACT-NEXT: [[TMP2:%.*]] = call float @llvm.amdgcn.fract.f32(float [[TMP0]])2198; IR-FRACT-NEXT: [[TMP3:%.*]] = call float @llvm.amdgcn.fract.f32(float [[TMP1]])2199; IR-FRACT-NEXT: [[TMP4:%.*]] = insertelement <2 x float> poison, float [[TMP2]], i64 02200; IR-FRACT-NEXT: [[COND:%.*]] = insertelement <2 x float> [[TMP4]], float [[TMP3]], i64 12201; IR-FRACT-NEXT: [[FABS:%.*]] = tail call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]])2202; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x float> [[FABS]], splat (float 0x7FF0000000000000)2203; IR-FRACT-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x float> zeroinitializer, <2 x float> [[COND]]2204; IR-FRACT-NEXT: store <2 x float> [[FLOOR]], ptr addrspace(1) [[IP]], align 42205; IR-FRACT-NEXT: ret <2 x float> [[COND6]]2206;2207; GFX6-LABEL: safe_math_fract_v2f32:2208; GFX6: ; %bb.0: ; %entry2209; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2210; GFX6-NEXT: v_floor_f32_e32 v5, v12211; GFX6-NEXT: v_floor_f32_e32 v4, v02212; GFX6-NEXT: v_sub_f32_e32 v6, v1, v52213; GFX6-NEXT: v_sub_f32_e32 v7, v0, v42214; GFX6-NEXT: v_min_f32_e32 v6, 0x3f7fffff, v62215; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v1, v12216; GFX6-NEXT: v_min_f32_e32 v7, 0x3f7fffff, v72217; GFX6-NEXT: v_cndmask_b32_e32 v6, v6, v1, vcc2218; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v02219; GFX6-NEXT: v_mov_b32_e32 v8, 0x2042220; GFX6-NEXT: v_cndmask_b32_e32 v7, v7, v0, vcc2221; GFX6-NEXT: v_cmp_class_f32_e32 vcc, v0, v82222; GFX6-NEXT: s_mov_b32 s6, 02223; GFX6-NEXT: v_cndmask_b32_e64 v0, v7, 0, vcc2224; GFX6-NEXT: v_cmp_class_f32_e32 vcc, v1, v82225; GFX6-NEXT: s_mov_b32 s7, 0xf0002226; GFX6-NEXT: s_mov_b32 s4, s62227; GFX6-NEXT: s_mov_b32 s5, s62228; GFX6-NEXT: v_cndmask_b32_e64 v1, v6, 0, vcc2229; GFX6-NEXT: buffer_store_dwordx2 v[4:5], v[2:3], s[4:7], 0 addr642230; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)2231; GFX6-NEXT: s_setpc_b64 s[30:31]2232;2233; GFX7-LABEL: safe_math_fract_v2f32:2234; GFX7: ; %bb.0: ; %entry2235; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2236; GFX7-NEXT: v_mov_b32_e32 v8, 0x2042237; GFX7-NEXT: v_fract_f32_e32 v6, v02238; GFX7-NEXT: v_cmp_class_f32_e32 vcc, v0, v82239; GFX7-NEXT: s_mov_b32 s6, 02240; GFX7-NEXT: v_floor_f32_e32 v4, v02241; GFX7-NEXT: v_fract_f32_e32 v7, v12242; GFX7-NEXT: v_cndmask_b32_e64 v0, v6, 0, vcc2243; GFX7-NEXT: v_cmp_class_f32_e32 vcc, v1, v82244; GFX7-NEXT: s_mov_b32 s7, 0xf0002245; GFX7-NEXT: s_mov_b32 s4, s62246; GFX7-NEXT: s_mov_b32 s5, s62247; GFX7-NEXT: v_floor_f32_e32 v5, v12248; GFX7-NEXT: v_cndmask_b32_e64 v1, v7, 0, vcc2249; GFX7-NEXT: buffer_store_dwordx2 v[4:5], v[2:3], s[4:7], 0 addr642250; GFX7-NEXT: s_waitcnt vmcnt(0)2251; GFX7-NEXT: s_setpc_b64 s[30:31]2252;2253; GFX8-LABEL: safe_math_fract_v2f32:2254; GFX8: ; %bb.0: ; %entry2255; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2256; GFX8-NEXT: v_mov_b32_e32 v8, 0x2042257; GFX8-NEXT: v_fract_f32_e32 v6, v02258; GFX8-NEXT: v_cmp_class_f32_e32 vcc, v0, v82259; GFX8-NEXT: v_floor_f32_e32 v4, v02260; GFX8-NEXT: v_fract_f32_e32 v7, v12261; GFX8-NEXT: v_cndmask_b32_e64 v0, v6, 0, vcc2262; GFX8-NEXT: v_cmp_class_f32_e32 vcc, v1, v82263; GFX8-NEXT: v_floor_f32_e32 v5, v12264; GFX8-NEXT: v_cndmask_b32_e64 v1, v7, 0, vcc2265; GFX8-NEXT: global_store_dwordx2 v[2:3], v[4:5], off2266; GFX8-NEXT: s_waitcnt vmcnt(0)2267; GFX8-NEXT: s_setpc_b64 s[30:31]2268;2269; GFX11-LABEL: safe_math_fract_v2f32:2270; GFX11: ; %bb.0: ; %entry2271; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2272; GFX11-NEXT: v_fract_f32_e32 v6, v02273; GFX11-NEXT: v_cmp_class_f32_e64 s0, v0, 0x2042274; GFX11-NEXT: v_fract_f32_e32 v7, v12275; GFX11-NEXT: v_floor_f32_e32 v4, v02276; GFX11-NEXT: v_floor_f32_e32 v5, v12277; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4)2278; GFX11-NEXT: v_cndmask_b32_e64 v0, v6, 0, s02279; GFX11-NEXT: v_cmp_class_f32_e64 s0, v1, 0x2042280; GFX11-NEXT: global_store_b64 v[2:3], v[4:5], off2281; GFX11-NEXT: v_cndmask_b32_e64 v1, v7, 0, s02282; GFX11-NEXT: s_setpc_b64 s[30:31]2283;2284; GFX12-LABEL: safe_math_fract_v2f32:2285; GFX12: ; %bb.0: ; %entry2286; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02287; GFX12-NEXT: s_wait_expcnt 0x02288; GFX12-NEXT: s_wait_samplecnt 0x02289; GFX12-NEXT: s_wait_bvhcnt 0x02290; GFX12-NEXT: s_wait_kmcnt 0x02291; GFX12-NEXT: v_fract_f32_e32 v6, v02292; GFX12-NEXT: v_cmp_class_f32_e64 s0, v0, 0x2042293; GFX12-NEXT: v_fract_f32_e32 v7, v12294; GFX12-NEXT: v_floor_f32_e32 v4, v02295; GFX12-NEXT: v_floor_f32_e32 v5, v12296; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)2297; GFX12-NEXT: v_cndmask_b32_e64 v0, v6, 0, s02298; GFX12-NEXT: v_cmp_class_f32_e64 s0, v1, 0x2042299; GFX12-NEXT: global_store_b64 v[2:3], v[4:5], off2300; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)2301; GFX12-NEXT: v_cndmask_b32_e64 v1, v7, 0, s02302; GFX12-NEXT: s_setpc_b64 s[30:31]2303entry:2304 %floor = tail call <2 x float> @llvm.floor.v2f32(<2 x float> %x)2305 %sub = fsub <2 x float> %x, %floor2306 %min = tail call <2 x float> @llvm.minnum.v2f32(<2 x float> %sub, <2 x float> <float 0x3FEFFFFFE0000000, float 0x3FEFFFFFE0000000>)2307 %uno = fcmp uno <2 x float> %x, zeroinitializer2308 %cond = select <2 x i1> %uno, <2 x float> %x, <2 x float> %min2309 %fabs = tail call <2 x float> @llvm.fabs.v2f32(<2 x float> %x)2310 %cmpinf = fcmp oeq <2 x float> %fabs, <float 0x7FF0000000000000, float 0x7FF0000000000000>2311 %cond6 = select <2 x i1> %cmpinf, <2 x float> zeroinitializer, <2 x float> %cond2312 store <2 x float> %floor, ptr addrspace(1) %ip, align 42313 ret <2 x float> %cond62314}2315 2316define double @safe_math_fract_f64(double %x, ptr addrspace(1) writeonly captures(none) %ip) {2317; GFX6-IR-LABEL: define double @safe_math_fract_f64(2318; GFX6-IR-SAME: double [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2319; GFX6-IR-NEXT: [[ENTRY:.*:]]2320; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call double @llvm.floor.f64(double [[X]])2321; GFX6-IR-NEXT: [[SUB:%.*]] = fsub double [[X]], [[FLOOR]]2322; GFX6-IR-NEXT: [[MIN:%.*]] = tail call double @llvm.minnum.f64(double [[SUB]], double 0x3FEFFFFFFFFFFFFF)2323; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno double [[X]], 0.000000e+002324; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], double [[X]], double [[MIN]]2325; GFX6-IR-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X]])2326; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq double [[FABS]], 0x7FF00000000000002327; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], double 0.000000e+00, double [[COND]]2328; GFX6-IR-NEXT: store double [[FLOOR]], ptr addrspace(1) [[IP]], align 42329; GFX6-IR-NEXT: ret double [[COND6]]2330;2331; IR-FRACT-LABEL: define double @safe_math_fract_f64(2332; IR-FRACT-SAME: double [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2333; IR-FRACT-NEXT: [[ENTRY:.*:]]2334; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call double @llvm.floor.f64(double [[X]])2335; IR-FRACT-NEXT: [[COND:%.*]] = call double @llvm.amdgcn.fract.f64(double [[X]])2336; IR-FRACT-NEXT: [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X]])2337; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq double [[FABS]], 0x7FF00000000000002338; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], double 0.000000e+00, double [[COND]]2339; IR-FRACT-NEXT: store double [[FLOOR]], ptr addrspace(1) [[IP]], align 42340; IR-FRACT-NEXT: ret double [[COND6]]2341;2342; GFX6-LABEL: safe_math_fract_f64:2343; GFX6: ; %bb.0: ; %entry2344; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2345; GFX6-NEXT: v_fract_f64_e32 v[4:5], v[0:1]2346; GFX6-NEXT: v_mov_b32_e32 v6, -12347; GFX6-NEXT: v_mov_b32_e32 v7, 0x3fefffff2348; GFX6-NEXT: v_min_f64 v[4:5], v[4:5], v[6:7]2349; GFX6-NEXT: v_cmp_class_f64_e64 vcc, v[0:1], 32350; GFX6-NEXT: s_mov_b32 s8, -12351; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v0, vcc2352; GFX6-NEXT: v_cndmask_b32_e32 v5, v5, v1, vcc2353; GFX6-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]2354; GFX6-NEXT: s_mov_b32 s9, 0x3fefffff2355; GFX6-NEXT: v_add_f64 v[6:7], v[0:1], -v[4:5]2356; GFX6-NEXT: v_cmp_u_f64_e32 vcc, v[0:1], v[0:1]2357; GFX6-NEXT: v_min_f64 v[6:7], v[6:7], s[8:9]2358; GFX6-NEXT: s_mov_b32 s8, 02359; GFX6-NEXT: s_mov_b32 s9, 0x7ff000002360; GFX6-NEXT: v_cndmask_b32_e32 v7, v7, v1, vcc2361; GFX6-NEXT: v_cndmask_b32_e32 v6, v6, v0, vcc2362; GFX6-NEXT: v_cmp_neq_f64_e64 vcc, |v[0:1]|, s[8:9]2363; GFX6-NEXT: s_mov_b32 s6, 02364; GFX6-NEXT: s_mov_b32 s7, 0xf0002365; GFX6-NEXT: s_mov_b32 s4, s62366; GFX6-NEXT: s_mov_b32 s5, s62367; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v6, vcc2368; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v7, vcc2369; GFX6-NEXT: buffer_store_dwordx2 v[4:5], v[2:3], s[4:7], 0 addr642370; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)2371; GFX6-NEXT: s_setpc_b64 s[30:31]2372;2373; GFX7-LABEL: safe_math_fract_f64:2374; GFX7: ; %bb.0: ; %entry2375; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2376; GFX7-NEXT: s_mov_b32 s4, 02377; GFX7-NEXT: s_mov_b32 s5, 0x7ff000002378; GFX7-NEXT: v_fract_f64_e32 v[4:5], v[0:1]2379; GFX7-NEXT: v_cmp_neq_f64_e64 vcc, |v[0:1]|, s[4:5]2380; GFX7-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2381; GFX7-NEXT: s_mov_b32 s6, 02382; GFX7-NEXT: s_mov_b32 s7, 0xf0002383; GFX7-NEXT: s_mov_b32 s4, s62384; GFX7-NEXT: s_mov_b32 s5, s62385; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc2386; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v5, vcc2387; GFX7-NEXT: buffer_store_dwordx2 v[6:7], v[2:3], s[4:7], 0 addr642388; GFX7-NEXT: s_waitcnt vmcnt(0)2389; GFX7-NEXT: s_setpc_b64 s[30:31]2390;2391; GFX8-LABEL: safe_math_fract_f64:2392; GFX8: ; %bb.0: ; %entry2393; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2394; GFX8-NEXT: s_mov_b32 s4, 02395; GFX8-NEXT: s_mov_b32 s5, 0x7ff000002396; GFX8-NEXT: v_fract_f64_e32 v[4:5], v[0:1]2397; GFX8-NEXT: v_cmp_neq_f64_e64 vcc, |v[0:1]|, s[4:5]2398; GFX8-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2399; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc2400; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v5, vcc2401; GFX8-NEXT: global_store_dwordx2 v[2:3], v[6:7], off2402; GFX8-NEXT: s_waitcnt vmcnt(0)2403; GFX8-NEXT: s_setpc_b64 s[30:31]2404;2405; GFX11-LABEL: safe_math_fract_f64:2406; GFX11: ; %bb.0: ; %entry2407; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2408; GFX11-NEXT: v_fract_f64_e32 v[4:5], v[0:1]2409; GFX11-NEXT: v_cmp_neq_f64_e64 vcc_lo, 0x7ff00000, |v[0:1]|2410; GFX11-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2411; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)2412; GFX11-NEXT: v_dual_cndmask_b32 v0, 0, v4 :: v_dual_cndmask_b32 v1, 0, v52413; GFX11-NEXT: global_store_b64 v[2:3], v[6:7], off2414; GFX11-NEXT: s_setpc_b64 s[30:31]2415;2416; GFX12-LABEL: safe_math_fract_f64:2417; GFX12: ; %bb.0: ; %entry2418; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02419; GFX12-NEXT: s_wait_expcnt 0x02420; GFX12-NEXT: s_wait_samplecnt 0x02421; GFX12-NEXT: s_wait_bvhcnt 0x02422; GFX12-NEXT: s_wait_kmcnt 0x02423; GFX12-NEXT: v_fract_f64_e32 v[4:5], v[0:1]2424; GFX12-NEXT: v_cmp_neq_f64_e64 vcc_lo, 0x7ff00000, |v[0:1]|2425; GFX12-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2426; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)2427; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)2428; GFX12-NEXT: v_dual_cndmask_b32 v0, 0, v4 :: v_dual_cndmask_b32 v1, 0, v52429; GFX12-NEXT: global_store_b64 v[2:3], v[6:7], off2430; GFX12-NEXT: s_setpc_b64 s[30:31]2431entry:2432 %floor = tail call double @llvm.floor.f64(double %x)2433 %sub = fsub double %x, %floor2434 %min = tail call double @llvm.minnum.f64(double %sub, double 0x3FEFFFFFFFFFFFFF)2435 %uno = fcmp uno double %x, 0.000000e+002436 %cond = select i1 %uno, double %x, double %min2437 %fabs = tail call double @llvm.fabs.f64(double %x)2438 %cmpinf = fcmp oeq double %fabs, 0x7FF00000000000002439 %cond6 = select i1 %cmpinf, double 0.000000e+00, double %cond2440 store double %floor, ptr addrspace(1) %ip, align 42441 ret double %cond62442}2443 2444define half @safe_math_fract_f16(half %x, ptr addrspace(1) writeonly captures(none) %ip) {2445; GFX6-IR-LABEL: define half @safe_math_fract_f16(2446; GFX6-IR-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2447; GFX6-IR-NEXT: [[ENTRY:.*:]]2448; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])2449; GFX6-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]2450; GFX6-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)2451; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], 0xH00002452; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], half [[X]], half [[MIN]]2453; GFX6-IR-NEXT: [[FABS:%.*]] = tail call half @llvm.fabs.f16(half [[X]])2454; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C002455; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], half 0xH0000, half [[COND]]2456; GFX6-IR-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 42457; GFX6-IR-NEXT: ret half [[COND6]]2458;2459; GFX7-IR-LABEL: define half @safe_math_fract_f16(2460; GFX7-IR-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2461; GFX7-IR-NEXT: [[ENTRY:.*:]]2462; GFX7-IR-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])2463; GFX7-IR-NEXT: [[SUB:%.*]] = fsub half [[X]], [[FLOOR]]2464; GFX7-IR-NEXT: [[MIN:%.*]] = tail call half @llvm.minnum.f16(half [[SUB]], half 0xH3BFF)2465; GFX7-IR-NEXT: [[UNO:%.*]] = fcmp uno half [[X]], 0xH00002466; GFX7-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], half [[X]], half [[MIN]]2467; GFX7-IR-NEXT: [[FABS:%.*]] = tail call half @llvm.fabs.f16(half [[X]])2468; GFX7-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C002469; GFX7-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], half 0xH0000, half [[COND]]2470; GFX7-IR-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 42471; GFX7-IR-NEXT: ret half [[COND6]]2472;2473; IR-LEGALF16-LABEL: define half @safe_math_fract_f16(2474; IR-LEGALF16-SAME: half [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2475; IR-LEGALF16-NEXT: [[ENTRY:.*:]]2476; IR-LEGALF16-NEXT: [[FLOOR:%.*]] = tail call half @llvm.floor.f16(half [[X]])2477; IR-LEGALF16-NEXT: [[COND:%.*]] = call half @llvm.amdgcn.fract.f16(half [[X]])2478; IR-LEGALF16-NEXT: [[FABS:%.*]] = tail call half @llvm.fabs.f16(half [[X]])2479; IR-LEGALF16-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C002480; IR-LEGALF16-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], half 0xH0000, half [[COND]]2481; IR-LEGALF16-NEXT: store half [[FLOOR]], ptr addrspace(1) [[IP]], align 42482; IR-LEGALF16-NEXT: ret half [[COND6]]2483;2484; GFX6-LABEL: safe_math_fract_f16:2485; GFX6: ; %bb.0: ; %entry2486; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2487; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v02488; GFX6-NEXT: s_movk_i32 s8, 0x7c002489; GFX6-NEXT: s_mov_b32 s6, 02490; GFX6-NEXT: s_mov_b32 s7, 0xf0002491; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v02492; GFX6-NEXT: v_and_b32_e32 v0, 0x7fff, v02493; GFX6-NEXT: s_mov_b32 s4, s62494; GFX6-NEXT: s_mov_b32 s5, s62495; GFX6-NEXT: v_floor_f32_e32 v4, v32496; GFX6-NEXT: v_sub_f32_e32 v5, v3, v42497; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v42498; GFX6-NEXT: v_min_f32_e32 v5, 0x3f7fe000, v52499; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v3, v32500; GFX6-NEXT: v_cndmask_b32_e32 v3, v5, v3, vcc2501; GFX6-NEXT: v_cmp_ne_u32_e32 vcc, s8, v02502; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc2503; GFX6-NEXT: buffer_store_short v4, v[1:2], s[4:7], 0 addr642504; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)2505; GFX6-NEXT: s_setpc_b64 s[30:31]2506;2507; GFX7-LABEL: safe_math_fract_f16:2508; GFX7: ; %bb.0: ; %entry2509; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2510; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v02511; GFX7-NEXT: s_movk_i32 s8, 0x7c002512; GFX7-NEXT: s_mov_b32 s6, 02513; GFX7-NEXT: s_mov_b32 s7, 0xf0002514; GFX7-NEXT: v_cvt_f32_f16_e32 v3, v02515; GFX7-NEXT: v_and_b32_e32 v0, 0x7fff, v02516; GFX7-NEXT: s_mov_b32 s4, s62517; GFX7-NEXT: s_mov_b32 s5, s62518; GFX7-NEXT: v_floor_f32_e32 v4, v32519; GFX7-NEXT: v_sub_f32_e32 v5, v3, v42520; GFX7-NEXT: v_cvt_f16_f32_e32 v4, v42521; GFX7-NEXT: v_min_f32_e32 v5, 0x3f7fe000, v52522; GFX7-NEXT: v_cmp_u_f32_e32 vcc, v3, v32523; GFX7-NEXT: v_cndmask_b32_e32 v3, v5, v3, vcc2524; GFX7-NEXT: v_cmp_ne_u32_e32 vcc, s8, v02525; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc2526; GFX7-NEXT: buffer_store_short v4, v[1:2], s[4:7], 0 addr642527; GFX7-NEXT: s_waitcnt vmcnt(0)2528; GFX7-NEXT: s_setpc_b64 s[30:31]2529;2530; GFX8-LABEL: safe_math_fract_f16:2531; GFX8: ; %bb.0: ; %entry2532; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2533; GFX8-NEXT: s_movk_i32 s4, 0x7c002534; GFX8-NEXT: v_fract_f16_e32 v4, v02535; GFX8-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s42536; GFX8-NEXT: v_floor_f16_e32 v3, v02537; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc2538; GFX8-NEXT: global_store_short v[1:2], v3, off2539; GFX8-NEXT: s_waitcnt vmcnt(0)2540; GFX8-NEXT: s_setpc_b64 s[30:31]2541;2542; GFX11-TRUE16-LABEL: safe_math_fract_f16:2543; GFX11-TRUE16: ; %bb.0: ; %entry2544; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2545; GFX11-TRUE16-NEXT: v_fract_f16_e32 v0.h, v0.l2546; GFX11-TRUE16-NEXT: v_cmp_neq_f16_e64 s0, 0x7c00, |v0.l|2547; GFX11-TRUE16-NEXT: v_floor_f16_e32 v3.l, v0.l2548; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)2549; GFX11-TRUE16-NEXT: v_cndmask_b16 v0.l, 0, v0.h, s02550; GFX11-TRUE16-NEXT: global_store_b16 v[1:2], v3, off2551; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]2552;2553; GFX11-FAKE16-LABEL: safe_math_fract_f16:2554; GFX11-FAKE16: ; %bb.0: ; %entry2555; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2556; GFX11-FAKE16-NEXT: v_fract_f16_e32 v3, v02557; GFX11-FAKE16-NEXT: v_cmp_neq_f16_e64 vcc_lo, 0x7c00, |v0|2558; GFX11-FAKE16-NEXT: v_floor_f16_e32 v4, v02559; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)2560; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo2561; GFX11-FAKE16-NEXT: global_store_b16 v[1:2], v4, off2562; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]2563;2564; GFX12-TRUE16-LABEL: safe_math_fract_f16:2565; GFX12-TRUE16: ; %bb.0: ; %entry2566; GFX12-TRUE16-NEXT: s_wait_loadcnt_dscnt 0x02567; GFX12-TRUE16-NEXT: s_wait_expcnt 0x02568; GFX12-TRUE16-NEXT: s_wait_samplecnt 0x02569; GFX12-TRUE16-NEXT: s_wait_bvhcnt 0x02570; GFX12-TRUE16-NEXT: s_wait_kmcnt 0x02571; GFX12-TRUE16-NEXT: v_fract_f16_e32 v0.h, v0.l2572; GFX12-TRUE16-NEXT: v_cmp_neq_f16_e64 s0, 0x7c00, |v0.l|2573; GFX12-TRUE16-NEXT: v_floor_f16_e32 v3.l, v0.l2574; GFX12-TRUE16-NEXT: s_wait_alu depctr_va_sdst(0)2575; GFX12-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)2576; GFX12-TRUE16-NEXT: v_cndmask_b16 v0.l, 0, v0.h, s02577; GFX12-TRUE16-NEXT: global_store_b16 v[1:2], v3, off2578; GFX12-TRUE16-NEXT: s_setpc_b64 s[30:31]2579;2580; GFX12-FAKE16-LABEL: safe_math_fract_f16:2581; GFX12-FAKE16: ; %bb.0: ; %entry2582; GFX12-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x02583; GFX12-FAKE16-NEXT: s_wait_expcnt 0x02584; GFX12-FAKE16-NEXT: s_wait_samplecnt 0x02585; GFX12-FAKE16-NEXT: s_wait_bvhcnt 0x02586; GFX12-FAKE16-NEXT: s_wait_kmcnt 0x02587; GFX12-FAKE16-NEXT: v_fract_f16_e32 v3, v02588; GFX12-FAKE16-NEXT: v_cmp_neq_f16_e64 vcc_lo, 0x7c00, |v0|2589; GFX12-FAKE16-NEXT: v_floor_f16_e32 v4, v02590; GFX12-FAKE16-NEXT: s_wait_alu depctr_va_vcc(0)2591; GFX12-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)2592; GFX12-FAKE16-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo2593; GFX12-FAKE16-NEXT: global_store_b16 v[1:2], v4, off2594; GFX12-FAKE16-NEXT: s_setpc_b64 s[30:31]2595entry:2596 %floor = tail call half @llvm.floor.f16(half %x)2597 %sub = fsub half %x, %floor2598 %min = tail call half @llvm.minnum.f16(half %sub, half 0xH3BFF)2599 %uno = fcmp uno half %x, 0.000000e+002600 %cond = select i1 %uno, half %x, half %min2601 %fabs = tail call half @llvm.fabs.f16(half %x)2602 %cmpinf = fcmp oeq half %fabs, 0xH7C002603 %cond6 = select i1 %cmpinf, half 0.000000e+00, half %cond2604 store half %floor, ptr addrspace(1) %ip, align 42605 ret half %cond62606}2607 2608define <2 x half> @safe_math_fract_v2f16(<2 x half> %x, ptr addrspace(1) writeonly captures(none) %ip) {2609; GFX6-IR-LABEL: define <2 x half> @safe_math_fract_v2f16(2610; GFX6-IR-SAME: <2 x half> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2611; GFX6-IR-NEXT: [[ENTRY:.*:]]2612; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x half> @llvm.floor.v2f16(<2 x half> [[X]])2613; GFX6-IR-NEXT: [[SUB:%.*]] = fsub <2 x half> [[X]], [[FLOOR]]2614; GFX6-IR-NEXT: [[MIN:%.*]] = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> [[SUB]], <2 x half> splat (half 0xH3BFF))2615; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno <2 x half> [[X]], zeroinitializer2616; GFX6-IR-NEXT: [[COND:%.*]] = select <2 x i1> [[UNO]], <2 x half> [[X]], <2 x half> [[MIN]]2617; GFX6-IR-NEXT: [[FABS:%.*]] = tail call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])2618; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x half> [[FABS]], splat (half 0xH7C00)2619; GFX6-IR-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x half> zeroinitializer, <2 x half> [[COND]]2620; GFX6-IR-NEXT: store <2 x half> [[FLOOR]], ptr addrspace(1) [[IP]], align 42621; GFX6-IR-NEXT: ret <2 x half> [[COND6]]2622;2623; GFX7-IR-LABEL: define <2 x half> @safe_math_fract_v2f16(2624; GFX7-IR-SAME: <2 x half> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2625; GFX7-IR-NEXT: [[ENTRY:.*:]]2626; GFX7-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x half> @llvm.floor.v2f16(<2 x half> [[X]])2627; GFX7-IR-NEXT: [[SUB:%.*]] = fsub <2 x half> [[X]], [[FLOOR]]2628; GFX7-IR-NEXT: [[MIN:%.*]] = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> [[SUB]], <2 x half> splat (half 0xH3BFF))2629; GFX7-IR-NEXT: [[UNO:%.*]] = fcmp uno <2 x half> [[X]], zeroinitializer2630; GFX7-IR-NEXT: [[COND:%.*]] = select <2 x i1> [[UNO]], <2 x half> [[X]], <2 x half> [[MIN]]2631; GFX7-IR-NEXT: [[FABS:%.*]] = tail call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])2632; GFX7-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x half> [[FABS]], splat (half 0xH7C00)2633; GFX7-IR-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x half> zeroinitializer, <2 x half> [[COND]]2634; GFX7-IR-NEXT: store <2 x half> [[FLOOR]], ptr addrspace(1) [[IP]], align 42635; GFX7-IR-NEXT: ret <2 x half> [[COND6]]2636;2637; IR-LEGALF16-LABEL: define <2 x half> @safe_math_fract_v2f16(2638; IR-LEGALF16-SAME: <2 x half> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2639; IR-LEGALF16-NEXT: [[ENTRY:.*:]]2640; IR-LEGALF16-NEXT: [[FLOOR:%.*]] = tail call <2 x half> @llvm.floor.v2f16(<2 x half> [[X]])2641; IR-LEGALF16-NEXT: [[TMP0:%.*]] = extractelement <2 x half> [[X]], i64 02642; IR-LEGALF16-NEXT: [[TMP1:%.*]] = extractelement <2 x half> [[X]], i64 12643; IR-LEGALF16-NEXT: [[TMP2:%.*]] = call half @llvm.amdgcn.fract.f16(half [[TMP0]])2644; IR-LEGALF16-NEXT: [[TMP3:%.*]] = call half @llvm.amdgcn.fract.f16(half [[TMP1]])2645; IR-LEGALF16-NEXT: [[TMP4:%.*]] = insertelement <2 x half> poison, half [[TMP2]], i64 02646; IR-LEGALF16-NEXT: [[COND:%.*]] = insertelement <2 x half> [[TMP4]], half [[TMP3]], i64 12647; IR-LEGALF16-NEXT: [[FABS:%.*]] = tail call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X]])2648; IR-LEGALF16-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x half> [[FABS]], splat (half 0xH7C00)2649; IR-LEGALF16-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x half> zeroinitializer, <2 x half> [[COND]]2650; IR-LEGALF16-NEXT: store <2 x half> [[FLOOR]], ptr addrspace(1) [[IP]], align 42651; IR-LEGALF16-NEXT: ret <2 x half> [[COND6]]2652;2653; GFX6-LABEL: safe_math_fract_v2f16:2654; GFX6: ; %bb.0: ; %entry2655; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2656; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v12657; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v02658; GFX6-NEXT: s_movk_i32 s8, 0x7c002659; GFX6-NEXT: s_mov_b32 s6, 02660; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v12661; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v02662; GFX6-NEXT: v_and_b32_e32 v0, 0x7fff, v02663; GFX6-NEXT: v_and_b32_e32 v1, 0x7fff, v12664; GFX6-NEXT: v_floor_f32_e32 v6, v42665; GFX6-NEXT: v_cvt_f16_f32_e32 v7, v62666; GFX6-NEXT: v_floor_f32_e32 v8, v52667; GFX6-NEXT: v_sub_f32_e32 v6, v4, v62668; GFX6-NEXT: v_cvt_f16_f32_e32 v9, v82669; GFX6-NEXT: v_sub_f32_e32 v8, v5, v82670; GFX6-NEXT: v_min_f32_e32 v6, 0x3f7fe000, v62671; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v4, v42672; GFX6-NEXT: v_min_f32_e32 v8, 0x3f7fe000, v82673; GFX6-NEXT: v_cndmask_b32_e32 v4, v6, v4, vcc2674; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v5, v52675; GFX6-NEXT: v_cndmask_b32_e32 v5, v8, v5, vcc2676; GFX6-NEXT: v_cmp_ne_u32_e32 vcc, s8, v02677; GFX6-NEXT: v_lshlrev_b32_e32 v7, 16, v72678; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v5, vcc2679; GFX6-NEXT: v_cmp_ne_u32_e32 vcc, s8, v12680; GFX6-NEXT: s_mov_b32 s7, 0xf0002681; GFX6-NEXT: s_mov_b32 s4, s62682; GFX6-NEXT: s_mov_b32 s5, s62683; GFX6-NEXT: v_or_b32_e32 v7, v9, v72684; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v4, vcc2685; GFX6-NEXT: buffer_store_dword v7, v[2:3], s[4:7], 0 addr642686; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)2687; GFX6-NEXT: s_setpc_b64 s[30:31]2688;2689; GFX7-LABEL: safe_math_fract_v2f16:2690; GFX7: ; %bb.0: ; %entry2691; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2692; GFX7-NEXT: v_cvt_f16_f32_e32 v1, v12693; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v02694; GFX7-NEXT: s_movk_i32 s8, 0x7c002695; GFX7-NEXT: s_mov_b32 s6, 02696; GFX7-NEXT: v_cvt_f32_f16_e32 v4, v12697; GFX7-NEXT: v_cvt_f32_f16_e32 v5, v02698; GFX7-NEXT: v_and_b32_e32 v0, 0x7fff, v02699; GFX7-NEXT: v_and_b32_e32 v1, 0x7fff, v12700; GFX7-NEXT: v_floor_f32_e32 v6, v42701; GFX7-NEXT: v_cvt_f16_f32_e32 v7, v62702; GFX7-NEXT: v_floor_f32_e32 v8, v52703; GFX7-NEXT: v_sub_f32_e32 v6, v4, v62704; GFX7-NEXT: v_cvt_f16_f32_e32 v9, v82705; GFX7-NEXT: v_sub_f32_e32 v8, v5, v82706; GFX7-NEXT: v_min_f32_e32 v6, 0x3f7fe000, v62707; GFX7-NEXT: v_cmp_u_f32_e32 vcc, v4, v42708; GFX7-NEXT: v_min_f32_e32 v8, 0x3f7fe000, v82709; GFX7-NEXT: v_cndmask_b32_e32 v4, v6, v4, vcc2710; GFX7-NEXT: v_cmp_u_f32_e32 vcc, v5, v52711; GFX7-NEXT: v_cndmask_b32_e32 v5, v8, v5, vcc2712; GFX7-NEXT: v_cmp_ne_u32_e32 vcc, s8, v02713; GFX7-NEXT: v_lshlrev_b32_e32 v7, 16, v72714; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v5, vcc2715; GFX7-NEXT: v_cmp_ne_u32_e32 vcc, s8, v12716; GFX7-NEXT: s_mov_b32 s7, 0xf0002717; GFX7-NEXT: s_mov_b32 s4, s62718; GFX7-NEXT: s_mov_b32 s5, s62719; GFX7-NEXT: v_or_b32_e32 v7, v9, v72720; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v4, vcc2721; GFX7-NEXT: buffer_store_dword v7, v[2:3], s[4:7], 0 addr642722; GFX7-NEXT: s_waitcnt vmcnt(0)2723; GFX7-NEXT: s_setpc_b64 s[30:31]2724;2725; GFX8-LABEL: safe_math_fract_v2f16:2726; GFX8: ; %bb.0: ; %entry2727; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2728; GFX8-NEXT: s_movk_i32 s6, 0x2042729; GFX8-NEXT: v_floor_f16_sdwa v3, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_12730; GFX8-NEXT: v_floor_f16_e32 v4, v02731; GFX8-NEXT: v_fract_f16_sdwa v5, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_12732; GFX8-NEXT: v_cmp_class_f16_sdwa s[4:5], v0, s6 src0_sel:WORD_1 src1_sel:DWORD2733; GFX8-NEXT: v_pack_b32_f16 v3, v4, v32734; GFX8-NEXT: v_fract_f16_e32 v4, v02735; GFX8-NEXT: v_cndmask_b32_e64 v5, v5, 0, s[4:5]2736; GFX8-NEXT: v_cmp_class_f16_e64 s[4:5], v0, s62737; GFX8-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]2738; GFX8-NEXT: v_pack_b32_f16 v0, v0, v52739; GFX8-NEXT: global_store_dword v[1:2], v3, off2740; GFX8-NEXT: s_waitcnt vmcnt(0)2741; GFX8-NEXT: s_setpc_b64 s[30:31]2742;2743; GFX11-TRUE16-LABEL: safe_math_fract_v2f16:2744; GFX11-TRUE16: ; %bb.0: ; %entry2745; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2746; GFX11-TRUE16-NEXT: v_fract_f16_e32 v3.l, v0.l2747; GFX11-TRUE16-NEXT: v_fract_f16_e32 v3.h, v0.h2748; GFX11-TRUE16-NEXT: v_cmp_class_f16_e64 s0, v0.h, 0x2042749; GFX11-TRUE16-NEXT: v_cmp_class_f16_e64 s1, v0.l, 0x2042750; GFX11-TRUE16-NEXT: v_floor_f16_e32 v0.h, v0.h2751; GFX11-TRUE16-NEXT: v_floor_f16_e32 v0.l, v0.l2752; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)2753; GFX11-TRUE16-NEXT: v_cndmask_b16 v3.h, v3.h, 0, s02754; GFX11-TRUE16-NEXT: v_cndmask_b16 v3.l, v3.l, 0, s12755; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)2756; GFX11-TRUE16-NEXT: v_pack_b32_f16 v4, v0.l, v0.h2757; GFX11-TRUE16-NEXT: v_pack_b32_f16 v0, v3.l, v3.h2758; GFX11-TRUE16-NEXT: global_store_b32 v[1:2], v4, off2759; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]2760;2761; GFX11-FAKE16-LABEL: safe_math_fract_v2f16:2762; GFX11-FAKE16: ; %bb.0: ; %entry2763; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2764; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v02765; GFX11-FAKE16-NEXT: v_fract_f16_e32 v6, v02766; GFX11-FAKE16-NEXT: v_floor_f16_e32 v5, v02767; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_2) | instid1(VALU_DEP_2)2768; GFX11-FAKE16-NEXT: v_fract_f16_e32 v4, v32769; GFX11-FAKE16-NEXT: v_cmp_class_f16_e64 s0, v3, 0x2042770; GFX11-FAKE16-NEXT: v_floor_f16_e32 v7, v32771; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, v4, 0, s02772; GFX11-FAKE16-NEXT: v_cmp_class_f16_e64 s0, v0, 0x2042773; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)2774; GFX11-FAKE16-NEXT: v_pack_b32_f16 v4, v5, v72775; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v6, 0, s02776; GFX11-FAKE16-NEXT: global_store_b32 v[1:2], v4, off2777; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v32778; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]2779;2780; GFX12-TRUE16-LABEL: safe_math_fract_v2f16:2781; GFX12-TRUE16: ; %bb.0: ; %entry2782; GFX12-TRUE16-NEXT: s_wait_loadcnt_dscnt 0x02783; GFX12-TRUE16-NEXT: s_wait_expcnt 0x02784; GFX12-TRUE16-NEXT: s_wait_samplecnt 0x02785; GFX12-TRUE16-NEXT: s_wait_bvhcnt 0x02786; GFX12-TRUE16-NEXT: s_wait_kmcnt 0x02787; GFX12-TRUE16-NEXT: v_fract_f16_e32 v3.l, v0.l2788; GFX12-TRUE16-NEXT: v_fract_f16_e32 v3.h, v0.h2789; GFX12-TRUE16-NEXT: v_cmp_class_f16_e64 s0, v0.h, 0x2042790; GFX12-TRUE16-NEXT: v_cmp_class_f16_e64 s1, v0.l, 0x2042791; GFX12-TRUE16-NEXT: v_floor_f16_e32 v0.h, v0.h2792; GFX12-TRUE16-NEXT: v_floor_f16_e32 v0.l, v0.l2793; GFX12-TRUE16-NEXT: s_wait_alu depctr_va_sdst(0)2794; GFX12-TRUE16-NEXT: v_cndmask_b16 v3.h, v3.h, 0, s02795; GFX12-TRUE16-NEXT: v_cndmask_b16 v3.l, v3.l, 0, s12796; GFX12-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)2797; GFX12-TRUE16-NEXT: v_pack_b32_f16 v4, v0.l, v0.h2798; GFX12-TRUE16-NEXT: v_pack_b32_f16 v0, v3.l, v3.h2799; GFX12-TRUE16-NEXT: global_store_b32 v[1:2], v4, off2800; GFX12-TRUE16-NEXT: s_setpc_b64 s[30:31]2801;2802; GFX12-FAKE16-LABEL: safe_math_fract_v2f16:2803; GFX12-FAKE16: ; %bb.0: ; %entry2804; GFX12-FAKE16-NEXT: s_wait_loadcnt_dscnt 0x02805; GFX12-FAKE16-NEXT: s_wait_expcnt 0x02806; GFX12-FAKE16-NEXT: s_wait_samplecnt 0x02807; GFX12-FAKE16-NEXT: s_wait_bvhcnt 0x02808; GFX12-FAKE16-NEXT: s_wait_kmcnt 0x02809; GFX12-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v02810; GFX12-FAKE16-NEXT: v_fract_f16_e32 v6, v02811; GFX12-FAKE16-NEXT: v_floor_f16_e32 v5, v02812; GFX12-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_3) | instid1(VALU_DEP_2)2813; GFX12-FAKE16-NEXT: v_fract_f16_e32 v4, v32814; GFX12-FAKE16-NEXT: v_cmp_class_f16_e64 s0, v3, 0x2042815; GFX12-FAKE16-NEXT: v_floor_f16_e32 v7, v32816; GFX12-FAKE16-NEXT: s_wait_alu depctr_va_sdst(0)2817; GFX12-FAKE16-NEXT: v_cndmask_b32_e64 v3, v4, 0, s02818; GFX12-FAKE16-NEXT: v_cmp_class_f16_e64 s0, v0, 0x2042819; GFX12-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)2820; GFX12-FAKE16-NEXT: v_pack_b32_f16 v4, v5, v72821; GFX12-FAKE16-NEXT: s_wait_alu depctr_va_sdst(0)2822; GFX12-FAKE16-NEXT: v_cndmask_b32_e64 v0, v6, 0, s02823; GFX12-FAKE16-NEXT: global_store_b32 v[1:2], v4, off2824; GFX12-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v32825; GFX12-FAKE16-NEXT: s_setpc_b64 s[30:31]2826entry:2827 %floor = tail call <2 x half> @llvm.floor.v2f16(<2 x half> %x)2828 %sub = fsub <2 x half> %x, %floor2829 %min = tail call <2 x half> @llvm.minnum.v2f16(<2 x half> %sub, <2 x half> <half 0xH3BFF, half 0xH3BFF>)2830 %uno = fcmp uno <2 x half> %x, zeroinitializer2831 %cond = select <2 x i1> %uno, <2 x half> %x, <2 x half> %min2832 %fabs = tail call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)2833 %cmpinf = fcmp oeq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>2834 %cond6 = select <2 x i1> %cmpinf, <2 x half> zeroinitializer, <2 x half> %cond2835 store <2 x half> %floor, ptr addrspace(1) %ip, align 42836 ret <2 x half> %cond62837}2838 2839define <2 x double> @safe_math_fract_v2f64(<2 x double> %x, ptr addrspace(1) writeonly captures(none) %ip) {2840; GFX6-IR-LABEL: define <2 x double> @safe_math_fract_v2f64(2841; GFX6-IR-SAME: <2 x double> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2842; GFX6-IR-NEXT: [[ENTRY:.*:]]2843; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call <2 x double> @llvm.floor.v2f64(<2 x double> [[X]])2844; GFX6-IR-NEXT: [[SUB:%.*]] = fsub <2 x double> [[X]], [[FLOOR]]2845; GFX6-IR-NEXT: [[MIN:%.*]] = tail call <2 x double> @llvm.minnum.v2f64(<2 x double> [[SUB]], <2 x double> splat (double 0x3FEFFFFFFFFFFFFF))2846; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno <2 x double> [[X]], zeroinitializer2847; GFX6-IR-NEXT: [[COND:%.*]] = select <2 x i1> [[UNO]], <2 x double> [[X]], <2 x double> [[MIN]]2848; GFX6-IR-NEXT: [[FABS:%.*]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]])2849; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x double> [[FABS]], splat (double 0x7FF0000000000000)2850; GFX6-IR-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x double> zeroinitializer, <2 x double> [[COND]]2851; GFX6-IR-NEXT: store <2 x double> [[FLOOR]], ptr addrspace(1) [[IP]], align 42852; GFX6-IR-NEXT: ret <2 x double> [[COND6]]2853;2854; IR-FRACT-LABEL: define <2 x double> @safe_math_fract_v2f64(2855; IR-FRACT-SAME: <2 x double> [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {2856; IR-FRACT-NEXT: [[ENTRY:.*:]]2857; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call <2 x double> @llvm.floor.v2f64(<2 x double> [[X]])2858; IR-FRACT-NEXT: [[TMP0:%.*]] = extractelement <2 x double> [[X]], i64 02859; IR-FRACT-NEXT: [[TMP1:%.*]] = extractelement <2 x double> [[X]], i64 12860; IR-FRACT-NEXT: [[TMP2:%.*]] = call double @llvm.amdgcn.fract.f64(double [[TMP0]])2861; IR-FRACT-NEXT: [[TMP3:%.*]] = call double @llvm.amdgcn.fract.f64(double [[TMP1]])2862; IR-FRACT-NEXT: [[TMP4:%.*]] = insertelement <2 x double> poison, double [[TMP2]], i64 02863; IR-FRACT-NEXT: [[COND:%.*]] = insertelement <2 x double> [[TMP4]], double [[TMP3]], i64 12864; IR-FRACT-NEXT: [[FABS:%.*]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> [[X]])2865; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq <2 x double> [[FABS]], splat (double 0x7FF0000000000000)2866; IR-FRACT-NEXT: [[COND6:%.*]] = select <2 x i1> [[CMPINF]], <2 x double> zeroinitializer, <2 x double> [[COND]]2867; IR-FRACT-NEXT: store <2 x double> [[FLOOR]], ptr addrspace(1) [[IP]], align 42868; IR-FRACT-NEXT: ret <2 x double> [[COND6]]2869;2870; GFX6-LABEL: safe_math_fract_v2f64:2871; GFX6: ; %bb.0: ; %entry2872; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2873; GFX6-NEXT: v_fract_f64_e32 v[6:7], v[2:3]2874; GFX6-NEXT: v_mov_b32_e32 v10, -12875; GFX6-NEXT: v_mov_b32_e32 v11, 0x3fefffff2876; GFX6-NEXT: v_min_f64 v[6:7], v[6:7], v[10:11]2877; GFX6-NEXT: v_cmp_class_f64_e64 vcc, v[2:3], 32878; GFX6-NEXT: v_fract_f64_e32 v[12:13], v[0:1]2879; GFX6-NEXT: v_cndmask_b32_e32 v6, v6, v2, vcc2880; GFX6-NEXT: v_cndmask_b32_e32 v7, v7, v3, vcc2881; GFX6-NEXT: v_add_f64 v[8:9], v[2:3], -v[6:7]2882; GFX6-NEXT: v_min_f64 v[6:7], v[12:13], v[10:11]2883; GFX6-NEXT: v_cmp_class_f64_e64 vcc, v[0:1], 32884; GFX6-NEXT: v_add_f64 v[10:11], v[2:3], -v[8:9]2885; GFX6-NEXT: v_cndmask_b32_e32 v6, v6, v0, vcc2886; GFX6-NEXT: v_cndmask_b32_e32 v7, v7, v1, vcc2887; GFX6-NEXT: v_add_f64 v[6:7], v[0:1], -v[6:7]2888; GFX6-NEXT: s_mov_b32 s8, -12889; GFX6-NEXT: s_mov_b32 s9, 0x3fefffff2890; GFX6-NEXT: v_add_f64 v[12:13], v[0:1], -v[6:7]2891; GFX6-NEXT: v_min_f64 v[10:11], v[10:11], s[8:9]2892; GFX6-NEXT: v_cmp_u_f64_e32 vcc, v[2:3], v[2:3]2893; GFX6-NEXT: v_min_f64 v[12:13], v[12:13], s[8:9]2894; GFX6-NEXT: v_cndmask_b32_e32 v11, v11, v3, vcc2895; GFX6-NEXT: v_cndmask_b32_e32 v10, v10, v2, vcc2896; GFX6-NEXT: v_cmp_u_f64_e32 vcc, v[0:1], v[0:1]2897; GFX6-NEXT: v_mov_b32_e32 v14, 0x2042898; GFX6-NEXT: v_cndmask_b32_e32 v13, v13, v1, vcc2899; GFX6-NEXT: v_cndmask_b32_e32 v12, v12, v0, vcc2900; GFX6-NEXT: v_cmp_class_f64_e32 vcc, v[0:1], v142901; GFX6-NEXT: s_mov_b32 s6, 02902; GFX6-NEXT: v_cndmask_b32_e64 v0, v12, 0, vcc2903; GFX6-NEXT: v_cndmask_b32_e64 v1, v13, 0, vcc2904; GFX6-NEXT: v_cmp_class_f64_e32 vcc, v[2:3], v142905; GFX6-NEXT: s_mov_b32 s7, 0xf0002906; GFX6-NEXT: s_mov_b32 s4, s62907; GFX6-NEXT: s_mov_b32 s5, s62908; GFX6-NEXT: v_cndmask_b32_e64 v2, v10, 0, vcc2909; GFX6-NEXT: v_cndmask_b32_e64 v3, v11, 0, vcc2910; GFX6-NEXT: buffer_store_dwordx4 v[6:9], v[4:5], s[4:7], 0 addr642911; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)2912; GFX6-NEXT: s_setpc_b64 s[30:31]2913;2914; GFX7-LABEL: safe_math_fract_v2f64:2915; GFX7: ; %bb.0: ; %entry2916; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2917; GFX7-NEXT: v_mov_b32_e32 v6, 0x2042918; GFX7-NEXT: v_fract_f64_e32 v[10:11], v[0:1]2919; GFX7-NEXT: v_cmp_class_f64_e32 vcc, v[0:1], v62920; GFX7-NEXT: v_fract_f64_e32 v[12:13], v[2:3]2921; GFX7-NEXT: v_cmp_class_f64_e64 s[4:5], v[2:3], v62922; GFX7-NEXT: v_floor_f64_e32 v[8:9], v[2:3]2923; GFX7-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2924; GFX7-NEXT: s_mov_b32 s10, 02925; GFX7-NEXT: s_mov_b32 s11, 0xf0002926; GFX7-NEXT: s_mov_b32 s8, s102927; GFX7-NEXT: s_mov_b32 s9, s102928; GFX7-NEXT: v_cndmask_b32_e64 v0, v10, 0, vcc2929; GFX7-NEXT: v_cndmask_b32_e64 v1, v11, 0, vcc2930; GFX7-NEXT: v_cndmask_b32_e64 v2, v12, 0, s[4:5]2931; GFX7-NEXT: v_cndmask_b32_e64 v3, v13, 0, s[4:5]2932; GFX7-NEXT: buffer_store_dwordx4 v[6:9], v[4:5], s[8:11], 0 addr642933; GFX7-NEXT: s_waitcnt vmcnt(0)2934; GFX7-NEXT: s_setpc_b64 s[30:31]2935;2936; GFX8-LABEL: safe_math_fract_v2f64:2937; GFX8: ; %bb.0: ; %entry2938; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2939; GFX8-NEXT: v_mov_b32_e32 v6, 0x2042940; GFX8-NEXT: v_fract_f64_e32 v[10:11], v[0:1]2941; GFX8-NEXT: v_cmp_class_f64_e32 vcc, v[0:1], v62942; GFX8-NEXT: v_fract_f64_e32 v[12:13], v[2:3]2943; GFX8-NEXT: v_cmp_class_f64_e64 s[4:5], v[2:3], v62944; GFX8-NEXT: v_floor_f64_e32 v[8:9], v[2:3]2945; GFX8-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2946; GFX8-NEXT: v_cndmask_b32_e64 v0, v10, 0, vcc2947; GFX8-NEXT: v_cndmask_b32_e64 v1, v11, 0, vcc2948; GFX8-NEXT: v_cndmask_b32_e64 v2, v12, 0, s[4:5]2949; GFX8-NEXT: v_cndmask_b32_e64 v3, v13, 0, s[4:5]2950; GFX8-NEXT: global_store_dwordx4 v[4:5], v[6:9], off2951; GFX8-NEXT: s_waitcnt vmcnt(0)2952; GFX8-NEXT: s_setpc_b64 s[30:31]2953;2954; GFX11-LABEL: safe_math_fract_v2f64:2955; GFX11: ; %bb.0: ; %entry2956; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)2957; GFX11-NEXT: v_fract_f64_e32 v[10:11], v[0:1]2958; GFX11-NEXT: v_cmp_class_f64_e64 s0, v[0:1], 0x2042959; GFX11-NEXT: v_fract_f64_e32 v[12:13], v[2:3]2960; GFX11-NEXT: v_cmp_class_f64_e64 s1, v[2:3], 0x2042961; GFX11-NEXT: v_floor_f64_e32 v[8:9], v[2:3]2962; GFX11-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2963; GFX11-NEXT: v_cndmask_b32_e64 v0, v10, 0, s02964; GFX11-NEXT: v_cndmask_b32_e64 v1, v11, 0, s02965; GFX11-NEXT: v_cndmask_b32_e64 v2, v12, 0, s12966; GFX11-NEXT: v_cndmask_b32_e64 v3, v13, 0, s12967; GFX11-NEXT: global_store_b128 v[4:5], v[6:9], off2968; GFX11-NEXT: s_setpc_b64 s[30:31]2969;2970; GFX12-LABEL: safe_math_fract_v2f64:2971; GFX12: ; %bb.0: ; %entry2972; GFX12-NEXT: s_wait_loadcnt_dscnt 0x02973; GFX12-NEXT: s_wait_expcnt 0x02974; GFX12-NEXT: s_wait_samplecnt 0x02975; GFX12-NEXT: s_wait_bvhcnt 0x02976; GFX12-NEXT: s_wait_kmcnt 0x02977; GFX12-NEXT: v_fract_f64_e32 v[10:11], v[0:1]2978; GFX12-NEXT: v_cmp_class_f64_e64 s0, v[0:1], 0x2042979; GFX12-NEXT: v_fract_f64_e32 v[12:13], v[2:3]2980; GFX12-NEXT: v_cmp_class_f64_e64 s1, v[2:3], 0x2042981; GFX12-NEXT: v_floor_f64_e32 v[8:9], v[2:3]2982; GFX12-NEXT: v_floor_f64_e32 v[6:7], v[0:1]2983; GFX12-NEXT: s_wait_alu depctr_va_sdst(0)2984; GFX12-NEXT: v_cndmask_b32_e64 v0, v10, 0, s02985; GFX12-NEXT: v_cndmask_b32_e64 v1, v11, 0, s02986; GFX12-NEXT: v_cndmask_b32_e64 v2, v12, 0, s12987; GFX12-NEXT: v_cndmask_b32_e64 v3, v13, 0, s12988; GFX12-NEXT: global_store_b128 v[4:5], v[6:9], off2989; GFX12-NEXT: s_setpc_b64 s[30:31]2990entry:2991 %floor = tail call <2 x double> @llvm.floor.v2f64(<2 x double> %x)2992 %sub = fsub <2 x double> %x, %floor2993 %min = tail call <2 x double> @llvm.minnum.v2f64(<2 x double> %sub, <2 x double> <double 0x3FEFFFFFFFFFFFFF, double 0x3FEFFFFFFFFFFFFF>)2994 %uno = fcmp uno <2 x double> %x, zeroinitializer2995 %cond = select <2 x i1> %uno, <2 x double> %x, <2 x double> %min2996 %fabs = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %x)2997 %cmpinf = fcmp oeq <2 x double> %fabs, <double 0x7FF0000000000000, double 0x7FF0000000000000>2998 %cond6 = select <2 x i1> %cmpinf, <2 x double> zeroinitializer, <2 x double> %cond2999 store <2 x double> %floor, ptr addrspace(1) %ip, align 43000 ret <2 x double> %cond63001}3002 3003define float @safe_math_fract_f32_minimum(float %x, ptr addrspace(1) writeonly captures(none) %ip) {3004; GFX6-IR-LABEL: define float @safe_math_fract_f32_minimum(3005; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3006; GFX6-IR-NEXT: [[ENTRY:.*:]]3007; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3008; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3009; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3010; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+003011; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]3012; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3013; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003014; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3015; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43016; GFX6-IR-NEXT: ret float [[COND6]]3017;3018; IR-FRACT-LABEL: define float @safe_math_fract_f32_minimum(3019; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3020; IR-FRACT-NEXT: [[ENTRY:.*:]]3021; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3022; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])3023; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3024; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003025; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3026; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43027; IR-FRACT-NEXT: ret float [[COND6]]3028;3029; GFX6-LABEL: safe_math_fract_f32_minimum:3030; GFX6: ; %bb.0: ; %entry3031; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3032; GFX6-NEXT: v_floor_f32_e32 v3, v03033; GFX6-NEXT: v_sub_f32_e32 v4, v0, v33034; GFX6-NEXT: v_min_f32_e32 v5, 0x3f7fffff, v43035; GFX6-NEXT: v_mov_b32_e32 v6, 0x7fc000003036; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v4, v43037; GFX6-NEXT: v_cndmask_b32_e32 v4, v6, v5, vcc3038; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v03039; GFX6-NEXT: s_mov_b32 s8, 0x7f8000003040; GFX6-NEXT: s_mov_b32 s6, 03041; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v0, vcc3042; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83043; GFX6-NEXT: s_mov_b32 s7, 0xf0003044; GFX6-NEXT: s_mov_b32 s4, s63045; GFX6-NEXT: s_mov_b32 s5, s63046; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3047; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643048; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)3049; GFX6-NEXT: s_setpc_b64 s[30:31]3050;3051; GFX7-LABEL: safe_math_fract_f32_minimum:3052; GFX7: ; %bb.0: ; %entry3053; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3054; GFX7-NEXT: s_mov_b32 s8, 0x7f8000003055; GFX7-NEXT: s_mov_b32 s6, 03056; GFX7-NEXT: v_fract_f32_e32 v4, v03057; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83058; GFX7-NEXT: s_mov_b32 s7, 0xf0003059; GFX7-NEXT: s_mov_b32 s4, s63060; GFX7-NEXT: s_mov_b32 s5, s63061; GFX7-NEXT: v_floor_f32_e32 v3, v03062; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3063; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643064; GFX7-NEXT: s_waitcnt vmcnt(0)3065; GFX7-NEXT: s_setpc_b64 s[30:31]3066;3067; GFX8-LABEL: safe_math_fract_f32_minimum:3068; GFX8: ; %bb.0: ; %entry3069; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3070; GFX8-NEXT: s_mov_b32 s4, 0x7f8000003071; GFX8-NEXT: v_fract_f32_e32 v4, v03072; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s43073; GFX8-NEXT: v_floor_f32_e32 v3, v03074; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3075; GFX8-NEXT: global_store_dword v[1:2], v3, off3076; GFX8-NEXT: s_waitcnt vmcnt(0)3077; GFX8-NEXT: s_setpc_b64 s[30:31]3078;3079; GFX11-LABEL: safe_math_fract_f32_minimum:3080; GFX11: ; %bb.0: ; %entry3081; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3082; GFX11-NEXT: v_fract_f32_e32 v3, v03083; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3084; GFX11-NEXT: v_floor_f32_e32 v4, v03085; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)3086; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3087; GFX11-NEXT: global_store_b32 v[1:2], v4, off3088; GFX11-NEXT: s_setpc_b64 s[30:31]3089;3090; GFX12-LABEL: safe_math_fract_f32_minimum:3091; GFX12: ; %bb.0: ; %entry3092; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03093; GFX12-NEXT: s_wait_expcnt 0x03094; GFX12-NEXT: s_wait_samplecnt 0x03095; GFX12-NEXT: s_wait_bvhcnt 0x03096; GFX12-NEXT: s_wait_kmcnt 0x03097; GFX12-NEXT: v_fract_f32_e32 v3, v03098; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3099; GFX12-NEXT: v_floor_f32_e32 v4, v03100; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)3101; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)3102; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3103; GFX12-NEXT: global_store_b32 v[1:2], v4, off3104; GFX12-NEXT: s_setpc_b64 s[30:31]3105entry:3106 %floor = tail call float @llvm.floor.f32(float %x)3107 %sub = fsub float %x, %floor3108 %min = tail call float @llvm.minimum.f32(float %sub, float 0x3FEFFFFFE0000000)3109 %uno = fcmp uno float %x, 0.000000e+003110 %cond = select i1 %uno, float %x, float %min3111 %fabs = tail call float @llvm.fabs.f32(float %x)3112 %cmpinf = fcmp oeq float %fabs, 0x7FF00000000000003113 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond3114 store float %floor, ptr addrspace(1) %ip, align 43115 ret float %cond63116}3117 3118define float @safe_math_fract_f32_minimum_swap(float %x, ptr addrspace(1) writeonly captures(none) %ip) {3119; GFX6-IR-LABEL: define float @safe_math_fract_f32_minimum_swap(3120; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3121; GFX6-IR-NEXT: [[ENTRY:.*:]]3122; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3123; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3124; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3125; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp ord float [[X]], 0.000000e+003126; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[MIN]], float [[X]]3127; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3128; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003129; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3130; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43131; GFX6-IR-NEXT: ret float [[COND6]]3132;3133; IR-FRACT-LABEL: define float @safe_math_fract_f32_minimum_swap(3134; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3135; IR-FRACT-NEXT: [[ENTRY:.*:]]3136; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3137; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])3138; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3139; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003140; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3141; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43142; IR-FRACT-NEXT: ret float [[COND6]]3143;3144; GFX6-LABEL: safe_math_fract_f32_minimum_swap:3145; GFX6: ; %bb.0: ; %entry3146; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3147; GFX6-NEXT: v_floor_f32_e32 v3, v03148; GFX6-NEXT: v_sub_f32_e32 v4, v0, v33149; GFX6-NEXT: v_min_f32_e32 v5, 0x3f7fffff, v43150; GFX6-NEXT: v_mov_b32_e32 v6, 0x7fc000003151; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v4, v43152; GFX6-NEXT: v_cndmask_b32_e32 v4, v6, v5, vcc3153; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v03154; GFX6-NEXT: s_mov_b32 s8, 0x7f8000003155; GFX6-NEXT: s_mov_b32 s6, 03156; GFX6-NEXT: v_cndmask_b32_e32 v4, v0, v4, vcc3157; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83158; GFX6-NEXT: s_mov_b32 s7, 0xf0003159; GFX6-NEXT: s_mov_b32 s4, s63160; GFX6-NEXT: s_mov_b32 s5, s63161; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3162; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643163; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)3164; GFX6-NEXT: s_setpc_b64 s[30:31]3165;3166; GFX7-LABEL: safe_math_fract_f32_minimum_swap:3167; GFX7: ; %bb.0: ; %entry3168; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3169; GFX7-NEXT: s_mov_b32 s8, 0x7f8000003170; GFX7-NEXT: s_mov_b32 s6, 03171; GFX7-NEXT: v_fract_f32_e32 v4, v03172; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83173; GFX7-NEXT: s_mov_b32 s7, 0xf0003174; GFX7-NEXT: s_mov_b32 s4, s63175; GFX7-NEXT: s_mov_b32 s5, s63176; GFX7-NEXT: v_floor_f32_e32 v3, v03177; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3178; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643179; GFX7-NEXT: s_waitcnt vmcnt(0)3180; GFX7-NEXT: s_setpc_b64 s[30:31]3181;3182; GFX8-LABEL: safe_math_fract_f32_minimum_swap:3183; GFX8: ; %bb.0: ; %entry3184; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3185; GFX8-NEXT: s_mov_b32 s4, 0x7f8000003186; GFX8-NEXT: v_fract_f32_e32 v4, v03187; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s43188; GFX8-NEXT: v_floor_f32_e32 v3, v03189; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3190; GFX8-NEXT: global_store_dword v[1:2], v3, off3191; GFX8-NEXT: s_waitcnt vmcnt(0)3192; GFX8-NEXT: s_setpc_b64 s[30:31]3193;3194; GFX11-LABEL: safe_math_fract_f32_minimum_swap:3195; GFX11: ; %bb.0: ; %entry3196; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3197; GFX11-NEXT: v_fract_f32_e32 v3, v03198; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3199; GFX11-NEXT: v_floor_f32_e32 v4, v03200; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)3201; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3202; GFX11-NEXT: global_store_b32 v[1:2], v4, off3203; GFX11-NEXT: s_setpc_b64 s[30:31]3204;3205; GFX12-LABEL: safe_math_fract_f32_minimum_swap:3206; GFX12: ; %bb.0: ; %entry3207; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03208; GFX12-NEXT: s_wait_expcnt 0x03209; GFX12-NEXT: s_wait_samplecnt 0x03210; GFX12-NEXT: s_wait_bvhcnt 0x03211; GFX12-NEXT: s_wait_kmcnt 0x03212; GFX12-NEXT: v_fract_f32_e32 v3, v03213; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3214; GFX12-NEXT: v_floor_f32_e32 v4, v03215; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)3216; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)3217; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3218; GFX12-NEXT: global_store_b32 v[1:2], v4, off3219; GFX12-NEXT: s_setpc_b64 s[30:31]3220entry:3221 %floor = tail call float @llvm.floor.f32(float %x)3222 %sub = fsub float %x, %floor3223 %min = tail call float @llvm.minimum.f32(float %sub, float 0x3FEFFFFFE0000000)3224 %uno = fcmp ord float %x, 0.000000e+003225 %cond = select i1 %uno, float %min, float %x3226 %fabs = tail call float @llvm.fabs.f32(float %x)3227 %cmpinf = fcmp oeq float %fabs, 0x7FF00000000000003228 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond3229 store float %floor, ptr addrspace(1) %ip, align 43230 ret float %cond63231}3232 3233define float @safe_math_fract_f32_minimumnum(float %x, ptr addrspace(1) writeonly captures(none) %ip) {3234; GFX6-IR-LABEL: define float @safe_math_fract_f32_minimumnum(3235; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3236; GFX6-IR-NEXT: [[ENTRY:.*:]]3237; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3238; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3239; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimumnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3240; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp uno float [[X]], 0.000000e+003241; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[X]], float [[MIN]]3242; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3243; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003244; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3245; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43246; GFX6-IR-NEXT: ret float [[COND6]]3247;3248; IR-FRACT-LABEL: define float @safe_math_fract_f32_minimumnum(3249; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3250; IR-FRACT-NEXT: [[ENTRY:.*:]]3251; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3252; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])3253; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3254; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003255; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3256; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43257; IR-FRACT-NEXT: ret float [[COND6]]3258;3259; GFX6-LABEL: safe_math_fract_f32_minimumnum:3260; GFX6: ; %bb.0: ; %entry3261; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3262; GFX6-NEXT: v_floor_f32_e32 v3, v03263; GFX6-NEXT: v_sub_f32_e32 v4, v0, v33264; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v43265; GFX6-NEXT: v_cmp_u_f32_e32 vcc, v0, v03266; GFX6-NEXT: s_mov_b32 s8, 0x7f8000003267; GFX6-NEXT: s_mov_b32 s6, 03268; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v0, vcc3269; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83270; GFX6-NEXT: s_mov_b32 s7, 0xf0003271; GFX6-NEXT: s_mov_b32 s4, s63272; GFX6-NEXT: s_mov_b32 s5, s63273; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3274; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643275; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)3276; GFX6-NEXT: s_setpc_b64 s[30:31]3277;3278; GFX7-LABEL: safe_math_fract_f32_minimumnum:3279; GFX7: ; %bb.0: ; %entry3280; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3281; GFX7-NEXT: s_mov_b32 s8, 0x7f8000003282; GFX7-NEXT: s_mov_b32 s6, 03283; GFX7-NEXT: v_fract_f32_e32 v4, v03284; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83285; GFX7-NEXT: s_mov_b32 s7, 0xf0003286; GFX7-NEXT: s_mov_b32 s4, s63287; GFX7-NEXT: s_mov_b32 s5, s63288; GFX7-NEXT: v_floor_f32_e32 v3, v03289; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3290; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643291; GFX7-NEXT: s_waitcnt vmcnt(0)3292; GFX7-NEXT: s_setpc_b64 s[30:31]3293;3294; GFX8-LABEL: safe_math_fract_f32_minimumnum:3295; GFX8: ; %bb.0: ; %entry3296; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3297; GFX8-NEXT: s_mov_b32 s4, 0x7f8000003298; GFX8-NEXT: v_fract_f32_e32 v4, v03299; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s43300; GFX8-NEXT: v_floor_f32_e32 v3, v03301; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3302; GFX8-NEXT: global_store_dword v[1:2], v3, off3303; GFX8-NEXT: s_waitcnt vmcnt(0)3304; GFX8-NEXT: s_setpc_b64 s[30:31]3305;3306; GFX11-LABEL: safe_math_fract_f32_minimumnum:3307; GFX11: ; %bb.0: ; %entry3308; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3309; GFX11-NEXT: v_fract_f32_e32 v3, v03310; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3311; GFX11-NEXT: v_floor_f32_e32 v4, v03312; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)3313; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3314; GFX11-NEXT: global_store_b32 v[1:2], v4, off3315; GFX11-NEXT: s_setpc_b64 s[30:31]3316;3317; GFX12-LABEL: safe_math_fract_f32_minimumnum:3318; GFX12: ; %bb.0: ; %entry3319; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03320; GFX12-NEXT: s_wait_expcnt 0x03321; GFX12-NEXT: s_wait_samplecnt 0x03322; GFX12-NEXT: s_wait_bvhcnt 0x03323; GFX12-NEXT: s_wait_kmcnt 0x03324; GFX12-NEXT: v_fract_f32_e32 v3, v03325; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3326; GFX12-NEXT: v_floor_f32_e32 v4, v03327; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)3328; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)3329; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3330; GFX12-NEXT: global_store_b32 v[1:2], v4, off3331; GFX12-NEXT: s_setpc_b64 s[30:31]3332entry:3333 %floor = tail call float @llvm.floor.f32(float %x)3334 %sub = fsub float %x, %floor3335 %min = tail call float @llvm.minimumnum.f32(float %sub, float 0x3FEFFFFFE0000000)3336 %uno = fcmp uno float %x, 0.000000e+003337 %cond = select i1 %uno, float %x, float %min3338 %fabs = tail call float @llvm.fabs.f32(float %x)3339 %cmpinf = fcmp oeq float %fabs, 0x7FF00000000000003340 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond3341 store float %floor, ptr addrspace(1) %ip, align 43342 ret float %cond63343}3344 3345define float @safe_math_fract_f32_minimumnum_swap(float %x, ptr addrspace(1) writeonly captures(none) %ip) {3346; GFX6-IR-LABEL: define float @safe_math_fract_f32_minimumnum_swap(3347; GFX6-IR-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3348; GFX6-IR-NEXT: [[ENTRY:.*:]]3349; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3350; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3351; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimumnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3352; GFX6-IR-NEXT: [[UNO:%.*]] = fcmp ord float [[X]], 0.000000e+003353; GFX6-IR-NEXT: [[COND:%.*]] = select i1 [[UNO]], float [[MIN]], float [[X]]3354; GFX6-IR-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3355; GFX6-IR-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003356; GFX6-IR-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3357; GFX6-IR-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43358; GFX6-IR-NEXT: ret float [[COND6]]3359;3360; IR-FRACT-LABEL: define float @safe_math_fract_f32_minimumnum_swap(3361; IR-FRACT-SAME: float [[X:%.*]], ptr addrspace(1) writeonly captures(none) [[IP:%.*]]) #[[ATTR0]] {3362; IR-FRACT-NEXT: [[ENTRY:.*:]]3363; IR-FRACT-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3364; IR-FRACT-NEXT: [[COND:%.*]] = call float @llvm.amdgcn.fract.f32(float [[X]])3365; IR-FRACT-NEXT: [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])3366; IR-FRACT-NEXT: [[CMPINF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000003367; IR-FRACT-NEXT: [[COND6:%.*]] = select i1 [[CMPINF]], float 0.000000e+00, float [[COND]]3368; IR-FRACT-NEXT: store float [[FLOOR]], ptr addrspace(1) [[IP]], align 43369; IR-FRACT-NEXT: ret float [[COND6]]3370;3371; GFX6-LABEL: safe_math_fract_f32_minimumnum_swap:3372; GFX6: ; %bb.0: ; %entry3373; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3374; GFX6-NEXT: v_floor_f32_e32 v3, v03375; GFX6-NEXT: v_sub_f32_e32 v4, v0, v33376; GFX6-NEXT: v_min_f32_e32 v4, 0x3f7fffff, v43377; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v03378; GFX6-NEXT: s_mov_b32 s8, 0x7f8000003379; GFX6-NEXT: s_mov_b32 s6, 03380; GFX6-NEXT: v_cndmask_b32_e32 v4, v0, v4, vcc3381; GFX6-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83382; GFX6-NEXT: s_mov_b32 s7, 0xf0003383; GFX6-NEXT: s_mov_b32 s4, s63384; GFX6-NEXT: s_mov_b32 s5, s63385; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3386; GFX6-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643387; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0)3388; GFX6-NEXT: s_setpc_b64 s[30:31]3389;3390; GFX7-LABEL: safe_math_fract_f32_minimumnum_swap:3391; GFX7: ; %bb.0: ; %entry3392; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3393; GFX7-NEXT: s_mov_b32 s8, 0x7f8000003394; GFX7-NEXT: s_mov_b32 s6, 03395; GFX7-NEXT: v_fract_f32_e32 v4, v03396; GFX7-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s83397; GFX7-NEXT: s_mov_b32 s7, 0xf0003398; GFX7-NEXT: s_mov_b32 s4, s63399; GFX7-NEXT: s_mov_b32 s5, s63400; GFX7-NEXT: v_floor_f32_e32 v3, v03401; GFX7-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3402; GFX7-NEXT: buffer_store_dword v3, v[1:2], s[4:7], 0 addr643403; GFX7-NEXT: s_waitcnt vmcnt(0)3404; GFX7-NEXT: s_setpc_b64 s[30:31]3405;3406; GFX8-LABEL: safe_math_fract_f32_minimumnum_swap:3407; GFX8: ; %bb.0: ; %entry3408; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3409; GFX8-NEXT: s_mov_b32 s4, 0x7f8000003410; GFX8-NEXT: v_fract_f32_e32 v4, v03411; GFX8-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s43412; GFX8-NEXT: v_floor_f32_e32 v3, v03413; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v4, vcc3414; GFX8-NEXT: global_store_dword v[1:2], v3, off3415; GFX8-NEXT: s_waitcnt vmcnt(0)3416; GFX8-NEXT: s_setpc_b64 s[30:31]3417;3418; GFX11-LABEL: safe_math_fract_f32_minimumnum_swap:3419; GFX11: ; %bb.0: ; %entry3420; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3421; GFX11-NEXT: v_fract_f32_e32 v3, v03422; GFX11-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3423; GFX11-NEXT: v_floor_f32_e32 v4, v03424; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3)3425; GFX11-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3426; GFX11-NEXT: global_store_b32 v[1:2], v4, off3427; GFX11-NEXT: s_setpc_b64 s[30:31]3428;3429; GFX12-LABEL: safe_math_fract_f32_minimumnum_swap:3430; GFX12: ; %bb.0: ; %entry3431; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03432; GFX12-NEXT: s_wait_expcnt 0x03433; GFX12-NEXT: s_wait_samplecnt 0x03434; GFX12-NEXT: s_wait_bvhcnt 0x03435; GFX12-NEXT: s_wait_kmcnt 0x03436; GFX12-NEXT: v_fract_f32_e32 v3, v03437; GFX12-NEXT: v_cmp_neq_f32_e64 vcc_lo, 0x7f800000, |v0|3438; GFX12-NEXT: v_floor_f32_e32 v4, v03439; GFX12-NEXT: s_wait_alu depctr_va_vcc(0)3440; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_3)3441; GFX12-NEXT: v_cndmask_b32_e32 v0, 0, v3, vcc_lo3442; GFX12-NEXT: global_store_b32 v[1:2], v4, off3443; GFX12-NEXT: s_setpc_b64 s[30:31]3444entry:3445 %floor = tail call float @llvm.floor.f32(float %x)3446 %sub = fsub float %x, %floor3447 %min = tail call float @llvm.minimumnum.f32(float %sub, float 0x3FEFFFFFE0000000)3448 %uno = fcmp ord float %x, 0.000000e+003449 %cond = select i1 %uno, float %min, float %x3450 %fabs = tail call float @llvm.fabs.f32(float %x)3451 %cmpinf = fcmp oeq float %fabs, 0x7FF00000000000003452 %cond6 = select i1 %cmpinf, float 0.000000e+00, float %cond3453 store float %floor, ptr addrspace(1) %ip, align 43454 ret float %cond63455}3456 3457define float @basic_fract_f32_nonans_minimumnum(float nofpclass(nan) %x) {3458; GFX6-IR-LABEL: define float @basic_fract_f32_nonans_minimumnum(3459; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {3460; GFX6-IR-NEXT: [[ENTRY:.*:]]3461; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3462; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3463; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimumnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3464; GFX6-IR-NEXT: ret float [[MIN]]3465;3466; IR-FRACT-LABEL: define float @basic_fract_f32_nonans_minimumnum(3467; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {3468; IR-FRACT-NEXT: [[ENTRY:.*:]]3469; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])3470; IR-FRACT-NEXT: ret float [[MIN]]3471;3472; GFX6-LABEL: basic_fract_f32_nonans_minimumnum:3473; GFX6: ; %bb.0: ; %entry3474; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3475; GFX6-NEXT: v_floor_f32_e32 v1, v03476; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13477; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03478; GFX6-NEXT: s_setpc_b64 s[30:31]3479;3480; GFX7-LABEL: basic_fract_f32_nonans_minimumnum:3481; GFX7: ; %bb.0: ; %entry3482; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3483; GFX7-NEXT: v_fract_f32_e32 v0, v03484; GFX7-NEXT: s_setpc_b64 s[30:31]3485;3486; GFX8-LABEL: basic_fract_f32_nonans_minimumnum:3487; GFX8: ; %bb.0: ; %entry3488; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3489; GFX8-NEXT: v_fract_f32_e32 v0, v03490; GFX8-NEXT: s_setpc_b64 s[30:31]3491;3492; GFX11-LABEL: basic_fract_f32_nonans_minimumnum:3493; GFX11: ; %bb.0: ; %entry3494; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3495; GFX11-NEXT: v_fract_f32_e32 v0, v03496; GFX11-NEXT: s_setpc_b64 s[30:31]3497;3498; GFX12-LABEL: basic_fract_f32_nonans_minimumnum:3499; GFX12: ; %bb.0: ; %entry3500; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03501; GFX12-NEXT: s_wait_expcnt 0x03502; GFX12-NEXT: s_wait_samplecnt 0x03503; GFX12-NEXT: s_wait_bvhcnt 0x03504; GFX12-NEXT: s_wait_kmcnt 0x03505; GFX12-NEXT: v_fract_f32_e32 v0, v03506; GFX12-NEXT: s_setpc_b64 s[30:31]3507entry:3508 %floor = tail call float @llvm.floor.f32(float %x)3509 %sub = fsub float %x, %floor3510 %min = tail call float @llvm.minimumnum.f32(float %sub, float 0x3FEFFFFFE0000000)3511 ret float %min3512}3513 3514define float @basic_fract_f32_nonans_minimum(float nofpclass(nan) %x) {3515; GFX6-IR-LABEL: define float @basic_fract_f32_nonans_minimum(3516; GFX6-IR-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {3517; GFX6-IR-NEXT: [[ENTRY:.*:]]3518; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3519; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3520; GFX6-IR-NEXT: [[MIN:%.*]] = tail call float @llvm.minimum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3521; GFX6-IR-NEXT: ret float [[MIN]]3522;3523; IR-FRACT-LABEL: define float @basic_fract_f32_nonans_minimum(3524; IR-FRACT-SAME: float nofpclass(nan) [[X:%.*]]) #[[ATTR0]] {3525; IR-FRACT-NEXT: [[ENTRY:.*:]]3526; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])3527; IR-FRACT-NEXT: ret float [[MIN]]3528;3529; GFX6-LABEL: basic_fract_f32_nonans_minimum:3530; GFX6: ; %bb.0: ; %entry3531; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3532; GFX6-NEXT: v_floor_f32_e32 v1, v03533; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13534; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v03535; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc000003536; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v03537; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc3538; GFX6-NEXT: s_setpc_b64 s[30:31]3539;3540; GFX7-LABEL: basic_fract_f32_nonans_minimum:3541; GFX7: ; %bb.0: ; %entry3542; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3543; GFX7-NEXT: v_fract_f32_e32 v0, v03544; GFX7-NEXT: s_setpc_b64 s[30:31]3545;3546; GFX8-LABEL: basic_fract_f32_nonans_minimum:3547; GFX8: ; %bb.0: ; %entry3548; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3549; GFX8-NEXT: v_fract_f32_e32 v0, v03550; GFX8-NEXT: s_setpc_b64 s[30:31]3551;3552; GFX11-LABEL: basic_fract_f32_nonans_minimum:3553; GFX11: ; %bb.0: ; %entry3554; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3555; GFX11-NEXT: v_fract_f32_e32 v0, v03556; GFX11-NEXT: s_setpc_b64 s[30:31]3557;3558; GFX12-LABEL: basic_fract_f32_nonans_minimum:3559; GFX12: ; %bb.0: ; %entry3560; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03561; GFX12-NEXT: s_wait_expcnt 0x03562; GFX12-NEXT: s_wait_samplecnt 0x03563; GFX12-NEXT: s_wait_bvhcnt 0x03564; GFX12-NEXT: s_wait_kmcnt 0x03565; GFX12-NEXT: v_fract_f32_e32 v0, v03566; GFX12-NEXT: s_setpc_b64 s[30:31]3567entry:3568 %floor = tail call float @llvm.floor.f32(float %x)3569 %sub = fsub float %x, %floor3570 %min = tail call float @llvm.minimum.f32(float %sub, float 0x3FEFFFFFE0000000)3571 ret float %min3572}3573 3574define float @nnan_minimum_fract_f32(float %x) {3575; GFX6-IR-LABEL: define float @nnan_minimum_fract_f32(3576; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {3577; GFX6-IR-NEXT: [[ENTRY:.*:]]3578; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3579; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3580; GFX6-IR-NEXT: [[MIN:%.*]] = tail call nnan float @llvm.minimum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3581; GFX6-IR-NEXT: ret float [[MIN]]3582;3583; IR-FRACT-LABEL: define float @nnan_minimum_fract_f32(3584; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {3585; IR-FRACT-NEXT: [[ENTRY:.*:]]3586; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])3587; IR-FRACT-NEXT: ret float [[MIN]]3588;3589; GFX6-LABEL: nnan_minimum_fract_f32:3590; GFX6: ; %bb.0: ; %entry3591; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3592; GFX6-NEXT: v_floor_f32_e32 v1, v03593; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13594; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03595; GFX6-NEXT: s_setpc_b64 s[30:31]3596;3597; GFX7-LABEL: nnan_minimum_fract_f32:3598; GFX7: ; %bb.0: ; %entry3599; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3600; GFX7-NEXT: v_fract_f32_e32 v0, v03601; GFX7-NEXT: s_setpc_b64 s[30:31]3602;3603; GFX8-LABEL: nnan_minimum_fract_f32:3604; GFX8: ; %bb.0: ; %entry3605; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3606; GFX8-NEXT: v_fract_f32_e32 v0, v03607; GFX8-NEXT: s_setpc_b64 s[30:31]3608;3609; GFX11-LABEL: nnan_minimum_fract_f32:3610; GFX11: ; %bb.0: ; %entry3611; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3612; GFX11-NEXT: v_fract_f32_e32 v0, v03613; GFX11-NEXT: s_setpc_b64 s[30:31]3614;3615; GFX12-LABEL: nnan_minimum_fract_f32:3616; GFX12: ; %bb.0: ; %entry3617; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03618; GFX12-NEXT: s_wait_expcnt 0x03619; GFX12-NEXT: s_wait_samplecnt 0x03620; GFX12-NEXT: s_wait_bvhcnt 0x03621; GFX12-NEXT: s_wait_kmcnt 0x03622; GFX12-NEXT: v_fract_f32_e32 v0, v03623; GFX12-NEXT: s_setpc_b64 s[30:31]3624entry:3625 %floor = tail call float @llvm.floor.f32(float %x)3626 %sub = fsub float %x, %floor3627 %min = tail call nnan float @llvm.minimum.f32(float %sub, float 0x3FEFFFFFE0000000)3628 ret float %min3629}3630 3631define float @nnan_minimumnum_fract_f32(float %x) {3632; GFX6-IR-LABEL: define float @nnan_minimumnum_fract_f32(3633; GFX6-IR-SAME: float [[X:%.*]]) #[[ATTR0]] {3634; GFX6-IR-NEXT: [[ENTRY:.*:]]3635; GFX6-IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3636; GFX6-IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3637; GFX6-IR-NEXT: [[MIN:%.*]] = tail call nnan float @llvm.minimumnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3638; GFX6-IR-NEXT: ret float [[MIN]]3639;3640; IR-FRACT-LABEL: define float @nnan_minimumnum_fract_f32(3641; IR-FRACT-SAME: float [[X:%.*]]) #[[ATTR0]] {3642; IR-FRACT-NEXT: [[ENTRY:.*:]]3643; IR-FRACT-NEXT: [[MIN:%.*]] = call nnan float @llvm.amdgcn.fract.f32(float [[X]])3644; IR-FRACT-NEXT: ret float [[MIN]]3645;3646; GFX6-LABEL: nnan_minimumnum_fract_f32:3647; GFX6: ; %bb.0: ; %entry3648; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3649; GFX6-NEXT: v_floor_f32_e32 v1, v03650; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13651; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03652; GFX6-NEXT: s_setpc_b64 s[30:31]3653;3654; GFX7-LABEL: nnan_minimumnum_fract_f32:3655; GFX7: ; %bb.0: ; %entry3656; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3657; GFX7-NEXT: v_fract_f32_e32 v0, v03658; GFX7-NEXT: s_setpc_b64 s[30:31]3659;3660; GFX8-LABEL: nnan_minimumnum_fract_f32:3661; GFX8: ; %bb.0: ; %entry3662; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3663; GFX8-NEXT: v_fract_f32_e32 v0, v03664; GFX8-NEXT: s_setpc_b64 s[30:31]3665;3666; GFX11-LABEL: nnan_minimumnum_fract_f32:3667; GFX11: ; %bb.0: ; %entry3668; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3669; GFX11-NEXT: v_fract_f32_e32 v0, v03670; GFX11-NEXT: s_setpc_b64 s[30:31]3671;3672; GFX12-LABEL: nnan_minimumnum_fract_f32:3673; GFX12: ; %bb.0: ; %entry3674; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03675; GFX12-NEXT: s_wait_expcnt 0x03676; GFX12-NEXT: s_wait_samplecnt 0x03677; GFX12-NEXT: s_wait_bvhcnt 0x03678; GFX12-NEXT: s_wait_kmcnt 0x03679; GFX12-NEXT: v_fract_f32_e32 v0, v03680; GFX12-NEXT: s_setpc_b64 s[30:31]3681entry:3682 %floor = tail call float @llvm.floor.f32(float %x)3683 %sub = fsub float %x, %floor3684 %min = tail call nnan float @llvm.minimumnum.f32(float %sub, float 0x3FEFFFFFE0000000)3685 ret float %min3686}3687 3688define float @basic_fract_f32_flags_minimumnum(float %x) {3689; IR-LABEL: define float @basic_fract_f32_flags_minimumnum(3690; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {3691; IR-NEXT: [[ENTRY:.*:]]3692; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3693; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3694; IR-NEXT: [[MIN:%.*]] = tail call nsz float @llvm.minimumnum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3695; IR-NEXT: ret float [[MIN]]3696;3697; GFX6-LABEL: basic_fract_f32_flags_minimumnum:3698; GFX6: ; %bb.0: ; %entry3699; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3700; GFX6-NEXT: v_floor_f32_e32 v1, v03701; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13702; GFX6-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03703; GFX6-NEXT: s_setpc_b64 s[30:31]3704;3705; GFX7-LABEL: basic_fract_f32_flags_minimumnum:3706; GFX7: ; %bb.0: ; %entry3707; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3708; GFX7-NEXT: v_floor_f32_e32 v1, v03709; GFX7-NEXT: v_sub_f32_e32 v0, v0, v13710; GFX7-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03711; GFX7-NEXT: s_setpc_b64 s[30:31]3712;3713; GFX8-LABEL: basic_fract_f32_flags_minimumnum:3714; GFX8: ; %bb.0: ; %entry3715; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3716; GFX8-NEXT: v_floor_f32_e32 v1, v03717; GFX8-NEXT: v_sub_f32_e32 v0, v0, v13718; GFX8-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03719; GFX8-NEXT: s_setpc_b64 s[30:31]3720;3721; GFX11-LABEL: basic_fract_f32_flags_minimumnum:3722; GFX11: ; %bb.0: ; %entry3723; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3724; GFX11-NEXT: v_floor_f32_e32 v1, v03725; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)3726; GFX11-NEXT: v_sub_f32_e32 v0, v0, v13727; GFX11-NEXT: v_min_f32_e32 v0, 0x3f7fffff, v03728; GFX11-NEXT: s_setpc_b64 s[30:31]3729;3730; GFX12-LABEL: basic_fract_f32_flags_minimumnum:3731; GFX12: ; %bb.0: ; %entry3732; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03733; GFX12-NEXT: s_wait_expcnt 0x03734; GFX12-NEXT: s_wait_samplecnt 0x03735; GFX12-NEXT: s_wait_bvhcnt 0x03736; GFX12-NEXT: s_wait_kmcnt 0x03737; GFX12-NEXT: v_floor_f32_e32 v1, v03738; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)3739; GFX12-NEXT: v_sub_f32_e32 v0, v0, v13740; GFX12-NEXT: v_min_num_f32_e32 v0, 0x3f7fffff, v03741; GFX12-NEXT: s_setpc_b64 s[30:31]3742entry:3743 %floor = tail call float @llvm.floor.f32(float %x)3744 %sub = fsub float %x, %floor3745 %min = tail call nsz float @llvm.minimumnum.f32(float %sub, float 0x3FEFFFFFE0000000)3746 ret float %min3747}3748 3749define float @basic_fract_f32_flags_minimum(float %x) {3750; IR-LABEL: define float @basic_fract_f32_flags_minimum(3751; IR-SAME: float [[X:%.*]]) #[[ATTR0]] {3752; IR-NEXT: [[ENTRY:.*:]]3753; IR-NEXT: [[FLOOR:%.*]] = tail call float @llvm.floor.f32(float [[X]])3754; IR-NEXT: [[SUB:%.*]] = fsub float [[X]], [[FLOOR]]3755; IR-NEXT: [[MIN:%.*]] = tail call nsz float @llvm.minimum.f32(float [[SUB]], float 0x3FEFFFFFE0000000)3756; IR-NEXT: ret float [[MIN]]3757;3758; GFX6-LABEL: basic_fract_f32_flags_minimum:3759; GFX6: ; %bb.0: ; %entry3760; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3761; GFX6-NEXT: v_floor_f32_e32 v1, v03762; GFX6-NEXT: v_sub_f32_e32 v0, v0, v13763; GFX6-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v03764; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc000003765; GFX6-NEXT: v_cmp_o_f32_e32 vcc, v0, v03766; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc3767; GFX6-NEXT: s_setpc_b64 s[30:31]3768;3769; GFX7-LABEL: basic_fract_f32_flags_minimum:3770; GFX7: ; %bb.0: ; %entry3771; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3772; GFX7-NEXT: v_floor_f32_e32 v1, v03773; GFX7-NEXT: v_sub_f32_e32 v0, v0, v13774; GFX7-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v03775; GFX7-NEXT: v_mov_b32_e32 v2, 0x7fc000003776; GFX7-NEXT: v_cmp_o_f32_e32 vcc, v0, v03777; GFX7-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc3778; GFX7-NEXT: s_setpc_b64 s[30:31]3779;3780; GFX8-LABEL: basic_fract_f32_flags_minimum:3781; GFX8: ; %bb.0: ; %entry3782; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3783; GFX8-NEXT: v_floor_f32_e32 v1, v03784; GFX8-NEXT: v_sub_f32_e32 v0, v0, v13785; GFX8-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v03786; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc000003787; GFX8-NEXT: v_cmp_o_f32_e32 vcc, v0, v03788; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc3789; GFX8-NEXT: s_setpc_b64 s[30:31]3790;3791; GFX11-LABEL: basic_fract_f32_flags_minimum:3792; GFX11: ; %bb.0: ; %entry3793; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)3794; GFX11-NEXT: v_floor_f32_e32 v1, v03795; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)3796; GFX11-NEXT: v_sub_f32_e32 v0, v0, v13797; GFX11-NEXT: v_min_f32_e32 v1, 0x3f7fffff, v03798; GFX11-NEXT: v_cmp_o_f32_e32 vcc_lo, v0, v03799; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)3800; GFX11-NEXT: v_cndmask_b32_e32 v0, 0x7fc00000, v1, vcc_lo3801; GFX11-NEXT: s_setpc_b64 s[30:31]3802;3803; GFX12-LABEL: basic_fract_f32_flags_minimum:3804; GFX12: ; %bb.0: ; %entry3805; GFX12-NEXT: s_wait_loadcnt_dscnt 0x03806; GFX12-NEXT: s_wait_expcnt 0x03807; GFX12-NEXT: s_wait_samplecnt 0x03808; GFX12-NEXT: s_wait_bvhcnt 0x03809; GFX12-NEXT: s_wait_kmcnt 0x03810; GFX12-NEXT: v_floor_f32_e32 v1, v03811; GFX12-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)3812; GFX12-NEXT: v_sub_f32_e32 v0, v0, v13813; GFX12-NEXT: v_minimum_f32 v0, 0x3f7fffff, v03814; GFX12-NEXT: s_setpc_b64 s[30:31]3815entry:3816 %floor = tail call float @llvm.floor.f32(float %x)3817 %sub = fsub float %x, %floor3818 %min = tail call nsz float @llvm.minimum.f32(float %sub, float 0x3FEFFFFFE0000000)3819 ret float %min3820}3821 3822declare half @llvm.floor.f16(half) #03823declare float @llvm.floor.f32(float) #03824declare double @llvm.floor.f64(double) #03825declare <2 x double> @llvm.floor.v2f64(<2 x double>) #03826declare <2 x float> @llvm.floor.v2f32(<2 x float>) #03827declare <2 x half> @llvm.floor.v2f16(<2 x half>) #03828declare float @llvm.trunc.f32(float) #03829declare float @llvm.minnum.f32(float, float) #03830declare half @llvm.minnum.f16(half, half) #03831declare double @llvm.minnum.f64(double, double) #03832declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>) #03833declare <2 x half> @llvm.minnum.v2f16(<2 x half>, <2 x half>) #03834declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>) #03835declare float @llvm.maxnum.f32(float, float) #03836declare float @llvm.fabs.f32(float) #03837declare double @llvm.fabs.f64(double) #03838declare <2 x float> @llvm.fabs.v2f32(<2 x float>) #03839declare half @llvm.fabs.f16(half) #03840declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #03841declare <2 x double> @llvm.fabs.v2f64(<2 x double>) #03842 3843attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }3844