| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a < %s | FileCheck %s |
| |
| define i32 @select.hi32.sgpr.oeq(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.oeq: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s17, 31 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_eq_u32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.oeq.multiuse(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) { |
| ; CHECK-LABEL: select.hi32.sgpr.oeq.multiuse: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s17, 31 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_eq_u32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: s_cselect_b32 s5, s22, s23 |
| ; CHECK-NEXT: s_add_i32 s4, s4, s5 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ab = select i1 %cmp, i32 %a, i32 %b |
| %cd = select i1 %cmp, i32 %c, i32 %d |
| %ret = add i32 %ab, %cd |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.oeq.bad.zero(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.oeq.bad.zero: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s19, 30 |
| ; CHECK-NEXT: s_mov_b32 s16, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, s[16:17], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xffffffff00000000 |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xbfffffff00000000 ; cannot be NaN |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked ; may compare +0 and -0 |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.oeq.bad.nan(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.oeq.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_mov_b32 s16, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, s[16:17], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xffffffff00000000 |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xffffffff00000000 |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ueq(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ueq: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_eq_u32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ueq.bad.zero(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ueq.bad.zero: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s19, 30 |
| ; CHECK-NEXT: s_and_b32 s5, s17, 0xbfffffff |
| ; CHECK-NEXT: s_mov_b32 s4, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, s[4:5], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xbfffffff00000000 ; cannot be NaN |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xbfffffff00000000 ; cannot be NaN |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked ; may compare +0 and -0 |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ueq.bad.nan(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ueq.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_and_b32 s5, s17, 0xbfffffff |
| ; CHECK-NEXT: s_mov_b32 s4, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_nlg_f64_e32 vcc, s[4:5], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xbfffffff00000000 ; cannot be NaN |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xffffffff00000000 |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.olt.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.olt.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s17, 31 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_lt_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp olt double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.olt.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.olt.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s17, 31 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_le_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.i64.bump = or i64 %y.i64.masked, 1 |
| %y.masked = bitcast i64 %y.i64.bump to double |
| %cmp = fcmp olt double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.olt.bad.neg(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.olt.bad.neg: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_and_b32 s4, s19, 0x8fffffff |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s4 |
| ; CHECK-NEXT: v_cmp_lt_f64_e64 s[4:5], |s[16:17]|, v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], s[4:5], exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x8fffffff00000000 ; cannot be NaN, may be negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp olt double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.olt.bad.nan(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.olt.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s18 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_lt_f64_e64 s[4:5], |s[16:17]|, |v[0:1]| |
| ; CHECK-NEXT: s_and_b64 s[4:5], s[4:5], exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.abs = call double @llvm.fabs(double %y) ; may be NaN |
| %cmp = fcmp olt double %x.abs, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ult.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ult.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_lt_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ult.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ult.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_le_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.i64.bump = or i64 %y.i64.masked, 1 |
| %y.masked = bitcast i64 %y.i64.bump to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ult.bad.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ult.bad.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_nge_f64_e64 s[4:5], |s[16:17]|, v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], s[4:5], exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ult.bad.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ult.bad.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_bitset0_b32 s19, 31 |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_nge_f64_e32 vcc, s[16:17], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x7fffffff00000000 ; cannot be negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| |
| define i32 @select.hi32.sgpr.ole.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ole.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_le_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ole.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ole.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_cmp_lt_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.i64.bump = or i64 %x.i64.masked, 1 |
| %x.masked = bitcast i64 %x.i64.bump to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ole.bad.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ole.bad.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s19, s19, -2.0 |
| ; CHECK-NEXT: s_and_b32 s5, s17, 0x7fffffff |
| ; CHECK-NEXT: s_mov_b32 s4, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s18 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_le_f64_e32 vcc, s[4:5], v[0:1] |
| ; CHECK-NEXT: s_and_b64 s[4:5], vcc, exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ole.bad.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ole.bad.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s18 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: s_and_b32 s5, s17, 0x3fffffff |
| ; CHECK-NEXT: s_mov_b32 s4, 0 |
| ; CHECK-NEXT: v_cmp_le_f64_e64 s[4:5], s[4:5], |v[0:1]| |
| ; CHECK-NEXT: s_and_b64 s[4:5], s[4:5], exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ole double %x.masked, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ule.0(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ule.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_bitset0_b32 s19, 31 |
| ; CHECK-NEXT: s_cmp_le_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ule double %x.masked, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ule.1(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ule.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: s_andn2_b32 s17, s17, -2.0 |
| ; CHECK-NEXT: s_bitset0_b32 s19, 31 |
| ; CHECK-NEXT: s_cmp_lt_i32 s17, s19 |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.i64.bump = or i64 %x.i64.masked, 1 |
| %x.masked = bitcast i64 %x.i64.bump to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x7fffffff00000000 ; cannot negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ule double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.sgpr.ule.bad(double inreg %x, double inreg %y, i32 inreg %a, i32 inreg %b) { |
| ; CHECK-LABEL: select.hi32.sgpr.ule.bad: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s18 |
| ; CHECK-NEXT: v_mov_b32_e32 v1, s19 |
| ; CHECK-NEXT: v_cmp_ngt_f64_e64 s[4:5], |s[16:17]|, |v[0:1]| |
| ; CHECK-NEXT: s_and_b64 s[4:5], s[4:5], exec |
| ; CHECK-NEXT: s_cselect_b32 s4, s20, s21 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, s4 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ule double %x.abs, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.oeq(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.oeq: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_eq_u32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.oeq.multiuse(double %x, double %y, i32 %a, i32 %b, i32 %c, i32 %d) { |
| ; CHECK-LABEL: select.hi32.vgpr.oeq.multiuse: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_eq_u32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: v_cndmask_b32_e32 v1, v7, v6, vcc |
| ; CHECK-NEXT: v_add_u32_e32 v0, v0, v1 |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ab = select i1 %cmp, i32 %a, i32 %b |
| %cd = select i1 %cmp, i32 %c, i32 %d |
| %ret = add i32 %ab, %cd |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.oeq.bad.zero(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.oeq.bad.zero: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0xbfffffff, v3 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, v0 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xffffffff00000000 |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xbfffffff00000000 ; cannot be NaN |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked ; may compare +0 and -0 |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.oeq.bad.nan(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.oeq.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, v0 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xffffffff00000000 |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xffffffff00000000 |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp oeq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ueq(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ueq: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_eq_u32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ueq.bad.zero(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ueq.bad.zero: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0xbfffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0xbfffffff, v3 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, v0 |
| ; CHECK-NEXT: v_cmp_eq_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xbfffffff00000000 ; cannot be NaN |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xbfffffff00000000 ; cannot be NaN |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked ; may compare +0 and -0 |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ueq.bad.nan(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ueq.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0xbfffffff, v1 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, v0 |
| ; CHECK-NEXT: v_cmp_nlg_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0xbfffffff00000000 ; cannot be NaN |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0xffffffff00000000 |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ueq double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.olt.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.olt.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_lt_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp olt double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.olt.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.olt.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_le_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.i64.bump = or i64 %y.i64.masked, 1 |
| %y.masked = bitcast i64 %y.i64.bump to double |
| %cmp = fcmp olt double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.olt.bad.neg(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.olt.bad.neg: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0x8fffffff, v3 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, 0 |
| ; CHECK-NEXT: v_cmp_lt_f64_e64 vcc, |v[0:1]|, v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x8fffffff00000000 ; cannot be NaN, may be negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp olt double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.olt.bad.nan(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.olt.bad.nan: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_cmp_lt_f64_e64 vcc, |v[0:1]|, |v[2:3]| |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.abs = call double @llvm.fabs(double %y) ; may be NaN |
| %cmp = fcmp olt double %x.abs, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ult.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ult.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_lt_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ult.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ult.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_le_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.i64.bump = or i64 %y.i64.masked, 1 |
| %y.masked = bitcast i64 %y.i64.bump to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ult.bad.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ult.bad.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, 0 |
| ; CHECK-NEXT: v_cmp_nge_f64_e64 vcc, |v[0:1]|, v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.abs, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ult.bad.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ult.bad.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0x7fffffff, v3 |
| ; CHECK-NEXT: v_mov_b32_e32 v2, 0 |
| ; CHECK-NEXT: v_cmp_nge_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x7fffffff00000000 ; cannot be negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ult double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| |
| define i32 @select.hi32.vgpr.ole.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ole.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_le_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ole.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ole.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_lt_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.i64.bump = or i64 %x.i64.masked, 1 |
| %x.masked = bitcast i64 %x.i64.bump to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ole.bad.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ole.bad.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_and_b32_e32 v3, 0x3fffffff, v3 |
| ; CHECK-NEXT: v_cmp_le_f64_e32 vcc, v[0:1], v[2:3] |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x7fffffff00000000 ; cannot be negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x3fffffffffffffff ; cannot be NaN or negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ole double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ole.bad.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ole.bad.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_mov_b32_e32 v0, 0 |
| ; CHECK-NEXT: v_cmp_le_f64_e64 vcc, v[0:1], |v[2:3]| |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ole double %x.masked, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ule.0(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ule.0: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x7fffffff, v3 |
| ; CHECK-NEXT: v_cmp_le_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.masked = bitcast i64 %x.i64.masked to double |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ule double %x.masked, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ule.1(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ule.1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_and_b32_e32 v0, 0x3fffffff, v1 |
| ; CHECK-NEXT: v_and_b32_e32 v1, 0x7fffffff, v3 |
| ; CHECK-NEXT: v_cmp_lt_i32_e32 vcc, v0, v1 |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.i64 = bitcast double %x to i64 |
| %x.i64.masked = and i64 %x.i64, u0x3fffffff00000000 ; cannot be NaN or negative |
| %x.i64.bump = or i64 %x.i64.masked, 1 |
| %x.masked = bitcast i64 %x.i64.bump to double |
| %y.i64 = bitcast double %y to i64 |
| %y.i64.masked = and i64 %y.i64, u0x7fffffff00000000 ; cannot negative |
| %y.masked = bitcast i64 %y.i64.masked to double |
| %cmp = fcmp ule double %x.masked, %y.masked |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |
| |
| define i32 @select.hi32.vgpr.ule.bad(double %x, double %y, i32 %a, i32 %b) { |
| ; CHECK-LABEL: select.hi32.vgpr.ule.bad: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) |
| ; CHECK-NEXT: v_cmp_ngt_f64_e64 vcc, |v[0:1]|, |v[2:3]| |
| ; CHECK-NEXT: v_cndmask_b32_e32 v0, v5, v4, vcc |
| ; CHECK-NEXT: s_setpc_b64 s[30:31] |
| %x.abs = call double @llvm.fabs(double %x) ; cannot be negative |
| %y.abs = call double @llvm.fabs(double %y) ; cannot be negative |
| %cmp = fcmp ule double %x.abs, %y.abs |
| %ret = select i1 %cmp, i32 %a, i32 %b |
| ret i32 %ret |
| } |