; 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 }