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