[llvm] [AMDGPU][SDAG] Support source modifiers on select integer operands (PR #147325)

Chris Jackson via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 11 10:27:23 PDT 2025


https://github.com/chrisjbris updated https://github.com/llvm/llvm-project/pull/147325

>From 470be6180f971bc55d5b0384d6178a55ced366b7 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Wed, 2 Jul 2025 04:39:04 -0500
Subject: [PATCH 01/17] Add new test for source modifiers on select

---
 .../AMDGPU/integer-select-source-modifiers.ll | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll

diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
new file mode 100644
index 0000000000000..6e7ff16b74139
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -0,0 +1,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GCN,GFX7 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GCN,GFX9 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-TRUE16 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-FAKE16 %s
+
+define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
+  %neg.a = xor i32 %a, u0x80000000
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %neg.a, i32 %b
+  ret i32 %select
+}
+
+define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+  %neg.a = xor <2 x i32> %a, splat (i32 u0x80000000)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
+  ret <2 x i32> %select
+}
+
+define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
+  %neg.a = and i32 %a, u0x7fffffff
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %neg.a, i32 %b
+  ret i32 %select
+}
+
+define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+  %neg.a = and <2 x i32> %a, splat (i32 u0x7fffffff)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
+  ret <2 x i32> %select
+}
+
+define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
+  %neg.a = or i32 %a, u0x80000000
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %neg.a, i32 %b
+  ret i32 %select
+}
+
+define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+  %neg.a = or <2 x i32> %a, splat (i32 u0x80000000)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
+  ret <2 x i32> %select
+}
+
+define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
+  %neg.a = xor i64 %a, u0x8000000000000000
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %neg.a, i64 %b
+  ret i64 %select
+}
+
+define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
+  %neg.a = and i64 %a, u0x7fffffffffffffff
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %neg.a, i64 %b
+  ret i64 %select
+}
+
+define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
+  %neg.a = or i64 %a, u0x8000000000000000
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %neg.a, i64 %b
+  ret i64 %select
+}

>From c1c30eae41afc94ec16207158741eaaac7e9edd5 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Wed, 2 Jul 2025 04:40:36 -0500
Subject: [PATCH 02/17] Populate check-lines before patching

---
 .../AMDGPU/integer-select-source-modifiers.ll | 170 ++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index 6e7ff16b74139..dd6cf9bc6c592 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -5,6 +5,22 @@
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-FAKE16 %s
 
 define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
+; GCN-LABEL: fneg_select_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_xor_b32_e32 v1, 0x80000000, v1
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v1
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i32 %a, u0x80000000
   %cmp = icmp eq i32 %cond, zeroinitializer
   %select = select i1 %cmp, i32 %neg.a, i32 %b
@@ -12,6 +28,28 @@ define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GCN-LABEL: fneg_select_v2i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_xor_b32_e32 v2, 0x80000000, v2
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_v2i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_xor_b32_e32 v2, 0x80000000, v2
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor <2 x i32> %a, splat (i32 u0x80000000)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer
   %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
@@ -19,6 +57,22 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 }
 
 define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
+; GCN-LABEL: fabs_select_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v1
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v1
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and i32 %a, u0x7fffffff
   %cmp = icmp eq i32 %cond, zeroinitializer
   %select = select i1 %cmp, i32 %neg.a, i32 %b
@@ -26,6 +80,28 @@ define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GCN-LABEL: fabs_select_v2i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_and_b32_e32 v2, 0x7fffffff, v2
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_v2i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GFX11-NEXT:    v_and_b32_e32 v2, 0x7fffffff, v2
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and <2 x i32> %a, splat (i32 u0x7fffffff)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer
   %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
@@ -33,6 +109,22 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 }
 
 define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
+; GCN-LABEL: fneg_fabs_select_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or i32 %a, u0x80000000
   %cmp = icmp eq i32 %cond, zeroinitializer
   %select = select i1 %cmp, i32 %neg.a, i32 %b
@@ -40,6 +132,28 @@ define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GCN-LABEL: fneg_fabs_select_v2i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_v2i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or <2 x i32> %a, splat (i32 u0x80000000)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer
   %select = select <2 x i1> %cmp, <2 x i32> %neg.a, <2 x i32> %b
@@ -47,6 +161,23 @@ define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32
 }
 
 define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
+; GCN-LABEL: fneg_select_i64:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_i64:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_cndmask_b32 v1, v5, v1
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer
   %select = select i1 %cmp, i64 %neg.a, i64 %b
@@ -54,6 +185,23 @@ define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
+; GCN-LABEL: fabs_select_i64:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_i64:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_and_b32 v1, 0x7fffffff, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and i64 %a, u0x7fffffffffffffff
   %cmp = icmp eq i64 %cond, zeroinitializer
   %select = select i1 %cmp, i64 %neg.a, i64 %b
@@ -61,8 +209,30 @@ define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
+; GCN-LABEL: fneg_fabs_select_i64:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_i64:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_cndmask_b32 v1, v5, v1
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer
   %select = select i1 %cmp, i64 %neg.a, i64 %b
   ret i64 %select
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; GFX11-FAKE16: {{.*}}
+; GFX11-TRUE16: {{.*}}
+; GFX7: {{.*}}
+; GFX9: {{.*}}

>From 85032f2284d2d619b71af6c365b053e1fafba98e Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 10:12:45 -0500
Subject: [PATCH 03/17] [AMDGPU][SDAG] Support source modifiers as integer on
 select

Extend the DAGCombine() for select to directly support fneg and fabs
for i32, v2i32 and i64.
---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 77 ++++++++++++++++++-
 .../AMDGPU/integer-select-source-modifiers.ll | 40 +++-------
 2 files changed, 86 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index e32accaba85fc..bec86877e1705 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4830,6 +4830,64 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
   return SDValue();
 }
 
+static EVT IntToFloatVT(EVT VT) {
+  return VT = VT.isVector() ? MVT::getVectorVT(MVT::getFloatingPointVT(
+                                                   VT.getScalarSizeInBits()),
+                                               VT.getVectorNumElements())
+                            : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
+}
+
+static SDValue BitwiseToSrcModifierOp(SDValue N,
+                                      TargetLowering::DAGCombinerInfo &DCI) {
+
+  unsigned Opc = N.getNode()->getOpcode();
+  if (Opc != ISD::AND && Opc != ISD::XOR && Opc != ISD::AND)
+    return SDValue();
+
+  SelectionDAG &DAG = DCI.DAG;
+  SDValue LHS = N.getNode()->getOperand(0);
+  SDValue RHS = N.getNode()->getOperand(1);
+  ConstantSDNode *CRHS = isConstOrConstSplat(RHS);
+
+  if (!CRHS)
+    return SDValue();
+
+  EVT VT = RHS.getValueType();
+
+  assert((VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) &&
+         "Expected i32, v2i32 or i64 value type.");
+
+  uint64_t Mask = 0;
+  if (VT.isVector()) {
+    SDValue Splat = DAG.getSplatValue(RHS);
+    const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Splat);
+    Mask = C->getZExtValue();
+  } else
+    Mask = CRHS->getZExtValue();
+
+  EVT FVT = IntToFloatVT(VT);
+  SDValue BC = DAG.getNode(ISD::BITCAST, SDLoc(N), FVT, LHS);
+
+  switch (Opc) {
+  case ISD::XOR:
+    if (Mask == 0x80000000u || Mask == 0x8000000000000000u)
+      return DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
+    return SDValue();
+  case ISD::OR:
+    if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
+      SDValue Abs = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
+      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, Abs);
+    }
+    return SDValue();
+  case ISD::AND:
+    if (Mask == 0x7fffffffu || Mask == 0x7fffffffffffffffu)
+      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, BC);
+    return SDValue();
+  default:
+    return SDValue();
+  }
+}
+
 SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
                                                    DAGCombinerInfo &DCI) const {
   if (SDValue Folded = foldFreeOpFromSelect(DCI, SDValue(N, 0)))
@@ -4864,12 +4922,25 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
     }
 
     if (VT == MVT::f32 && Subtarget->hasFminFmaxLegacy()) {
-      SDValue MinMax
-        = combineFMinMaxLegacy(SDLoc(N), VT, LHS, RHS, True, False, CC, DCI);
+      SDValue MinMax =
+          combineFMinMaxLegacy(SDLoc(N), VT, LHS, RHS, True, False, CC, DCI);
       // Revisit this node so we can catch min3/max3/med3 patterns.
-      //DCI.AddToWorklist(MinMax.getNode());
+      // DCI.AddToWorklist(MinMax.getNode());
       return MinMax;
     }
+
+    // Support source modifiers as integer.
+    if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
+      SDLoc SL(N);
+      SDValue LHS = N->getOperand(1);
+      SDValue RHS = N->getOperand(2);
+      if (SDValue SrcMod = BitwiseToSrcModifierOp(LHS, DCI)) {
+        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, VT, RHS);
+        SDValue FSelect = DAG.getNode(ISD::SELECT, SL, VT, Cond, SrcMod, FRHS);
+        SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
+        return BC;
+      }
+    }
   }
 
   // There's no reason to not do this if the condition has other uses.
diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index dd6cf9bc6c592..2db20e672c303 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -8,18 +8,15 @@ define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-LABEL: fneg_select_i32:
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_xor_b32_e32 v1, 0x80000000, v1
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v1
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i32 %a, u0x80000000
   %cmp = icmp eq i32 %cond, zeroinitializer
@@ -31,24 +28,19 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GCN-LABEL: fneg_select_v2i32:
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_xor_b32_e32 v2, 0x80000000, v2
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_v2i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    v_xor_b32_e32 v2, 0x80000000, v2
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc_lo
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor <2 x i32> %a, splat (i32 u0x80000000)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer
@@ -60,18 +52,15 @@ define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-LABEL: fabs_select_i32:
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v1
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    v_and_b32_e32 v1, 0x7fffffff, v1
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and i32 %a, u0x7fffffff
   %cmp = icmp eq i32 %cond, zeroinitializer
@@ -83,24 +72,19 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GCN-LABEL: fabs_select_v2i32:
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_and_b32_e32 v2, 0x7fffffff, v2
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_v2i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GFX11-NEXT:    v_and_b32_e32 v2, 0x7fffffff, v2
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_4)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc_lo
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and <2 x i32> %a, splat (i32 u0x7fffffff)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer

>From 9b486bc549f00efe7157d6f729216a67838c835e Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 10:32:27 -0500
Subject: [PATCH 04/17] Simplify switch in BitwiseToSrcModifierOp()

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index bec86877e1705..d0b1ecbe5ec13 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4872,20 +4872,21 @@ static SDValue BitwiseToSrcModifierOp(SDValue N,
   case ISD::XOR:
     if (Mask == 0x80000000u || Mask == 0x8000000000000000u)
       return DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
-    return SDValue();
+    break;
   case ISD::OR:
     if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
       SDValue Abs = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
       return DAG.getNode(ISD::FABS, SDLoc(N), FVT, Abs);
     }
-    return SDValue();
+    break;
   case ISD::AND:
     if (Mask == 0x7fffffffu || Mask == 0x7fffffffffffffffu)
       return DAG.getNode(ISD::FABS, SDLoc(N), FVT, BC);
-    return SDValue();
+    break;
   default:
     return SDValue();
   }
+  return SDValue();
 }
 
 SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,

>From ba276e39fa57527499c942fdb4ab6d85e0d06b26 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 10:46:53 -0500
Subject: [PATCH 05/17] [NFC] Correct typo in BitwiseToSrcModifierOp()

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index d0b1ecbe5ec13..2ada636d8d2c7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4875,8 +4875,8 @@ static SDValue BitwiseToSrcModifierOp(SDValue N,
     break;
   case ISD::OR:
     if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
-      SDValue Abs = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
-      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, Abs);
+      SDValue Neg = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
+      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, Neg);
     }
     break;
   case ISD::AND:

>From d5cf4e1d2d45609ea2a08500e1df644ad9836b6f Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 11:11:31 -0500
Subject: [PATCH 06/17] Fix bitcast type in performSelectCombine()

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 2ada636d8d2c7..fcd3628209312 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4931,13 +4931,15 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
     }
 
     // Support source modifiers as integer.
+    // (select c, (xor/or/and x, c), y) -> (bitcast (select c)))
     if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
       SDLoc SL(N);
       SDValue LHS = N->getOperand(1);
       SDValue RHS = N->getOperand(2);
       if (SDValue SrcMod = BitwiseToSrcModifierOp(LHS, DCI)) {
-        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, VT, RHS);
-        SDValue FSelect = DAG.getNode(ISD::SELECT, SL, VT, Cond, SrcMod, FRHS);
+        EVT FVT = IntToFloatVT(VT);
+        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, FVT, RHS);
+        SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, SrcMod, FRHS);
         SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
         return BC;
       }

>From 32b6dd651132af560c0803515cd240f53d76031c Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 11:31:26 -0500
Subject: [PATCH 07/17] Respond to first review comments

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 30 +++++++------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index fcd3628209312..ae141ead49193 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4845,8 +4845,8 @@ static SDValue BitwiseToSrcModifierOp(SDValue N,
     return SDValue();
 
   SelectionDAG &DAG = DCI.DAG;
-  SDValue LHS = N.getNode()->getOperand(0);
-  SDValue RHS = N.getNode()->getOperand(1);
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
   ConstantSDNode *CRHS = isConstOrConstSplat(RHS);
 
   if (!CRHS)
@@ -4857,31 +4857,25 @@ static SDValue BitwiseToSrcModifierOp(SDValue N,
   assert((VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) &&
          "Expected i32, v2i32 or i64 value type.");
 
-  uint64_t Mask = 0;
-  if (VT.isVector()) {
-    SDValue Splat = DAG.getSplatValue(RHS);
-    const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Splat);
-    Mask = C->getZExtValue();
-  } else
-    Mask = CRHS->getZExtValue();
-
+  uint64_t Mask = CRHS->getZExtValue();
   EVT FVT = IntToFloatVT(VT);
-  SDValue BC = DAG.getNode(ISD::BITCAST, SDLoc(N), FVT, LHS);
+  SDLoc SL = SDLoc(N);
+  SDValue BC = DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
 
   switch (Opc) {
   case ISD::XOR:
     if (Mask == 0x80000000u || Mask == 0x8000000000000000u)
-      return DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
+      return DAG.getNode(ISD::FNEG, SL, FVT, BC);
     break;
   case ISD::OR:
     if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
       SDValue Neg = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
-      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, Neg);
+      return DAG.getNode(ISD::FABS, SL, FVT, Neg);
     }
     break;
   case ISD::AND:
     if (Mask == 0x7fffffffu || Mask == 0x7fffffffffffffffu)
-      return DAG.getNode(ISD::FABS, SDLoc(N), FVT, BC);
+      return DAG.getNode(ISD::FABS, SL, FVT, BC);
     break;
   default:
     return SDValue();
@@ -4933,12 +4927,10 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
     // Support source modifiers as integer.
     // (select c, (xor/or/and x, c), y) -> (bitcast (select c)))
     if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
-      SDLoc SL(N);
-      SDValue LHS = N->getOperand(1);
-      SDValue RHS = N->getOperand(2);
-      if (SDValue SrcMod = BitwiseToSrcModifierOp(LHS, DCI)) {
+      if (SDValue SrcMod = BitwiseToSrcModifierOp(True, DCI)) {
+        SDLoc SL(N);
         EVT FVT = IntToFloatVT(VT);
-        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, FVT, RHS);
+        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, FVT, False);
         SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, SrcMod, FRHS);
         SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
         return BC;

>From 3f91910bfafc84b80298a3da84ac3d5ea308d668 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 11:38:29 -0500
Subject: [PATCH 08/17] Respond to secon review comments - rename function and
 correct test

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp |  12 +-
 .../AMDGPU/integer-select-source-modifiers.ll | 168 +++++++++++++++++-
 2 files changed, 165 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index ae141ead49193..796729fe563ec 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4830,15 +4830,15 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
   return SDValue();
 }
 
-static EVT IntToFloatVT(EVT VT) {
+static EVT getFloatVT(EVT VT) {
   return VT = VT.isVector() ? MVT::getVectorVT(MVT::getFloatingPointVT(
                                                    VT.getScalarSizeInBits()),
                                                VT.getVectorNumElements())
                             : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
 }
 
-static SDValue BitwiseToSrcModifierOp(SDValue N,
-                                      TargetLowering::DAGCombinerInfo &DCI) {
+static SDValue getBitwiseToSrcModifierOp(SDValue N,
+                                         TargetLowering::DAGCombinerInfo &DCI) {
 
   unsigned Opc = N.getNode()->getOpcode();
   if (Opc != ISD::AND && Opc != ISD::XOR && Opc != ISD::AND)
@@ -4858,7 +4858,7 @@ static SDValue BitwiseToSrcModifierOp(SDValue N,
          "Expected i32, v2i32 or i64 value type.");
 
   uint64_t Mask = CRHS->getZExtValue();
-  EVT FVT = IntToFloatVT(VT);
+  EVT FVT = getFloatVT(VT);
   SDLoc SL = SDLoc(N);
   SDValue BC = DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
 
@@ -4927,9 +4927,9 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
     // Support source modifiers as integer.
     // (select c, (xor/or/and x, c), y) -> (bitcast (select c)))
     if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
-      if (SDValue SrcMod = BitwiseToSrcModifierOp(True, DCI)) {
+      if (SDValue SrcMod = getBitwiseToSrcModifierOp(True, DCI)) {
         SDLoc SL(N);
-        EVT FVT = IntToFloatVT(VT);
+        EVT FVT = getFloatVT(VT);
         SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, FVT, False);
         SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, SrcMod, FRHS);
         SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index 2db20e672c303..8e1905475f628 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -1,8 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GCN,GFX7 %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GCN,GFX9 %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-TRUE16 %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-FAKE16 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GFX7 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck -check-prefixes=GFX11 %s
 
 define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-LABEL: fneg_select_i32:
@@ -12,6 +11,20 @@ define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_select_i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_select_i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -34,6 +47,24 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_select_v2i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_v2i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_select_v2i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -56,6 +87,20 @@ define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fabs_select_i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fabs_select_i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -78,6 +123,24 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fabs_select_v2i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_v2i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fabs_select_v2i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -101,6 +164,22 @@ define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_fabs_select_i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_fabs_select_i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -127,6 +206,28 @@ define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32
 ; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_fabs_select_v2i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_v2i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_fabs_select_v2i32:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -154,6 +255,24 @@ define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_select_i64:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i64:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_select_i64:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -178,6 +297,24 @@ define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fabs_select_i64:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_i64:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fabs_select_i64:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -202,6 +339,24 @@ define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
+; GFX7-LABEL: fneg_fabs_select_i64:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_i64:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
 ; GFX11-LABEL: fneg_fabs_select_i64:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
@@ -215,8 +370,3 @@ define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
   %select = select i1 %cmp, i64 %neg.a, i64 %b
   ret i64 %select
 }
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; GFX11-FAKE16: {{.*}}
-; GFX11-TRUE16: {{.*}}
-; GFX7: {{.*}}
-; GFX9: {{.*}}

>From 3fc453623f5ea2591bbcb417585613626ee764b6 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 11:57:18 -0500
Subject: [PATCH 09/17] [NFC] Remove incomplete dag-style comment

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 796729fe563ec..3eab8dcb91760 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4925,7 +4925,6 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
     }
 
     // Support source modifiers as integer.
-    // (select c, (xor/or/and x, c), y) -> (bitcast (select c)))
     if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
       if (SDValue SrcMod = getBitwiseToSrcModifierOp(True, DCI)) {
         SDLoc SL(N);

>From 699d6360c8ad605dbc8b8b16ee71c98169894e10 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Mon, 7 Jul 2025 12:58:02 -0500
Subject: [PATCH 10/17] Make test for bitwise src mods more stringent and
 correct fneg-fabs order

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 3eab8dcb91760..7ca100d34c51a 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4864,17 +4864,20 @@ static SDValue getBitwiseToSrcModifierOp(SDValue N,
 
   switch (Opc) {
   case ISD::XOR:
-    if (Mask == 0x80000000u || Mask == 0x8000000000000000u)
+    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64))
       return DAG.getNode(ISD::FNEG, SL, FVT, BC);
     break;
   case ISD::OR:
-    if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
-      SDValue Neg = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
-      return DAG.getNode(ISD::FABS, SL, FVT, Neg);
+    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64)) {
+      SDValue Abs = DAG.getNode(ISD::ABS, SDLoc(N), FVT, BC);
+      return DAG.getNode(ISD::FNEG, SL, FVT, Abs);
     }
     break;
   case ISD::AND:
-    if (Mask == 0x7fffffffu || Mask == 0x7fffffffffffffffu)
+    if ((Mask == 0x7fffffffu && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x7fffffffffffffffu && VT.getFixedSizeInBits() == 64))
       return DAG.getNode(ISD::FABS, SL, FVT, BC);
     break;
   default:

>From cad4b08e7f9fd8fad3f6a8dea43594ae40e2bea1 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Tue, 8 Jul 2025 06:33:32 -0500
Subject: [PATCH 11/17] Reviewer corrections

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 7ca100d34c51a..d01bf63ceea2d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4831,10 +4831,10 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
 }
 
 static EVT getFloatVT(EVT VT) {
-  return VT = VT.isVector() ? MVT::getVectorVT(MVT::getFloatingPointVT(
-                                                   VT.getScalarSizeInBits()),
-                                               VT.getVectorNumElements())
-                            : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
+  return VT.isVector() ? MVT::getVectorVT(
+                             MVT::getFloatingPointVT(VT.getScalarSizeInBits()),
+                             VT.getVectorNumElements())
+                       : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
 }
 
 static SDValue getBitwiseToSrcModifierOp(SDValue N,
@@ -4871,7 +4871,7 @@ static SDValue getBitwiseToSrcModifierOp(SDValue N,
   case ISD::OR:
     if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
         (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64)) {
-      SDValue Abs = DAG.getNode(ISD::ABS, SDLoc(N), FVT, BC);
+      SDValue Abs = DAG.getNode(ISD::FABS, SL, FVT, BC);
       return DAG.getNode(ISD::FNEG, SL, FVT, Abs);
     }
     break;

>From 3bf165c1c1fb7eef5a1e6051e1c5a7dea50e748f Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Tue, 8 Jul 2025 10:08:50 -0500
Subject: [PATCH 12/17] Refactor to support the source modifiers on either or
 both operands. Also extend the test. Still struggling with 64-bit though as
 the legalizer is splitting some 64-bit ops into v2i32.

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp |  39 +-
 .../AMDGPU/integer-select-source-modifiers.ll | 589 ++++++++++++++----
 2 files changed, 471 insertions(+), 157 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index d01bf63ceea2d..940ac6b510527 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4831,17 +4831,15 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
 }
 
 static EVT getFloatVT(EVT VT) {
-  return VT.isVector() ? MVT::getVectorVT(
-                             MVT::getFloatingPointVT(VT.getScalarSizeInBits()),
-                             VT.getVectorNumElements())
-                       : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
+  EVT FT = MVT::getFloatingPointVT(VT.getScalarSizeInBits());
+  return VT.isVector() ? VT.changeVectorElementType(FT) : FT;
 }
 
 static SDValue getBitwiseToSrcModifierOp(SDValue N,
                                          TargetLowering::DAGCombinerInfo &DCI) {
 
   unsigned Opc = N.getNode()->getOpcode();
-  if (Opc != ISD::AND && Opc != ISD::XOR && Opc != ISD::AND)
+  if (Opc != ISD::AND && Opc != ISD::XOR && Opc != ISD::OR)
     return SDValue();
 
   SelectionDAG &DAG = DCI.DAG;
@@ -4853,31 +4851,23 @@ static SDValue getBitwiseToSrcModifierOp(SDValue N,
     return SDValue();
 
   EVT VT = RHS.getValueType();
-
-  assert((VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) &&
-         "Expected i32, v2i32 or i64 value type.");
-
-  uint64_t Mask = CRHS->getZExtValue();
   EVT FVT = getFloatVT(VT);
   SDLoc SL = SDLoc(N);
   SDValue BC = DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
 
   switch (Opc) {
   case ISD::XOR:
-    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
-        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64))
+    if (CRHS->getAPIntValue().isSignMask())
       return DAG.getNode(ISD::FNEG, SL, FVT, BC);
     break;
   case ISD::OR:
-    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
-        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64)) {
+    if (CRHS->getAPIntValue().isSignMask()) {
       SDValue Abs = DAG.getNode(ISD::FABS, SL, FVT, BC);
       return DAG.getNode(ISD::FNEG, SL, FVT, Abs);
     }
     break;
   case ISD::AND:
-    if ((Mask == 0x7fffffffu && VT.getFixedSizeInBits() == 32) ||
-        (Mask == 0x7fffffffffffffffu && VT.getFixedSizeInBits() == 64))
+    if (CRHS->getAPIntValue().isMaxSignedValue())
       return DAG.getNode(ISD::FABS, SL, FVT, BC);
     break;
   default:
@@ -4927,15 +4917,20 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
       return MinMax;
     }
 
-    // Support source modifiers as integer.
+    // Support source modifiers on integer types.
     if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
-      if (SDValue SrcMod = getBitwiseToSrcModifierOp(True, DCI)) {
+      SDValue SrcModTrue = getBitwiseToSrcModifierOp(True, DCI);
+      SDValue SrcModFalse = getBitwiseToSrcModifierOp(False, DCI);
+      if (SrcModTrue || SrcModFalse) {
         SDLoc SL(N);
         EVT FVT = getFloatVT(VT);
-        SDValue FRHS = DAG.getNode(ISD::BITCAST, SL, FVT, False);
-        SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, SrcMod, FRHS);
-        SDValue BC = DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
-        return BC;
+        SDValue FLHS =
+            SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, True);
+        SDValue FRHS = SrcModFalse ? SrcModFalse
+                                   : DAG.getNode(ISD::BITCAST, SL, FVT, False);
+        ;
+        SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, FLHS, FRHS);
+        return DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
       }
     }
   }
diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index 8e1905475f628..4fc31493a05f9 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -1,31 +1,24 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GFX7 %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GFX7,GCN %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GCN %s
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck -check-prefixes=GFX11 %s
 
-define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
-; GCN-LABEL: fneg_select_i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fneg_select_i32:
+define i32 @fneg_select_i32_1(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_select_i32_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
 ; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_select_i32:
+; GFX9-LABEL: fneg_select_i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
 ; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_select_i32:
+; GFX11-LABEL: fneg_select_i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
@@ -37,17 +30,91 @@ define i32 @fneg_select_i32(i32 %cond, i32 %a, i32 %b) {
   ret i32 %select
 }
 
-define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GCN-LABEL: fneg_select_v2i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
+define i32 @fneg_select_i32_2(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_select_i32_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX7-LABEL: fneg_select_v2i32:
+; GFX9-LABEL: fneg_select_i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i32 %a, u0x80000000
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %b, i32 %neg.a
+  ret i32 %select
+}
+
+define i32 @fneg_select_i32_both(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_select_i32_both:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i32_both:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_i32_both:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i32 %a, u0x80000000
+  %neg.b = xor i32 %b, u0x80000000
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %neg.a, i32 %neg.b
+  ret i32 %select
+}
+
+define i32 @fneg_1_fabs_2_select_i32(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_1_fabs_2_select_i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_1_fabs_2_select_i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_1_fabs_2_select_i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i32 %a, u0x80000000
+  %abs.b = and i32 %a, u0x7fffffff
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %neg.a, i32 %abs.b
+  ret i32 %select
+}
+
+define <2 x i32> @fneg_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fneg_select_v2i32_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
@@ -56,7 +123,7 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_select_v2i32:
+; GFX9-LABEL: fneg_select_v2i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
@@ -65,7 +132,7 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_select_v2i32:
+; GFX11-LABEL: fneg_select_v2i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
@@ -79,29 +146,55 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
   ret <2 x i32> %select
 }
 
-define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
-; GCN-LABEL: fabs_select_i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fabs_select_i32:
+define <2 x i32> @fneg_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fneg_select_v2i32_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_v2i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_v2i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor <2 x i32> %a, splat (i32 u0x80000000)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %b, <2 x i32> %neg.a
+  ret <2 x i32> %select
+}
+
+define i32 @fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fabs_select_i32_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
 ; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fabs_select_i32:
+; GFX9-LABEL: fabs_select_i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
 ; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fabs_select_i32:
+; GFX11-LABEL: fabs_select_i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
@@ -113,17 +206,35 @@ define i32 @fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
   ret i32 %select
 }
 
-define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GCN-LABEL: fabs_select_v2i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fabs_select_v2i32:
+define i32 @fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fabs_select_i32_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = and i32 %a, u0x7fffffff
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %b, i32 %neg.a
+  ret i32 %select
+}
+
+define <2 x i32> @fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fabs_select_v2i32_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
@@ -132,7 +243,7 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fabs_select_v2i32:
+; GFX9-LABEL: fabs_select_v2i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
@@ -141,7 +252,7 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 ; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fabs_select_v2i32:
+; GFX11-LABEL: fabs_select_v2i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
@@ -155,38 +266,93 @@ define <2 x i32> @fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
   ret <2 x i32> %select
 }
 
-define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
-; GCN-LABEL: fneg_fabs_select_i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fneg_fabs_select_i32:
+define <2 x i32> @fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fabs_select_v2i32_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_v2i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_v2i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = and <2 x i32> %a, splat (i32 u0x7fffffff)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %b, <2 x i32> %neg.a
+  ret <2 x i32> %select
+}
+
+define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fneg_select_v2i32:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_v2i32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_v2i32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor <2 x i32> %a, splat (i32 u0x80000000)
+  %abs.b = and <2 x i32> %a, splat (i32 u0x7fffffff)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %abs.b, <2 x i32> %neg.a
+  ret <2 x i32> %select
+}
+
+define i32 @fneg_fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_fabs_select_i32_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_fabs_select_i32:
+; GFX9-LABEL: fneg_fabs_select_i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_fabs_select_i32:
+; GFX11-LABEL: fneg_fabs_select_i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v1
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or i32 %a, u0x80000000
   %cmp = icmp eq i32 %cond, zeroinitializer
@@ -194,50 +360,59 @@ define i32 @fneg_fabs_select_i32(i32 %cond, i32 %a, i32 %b) {
   ret i32 %select
 }
 
-define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GCN-LABEL: fneg_fabs_select_v2i32:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fneg_fabs_select_v2i32:
+define i32 @fneg_fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
+; GFX7-LABEL: fneg_fabs_select_i32_2:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = or i32 %a, u0x80000000
+  %cmp = icmp eq i32 %cond, zeroinitializer
+  %select = select i1 %cmp, i32 %b, i32 %neg.a
+  ret i32 %select
+}
+
+define <2 x i32> @fneg_fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fneg_fabs_select_v2i32_1:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc
 ; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_fabs_select_v2i32:
+; GFX9-LABEL: fneg_fabs_select_v2i32_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc
 ; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_fabs_select_v2i32:
+; GFX11-LABEL: fneg_fabs_select_v2i32_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    v_or_b32_e32 v2, 0x80000000, v2
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
-; GFX11-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
-; GFX11-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc_lo
 ; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or <2 x i32> %a, splat (i32 u0x80000000)
   %cmp = icmp eq <2 x i32> %cond, zeroinitializer
@@ -245,17 +420,41 @@ define <2 x i32> @fneg_fabs_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32
   ret <2 x i32> %select
 }
 
-define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
-; GCN-LABEL: fneg_select_i64:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fneg_select_i64:
+define <2 x i32> @fneg_fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
+; GFX7-LABEL: fneg_fabs_select_v2i32_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX7-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_v2i32_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc
+; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GFX9-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_v2i32_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc_lo
+; GFX11-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
+; GFX11-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = or <2 x i32> %a, splat (i32 u0x80000000)
+  %cmp = icmp eq <2 x i32> %cond, zeroinitializer
+  %select = select <2 x i1> %cmp, <2 x i32> %b, <2 x i32> %neg.a
+  ret <2 x i32> %select
+}
+
+define i64 @fneg_select_i64_1(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fneg_select_i64_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -264,7 +463,7 @@ define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_select_i64:
+; GFX9-LABEL: fneg_select_i64_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -273,7 +472,7 @@ define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_select_i64:
+; GFX11-LABEL: fneg_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
@@ -287,17 +486,78 @@ define i64 @fneg_select_i64(i64 %cond, i64 %a, i64 %b) {
   ret i64 %select
 }
 
-define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
-; GCN-LABEL: fabs_select_i64:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fabs_select_i64:
+define i64 @fneg_select_i64_2(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fneg_select_i64_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i64_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_select_i64_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_cndmask_b32 v1, v1, v5
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i64 %a, u0x8000000000000000
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %b, i64 %neg.a
+  ret i64 %select
+}
+
+define i64 @fneg_1_fabs_2_select_i64(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fneg_1_fabs_2_select_i64:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_1_fabs_2_select_i64:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_1_fabs_2_select_i64:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_and_b32 v1, 0x7fffffff, v5
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i64 %a, u0x8000000000000000
+  %abs.b = and i64 %b, u0x7fffffffffffffff
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %neg.a, i64 %abs.b
+  ret i64 %select
+}
+
+define i64 @fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fabs_select_i64_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -306,7 +566,7 @@ define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fabs_select_i64:
+; GFX9-LABEL: fabs_select_i64_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -315,7 +575,7 @@ define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fabs_select_i64:
+; GFX11-LABEL: fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
@@ -329,17 +589,41 @@ define i64 @fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
   ret i64 %select
 }
 
-define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
-; GCN-LABEL: fneg_fabs_select_i64:
-; GCN:       ; %bb.0:
-; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GCN-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX7-LABEL: fneg_fabs_select_i64:
+define i64 @fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fabs_select_i64_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fabs_select_i64_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fabs_select_i64_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_and_b32 v1, 0x7fffffff, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = and i64 %a, u0x7fffffffffffffff
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %b, i64 %neg.a
+  ret i64 %select
+}
+
+define i64 @fneg_fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fneg_fabs_select_i64_1:
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -348,7 +632,7 @@ define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX7-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX9-LABEL: fneg_fabs_select_i64:
+; GFX9-LABEL: fneg_fabs_select_i64_1:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
@@ -357,7 +641,7 @@ define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
-; GFX11-LABEL: fneg_fabs_select_i64:
+; GFX11-LABEL: fneg_fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
@@ -370,3 +654,38 @@ define i64 @fneg_fabs_select_i64(i64 %cond, i64 %a, i64 %b) {
   %select = select i1 %cmp, i64 %neg.a, i64 %b
   ret i64 %select
 }
+
+define i64 @fneg_fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
+; GFX7-LABEL: fneg_fabs_select_i64_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_fabs_select_i64_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: fneg_fabs_select_i64_2:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
+; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_cndmask_b32 v1, v1, v5
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = or i64 %a, u0x8000000000000000
+  %cmp = icmp eq i64 %cond, zeroinitializer
+  %select = select i1 %cmp, i64 %b, i64 %neg.a
+  ret i64 %select
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; GCN: {{.*}}

>From d94e7441e1d6f3f4b0c1579f749d03a40030db98 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Tue, 8 Jul 2025 10:17:38 -0500
Subject: [PATCH 13/17] Fix Typo.

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 940ac6b510527..89bf26cadeac4 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4928,7 +4928,6 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
             SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, True);
         SDValue FRHS = SrcModFalse ? SrcModFalse
                                    : DAG.getNode(ISD::BITCAST, SL, FVT, False);
-        ;
         SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, FLHS, FRHS);
         return DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
       }

>From 91335266697fc3ebb6b261ed6bc0a6f9522ade6b Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Tue, 8 Jul 2025 11:17:25 -0500
Subject: [PATCH 14/17] Respond to reviewer - Add i16 tests, simplify obtaining
 type

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp |   3 +-
 .../AMDGPU/integer-select-source-modifiers.ll | 685 +++++++++---------
 2 files changed, 338 insertions(+), 350 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 89bf26cadeac4..f2656a3eef6d4 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4923,7 +4923,8 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
       SDValue SrcModFalse = getBitwiseToSrcModifierOp(False, DCI);
       if (SrcModTrue || SrcModFalse) {
         SDLoc SL(N);
-        EVT FVT = getFloatVT(VT);
+        EVT FVT =
+            SrcModTrue ? SrcModTrue.getValueType() : SrcModFalse.getValueType();
         SDValue FLHS =
             SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, True);
         SDValue FRHS = SrcModFalse ? SrcModFalse
diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index 4fc31493a05f9..eed83dd905c38 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -1,22 +1,16 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GFX7,GCN %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GCN %s
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck -check-prefixes=GFX11 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 < %s | FileCheck -check-prefixes=GCN,GFX7 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -check-prefixes=GCN,GFX9 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-TRUE16 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-FAKE16 %s
 
 define i32 @fneg_select_i32_1(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_select_i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, -v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i32_1:
 ; GFX11:       ; %bb.0:
@@ -31,19 +25,12 @@ define i32 @fneg_select_i32_1(i32 %cond, i32 %a, i32 %b) {
 }
 
 define i32 @fneg_select_i32_2(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_select_i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -v1, v2, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i32_2:
 ; GFX11:       ; %bb.0:
@@ -58,19 +45,12 @@ define i32 @fneg_select_i32_2(i32 %cond, i32 %a, i32 %b) {
 }
 
 define i32 @fneg_select_i32_both(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_select_i32_both:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_i32_both:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_i32_both:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -v2, -v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i32_both:
 ; GFX11:       ; %bb.0:
@@ -86,19 +66,12 @@ define i32 @fneg_select_i32_both(i32 %cond, i32 %a, i32 %b) {
 }
 
 define i32 @fneg_1_fabs_2_select_i32(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_1_fabs_2_select_i32:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_1_fabs_2_select_i32:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_1_fabs_2_select_i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, |v1|, -v1, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_1_fabs_2_select_i32:
 ; GFX11:       ; %bb.0:
@@ -114,23 +87,14 @@ define i32 @fneg_1_fabs_2_select_i32(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fneg_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fneg_select_v2i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_v2i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_v2i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, -v2, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, -v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_v2i32_1:
 ; GFX11:       ; %bb.0:
@@ -147,23 +111,14 @@ define <2 x i32> @fneg_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %
 }
 
 define <2 x i32> @fneg_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fneg_select_v2i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_v2i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_v2i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -v2, v4, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, -v3, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_v2i32_2:
 ; GFX11:       ; %bb.0:
@@ -180,19 +135,12 @@ define <2 x i32> @fneg_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %
 }
 
 define i32 @fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fabs_select_i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, |v1|, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i32_1:
 ; GFX11:       ; %bb.0:
@@ -207,19 +155,12 @@ define i32 @fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
 }
 
 define i32 @fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fabs_select_i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, |v1|, v2, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i32_2:
 ; GFX11:       ; %bb.0:
@@ -234,23 +175,14 @@ define i32 @fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fabs_select_v2i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_v2i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_v2i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, |v2|, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, |v3|, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_v2i32_1:
 ; GFX11:       ; %bb.0:
@@ -267,23 +199,14 @@ define <2 x i32> @fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %
 }
 
 define <2 x i32> @fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fabs_select_v2i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_v2i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_v2i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, |v2|, v4, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, |v3|, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_v2i32_2:
 ; GFX11:       ; %bb.0:
@@ -300,23 +223,14 @@ define <2 x i32> @fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %
 }
 
 define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fneg_select_v2i32:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_v2i32:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_v2i32:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -v2, |v2|, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, -v3, |v3|, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_v2i32:
 ; GFX11:       ; %bb.0:
@@ -334,19 +248,12 @@ define <2 x i32> @fneg_select_v2i32(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b)
 }
 
 define i32 @fneg_fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_fabs_select_i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v2, -|v1|, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i32_1:
 ; GFX11:       ; %bb.0:
@@ -361,19 +268,12 @@ define i32 @fneg_fabs_select_i32_1(i32 %cond, i32 %a, i32 %b) {
 }
 
 define i32 @fneg_fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
-; GFX7-LABEL: fneg_fabs_select_i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -|v1|, v2, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i32_2:
 ; GFX11:       ; %bb.0:
@@ -388,23 +288,14 @@ define i32 @fneg_fabs_select_i32_2(i32 %cond, i32 %a, i32 %b) {
 }
 
 define <2 x i32> @fneg_fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fneg_fabs_select_v2i32_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_v2i32_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_v2i32_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v4, -|v2|, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, v5, -|v3|, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_v2i32_1:
 ; GFX11:       ; %bb.0:
@@ -421,23 +312,14 @@ define <2 x i32> @fneg_fabs_select_v2i32_1(<2 x i32> %cond, <2 x i32> %a, <2 x i
 }
 
 define <2 x i32> @fneg_fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i32> %b) {
-; GFX7-LABEL: fneg_fabs_select_v2i32_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX7-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc
-; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX7-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_v2i32_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
-; GFX9-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc
-; GFX9-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GFX9-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_v2i32_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -|v2|, v4, vcc
+; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
+; GCN-NEXT:    v_cndmask_b32_e64 v1, -|v3|, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_v2i32_2:
 ; GFX11:       ; %bb.0:
@@ -454,23 +336,14 @@ define <2 x i32> @fneg_fabs_select_v2i32_2(<2 x i32> %cond, <2 x i32> %a, <2 x i
 }
 
 define i64 @fneg_select_i64_1(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fneg_select_i64_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_i64_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_i64_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i64_1:
 ; GFX11:       ; %bb.0:
@@ -487,23 +360,14 @@ define i64 @fneg_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fneg_select_i64_2(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fneg_select_i64_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_select_i64_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_select_i64_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i64_2:
 ; GFX11:       ; %bb.0:
@@ -520,25 +384,15 @@ define i64 @fneg_select_i64_2(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fneg_1_fabs_2_select_i64(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fneg_1_fabs_2_select_i64:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_1_fabs_2_select_i64:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_1_fabs_2_select_i64:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_1_fabs_2_select_i64:
 ; GFX11:       ; %bb.0:
@@ -557,23 +411,14 @@ define i64 @fneg_1_fabs_2_select_i64(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fabs_select_i64_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_i64_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_i64_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
@@ -590,23 +435,14 @@ define i64 @fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fabs_select_i64_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fabs_select_i64_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fabs_select_i64_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i64_2:
 ; GFX11:       ; %bb.0:
@@ -623,23 +459,14 @@ define i64 @fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fneg_fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fneg_fabs_select_i64_1:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_i64_1:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_i64_1:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
@@ -656,23 +483,14 @@ define i64 @fneg_fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 }
 
 define i64 @fneg_fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
-; GFX7-LABEL: fneg_fabs_select_i64_2:
-; GFX7:       ; %bb.0:
-; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX7-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX7-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX7-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX7-NEXT:    s_setpc_b64 s[30:31]
-;
-; GFX9-LABEL: fneg_fabs_select_i64_2:
-; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GFX9-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GFX9-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
-; GFX9-NEXT:    s_setpc_b64 s[30:31]
+; GCN-LABEL: fneg_fabs_select_i64_2:
+; GCN:       ; %bb.0:
+; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
+; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i64_2:
 ; GFX11:       ; %bb.0:
@@ -687,5 +505,174 @@ define i64 @fneg_fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
   %select = select i1 %cmp, i64 %b, i64 %neg.a
   ret i64 %select
 }
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; GCN: {{.*}}
+define i16 @fneg_select_i16_1(i16 %cond, i16 %a, i16 %b) {
+; GFX7-LABEL: fneg_select_i16_1:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i16_1:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX9-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: fneg_select_i16_1:
+; GFX11-TRUE16:       ; %bb.0:
+; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT:    v_xor_b16 v0.h, 0x8000, v1.l
+; GFX11-TRUE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0.l
+; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT:    v_cndmask_b16 v0.l, v2.l, v0.h, vcc_lo
+; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: fneg_select_i16_1:
+; GFX11-FAKE16:       ; %bb.0:
+; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX11-FAKE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0
+; GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i16 %a, u0x8000
+  %cmp = icmp eq i16 %cond, zeroinitializer
+  %select = select i1 %cmp, i16 %neg.a, i16 %b
+  ret i16 %select
+}
+
+define i16 @fneg_select_i16_2(i16 %cond, i16 %a, i16 %b) {
+; GFX7-LABEL: fneg_select_i16_2:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i16_2:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX9-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: fneg_select_i16_2:
+; GFX11-TRUE16:       ; %bb.0:
+; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT:    v_xor_b16 v0.h, 0x8000, v1.l
+; GFX11-TRUE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0.l
+; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT:    v_cndmask_b16 v0.l, v0.h, v2.l, vcc_lo
+; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: fneg_select_i16_2:
+; GFX11-FAKE16:       ; %bb.0:
+; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT:    v_xor_b32_e32 v1, 0xffff8000, v1
+; GFX11-FAKE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0
+; GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc_lo
+; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i16 %a, u0x8000
+  %cmp = icmp eq i16 %cond, zeroinitializer
+  %select = select i1 %cmp, i16 %b, i16 %neg.a
+  ret i16 %select
+}
+
+define i16 @fneg_select_i16_both(i16 %cond, i16 %a, i16 %b) {
+; GFX7-LABEL: fneg_select_i16_both:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX7-NEXT:    v_xor_b32_e32 v0, 0xffff8000, v0
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_select_i16_both:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc
+; GFX9-NEXT:    v_xor_b32_e32 v0, 0xffff8000, v0
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: fneg_select_i16_both:
+; GFX11-TRUE16:       ; %bb.0:
+; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0.l
+; GFX11-TRUE16-NEXT:    v_cndmask_b16 v0.l, v2.l, v1.l, vcc_lo
+; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT:    v_xor_b16 v0.l, 0x8000, v0.l
+; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: fneg_select_i16_both:
+; GFX11-FAKE16:       ; %bb.0:
+; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0
+; GFX11-FAKE16-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-FAKE16-NEXT:    v_xor_b32_e32 v0, 0xffff8000, v0
+; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i16 %a, u0x8000
+  %neg.b = xor i16 %b, u0x8000
+  %cmp = icmp eq i16 %cond, zeroinitializer
+  %select = select i1 %cmp, i16 %neg.a, i16 %neg.b
+  ret i16 %select
+}
+
+define i16 @fneg_1_fabs_2_select_i16(i16 %cond, i16 %a, i16 %b) {
+; GFX7-LABEL: fneg_1_fabs_2_select_i16:
+; GFX7:       ; %bb.0:
+; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7-NEXT:    v_xor_b32_e32 v2, 0xffff8000, v1
+; GFX7-NEXT:    v_and_b32_e32 v1, 0x7fff, v1
+; GFX7-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX7-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: fneg_1_fabs_2_select_i16:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_xor_b32_e32 v2, 0xffff8000, v1
+; GFX9-NEXT:    v_and_b32_e32 v1, 0x7fff, v1
+; GFX9-NEXT:    v_cmp_eq_u16_e32 vcc, 0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: fneg_1_fabs_2_select_i16:
+; GFX11-TRUE16:       ; %bb.0:
+; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT:    v_xor_b16 v0.h, 0x8000, v1.l
+; GFX11-TRUE16-NEXT:    v_and_b16 v1.l, 0x7fff, v1.l
+; GFX11-TRUE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0.l
+; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT:    v_cndmask_b16 v0.l, v1.l, v0.h, vcc_lo
+; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: fneg_1_fabs_2_select_i16:
+; GFX11-FAKE16:       ; %bb.0:
+; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT:    v_xor_b32_e32 v2, 0xffff8000, v1
+; GFX11-FAKE16-NEXT:    v_and_b32_e32 v1, 0x7fff, v1
+; GFX11-FAKE16-NEXT:    v_cmp_eq_u16_e32 vcc_lo, 0, v0
+; GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc_lo
+; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
+  %neg.a = xor i16 %a, u0x8000
+  %abs.b = and i16 %a, u0x7fff
+  %cmp = icmp eq i16 %cond, zeroinitializer
+  %select = select i1 %cmp, i16 %neg.a, i16 %abs.b
+  ret i16 %select
+}
+
+

>From 008459990c80dae7d0a5bd00154863ed578c37c3 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Tue, 8 Jul 2025 11:22:37 -0500
Subject: [PATCH 15/17] Inline bitcast node creation.

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index f2656a3eef6d4..77bf9156880a1 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4853,22 +4853,24 @@ static SDValue getBitwiseToSrcModifierOp(SDValue N,
   EVT VT = RHS.getValueType();
   EVT FVT = getFloatVT(VT);
   SDLoc SL = SDLoc(N);
-  SDValue BC = DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
 
   switch (Opc) {
   case ISD::XOR:
     if (CRHS->getAPIntValue().isSignMask())
-      return DAG.getNode(ISD::FNEG, SL, FVT, BC);
+      return DAG.getNode(ISD::FNEG, SL, FVT,
+                         DAG.getNode(ISD::BITCAST, SL, FVT, LHS));
     break;
   case ISD::OR:
     if (CRHS->getAPIntValue().isSignMask()) {
-      SDValue Abs = DAG.getNode(ISD::FABS, SL, FVT, BC);
+      SDValue Abs = DAG.getNode(ISD::FABS, SL, FVT,
+                                DAG.getNode(ISD::BITCAST, SL, FVT, LHS));
       return DAG.getNode(ISD::FNEG, SL, FVT, Abs);
     }
     break;
   case ISD::AND:
     if (CRHS->getAPIntValue().isMaxSignedValue())
-      return DAG.getNode(ISD::FABS, SL, FVT, BC);
+      return DAG.getNode(ISD::FABS, SL, FVT,
+                         DAG.getNode(ISD::BITCAST, SL, FVT, LHS));
     break;
   default:
     return SDValue();

>From e543e45bad25847078b63597230dcb640205ff2f Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Fri, 11 Jul 2025 06:49:20 -0500
Subject: [PATCH 16/17] Add functional implementation for i64

While this is functional it can be refactored and simplified, working on
this now.
---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 103 ++++++++++++++++--
 .../AMDGPU/integer-select-source-modifiers.ll |  70 +++++-------
 2 files changed, 122 insertions(+), 51 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 77bf9156880a1..831c4456db08e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4919,23 +4919,112 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
       return MinMax;
     }
 
-    // Support source modifiers on integer types.
-    if (VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) {
-      SDValue SrcModTrue = getBitwiseToSrcModifierOp(True, DCI);
-      SDValue SrcModFalse = getBitwiseToSrcModifierOp(False, DCI);
+    auto FoldSrcMods = [&](SDValue LHS, SDValue RHS, EVT VT) -> SDValue {
+      SDValue SrcModTrue = getBitwiseToSrcModifierOp(LHS, DCI);
+      SDValue SrcModFalse = getBitwiseToSrcModifierOp(RHS, DCI);
       if (SrcModTrue || SrcModFalse) {
         SDLoc SL(N);
         EVT FVT =
             SrcModTrue ? SrcModTrue.getValueType() : SrcModFalse.getValueType();
         SDValue FLHS =
-            SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, True);
+            SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
         SDValue FRHS = SrcModFalse ? SrcModFalse
-                                   : DAG.getNode(ISD::BITCAST, SL, FVT, False);
+                                   : DAG.getNode(ISD::BITCAST, SL, FVT, RHS);
         SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, FLHS, FRHS);
         return DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
+    }
+    return SDValue();
+  };
+
+    // Support source modifiers on integer operands.
+    if (VT == MVT::i32 || VT == MVT::v2i32)
+      if (SDValue F = FoldSrcMods(True, False, VT))
+        return F;
+
+    // For i64 if a source modifier is to be folded in we split into two i32
+    // select of high and low values. The Operator need only be applied to the
+    // high values in order to change the sign bit.
+    if (VT == MVT::i64) {
+      bool TrueHasModifierOp =
+          (True.getOpcode() == ISD::AND || True.getOpcode() == ISD::OR ||
+           True.getOpcode() == ISD::XOR);
+
+      bool FalseHasModifierOp =
+          (False.getOpcode() == ISD::AND || False.getOpcode() == ISD::OR ||
+           False.getOpcode() == ISD::XOR);
+
+      ConstantSDNode *CTrueRHS = nullptr;
+      if (TrueHasModifierOp) {
+        SDValue TrueRHS = True->getOperand(1);
+        CTrueRHS = dyn_cast<ConstantSDNode>(TrueRHS);
+      }
+
+      ConstantSDNode *CFalseRHS = nullptr;
+      if (FalseHasModifierOp) {
+        SDValue FalseRHS = False->getOperand(1);
+        CFalseRHS = dyn_cast<ConstantSDNode>(FalseRHS);
+      }
+
+      // If True or False is a candidate for source modifier folding, extract
+      // the high value using APInt and reconstruct a ConstantSDNode.
+      SDValue TrueHiOp;
+      SDValue BCTrue = DAG.getNode(ISD::BITCAST, SDLoc(N), MVT::i64, True);
+      SDValue TrueLo;
+      SDValue TrueHi;
+      if (CTrueRHS) {
+        SDValue TrueLHS = True->getOperand(0);
+        SDValue TrueLHSHiVal = getHiHalf64(BCTrue, DAG);
+        TrueLo = getLoHalf64(TrueLHS, DAG);
+        APInt CTrueRHSHiBits =
+            CTrueRHS->getAPIntValue().getHiBits(32).trunc(32);
+        SDValue CTrueRHSHiVal =
+            DAG.getConstant(CTrueRHSHiBits, SDLoc(N), MVT::i32);
+        unsigned OpcTrue = True.getOpcode();
+        TrueHiOp = DAG.getNode(OpcTrue, SDLoc(N), MVT::i32, TrueLHSHiVal,
+                               CTrueRHSHiVal);
+      } else {
+        TrueLo = getLoHalf64(BCTrue, DAG);
+        TrueHi = getHiHalf64(BCTrue, DAG);
+      }
+
+      SDValue FalseHiOp;
+      SDValue BCFalse = DAG.getNode(ISD::BITCAST, SDLoc(N), MVT::i64, False);
+      SDValue FalseLo;
+      SDValue FalseHi;
+      if (CFalseRHS) {
+        SDValue FalseLHS = False->getOperand(0);
+        FalseLo = getLoHalf64(FalseLHS, DAG);
+        SDValue FalseLHSHiVal = getHiHalf64(BCFalse, DAG);
+        APInt CFalseRHSHiBits =
+            CFalseRHS->getAPIntValue().getHiBits(32).trunc(32);
+        SDValue CFalseRHSHiVal =
+            DAG.getConstant(CFalseRHSHiBits, SDLoc(N), MVT::i32);
+        unsigned OpcFalse = False.getOpcode();
+        FalseHiOp = DAG.getNode(OpcFalse, SDLoc(N), MVT::i32, FalseLHSHiVal,
+                                CFalseRHSHiVal);
+      } else {
+        FalseLo = getLoHalf64(BCFalse, DAG);
+        FalseHi = getHiHalf64(BCFalse, DAG);
+      }
+
+      if (CTrueRHS || CFalseRHS) {
+        // Place the low bits directly into the select. The operator is unneeded
+        // for these.
+        SDValue LoSelect =
+            DAG.getNode(ISD::SELECT, SDLoc(N), MVT::i32, Cond, TrueLo, FalseLo);
+        // If a source modifier may be folded use the bitwise-op of the high
+        // values, otherwise just pass the high part of the value.
+        SDValue FoldedHi =
+            FoldSrcMods(CTrueRHS ? TrueHiOp : TrueHi,
+                        CFalseRHS ? FalseHiOp : FalseHi, MVT::i32);
+
+        SDValue ResV =
+            DAG.getBuildVector(MVT::v2i32, SDLoc(N), {FoldedHi, LoSelect});
+        SDValue Res = DAG.getNode(ISD::BITCAST, SDLoc(N), MVT::i64, ResV);
+        return Res;
       }
     }
-  }
+}
 
   // There's no reason to not do this if the condition has other uses.
   return performCtlz_CttzCombine(SDLoc(N), Cond, True, False, DCI);
diff --git a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
index eed83dd905c38..c3ce0d1aa739e 100644
--- a/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
+++ b/llvm/test/CodeGen/AMDGPU/integer-select-source-modifiers.ll
@@ -340,18 +340,15 @@ define i64 @fneg_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_cndmask_b32 v1, v5, v1
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v5, v3 :: v_dual_cndmask_b32 v1, v4, v2
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer
@@ -364,18 +361,15 @@ define i64 @fneg_select_i64_2(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v0, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v2, v4, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_select_i64_2:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_xor_b32_e32 v1, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_cndmask_b32 v1, v1, v5
+; GFX11-NEXT:    v_dual_cndmask_b32 v0, v3, v5 :: v_dual_cndmask_b32 v1, v2, v4
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer
@@ -388,20 +382,16 @@ define i64 @fneg_1_fabs_2_select_i64(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_and_b32_e32 v5, 0x7fffffff, v5
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, |v5|, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_1_fabs_2_select_i64:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_xor_b32_e32 v3, 0x80000000, v3
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_and_b32 v1, 0x7fffffff, v5
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v1, v3, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, |v5|, v3, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = xor i64 %a, u0x8000000000000000
   %abs.b = and i64 %b, u0x7fffffffffffffff
@@ -415,18 +405,16 @@ define i64 @fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v5, |v3|, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_and_b32 v1, 0x7fffffff, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v5, |v3|, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and i64 %a, u0x7fffffffffffffff
   %cmp = icmp eq i64 %cond, zeroinitializer
@@ -439,18 +427,16 @@ define i64 @fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_and_b32_e32 v3, 0x7fffffff, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, |v3|, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v2, v4, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fabs_select_i64_2:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_and_b32 v1, 0x7fffffff, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_cndmask_b32_e32 v1, v1, v5, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, |v3|, v5, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v2, v4, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = and i64 %a, u0x7fffffffffffffff
   %cmp = icmp eq i64 %cond, zeroinitializer
@@ -463,18 +449,16 @@ define i64 @fneg_fabs_select_i64_1(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v4, v2, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v5, v3, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, v5, -|v3|, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i64_1:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v4, v2 :: v_dual_cndmask_b32 v1, v5, v1
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, v5, -|v3|, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer
@@ -487,18 +471,16 @@ define i64 @fneg_fabs_select_i64_2(i64 %cond, i64 %a, i64 %b) {
 ; GCN:       ; %bb.0:
 ; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, 0, v[0:1]
-; GCN-NEXT:    v_or_b32_e32 v3, 0x80000000, v3
-; GCN-NEXT:    v_cndmask_b32_e32 v0, v2, v4, vcc
-; GCN-NEXT:    v_cndmask_b32_e32 v1, v3, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e64 v0, -|v3|, v5, vcc
+; GCN-NEXT:    v_cndmask_b32_e32 v1, v2, v4, vcc
 ; GCN-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: fneg_fabs_select_i64_2:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
-; GFX11-NEXT:    v_or_b32_e32 v1, 0x80000000, v3
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT:    v_dual_cndmask_b32 v0, v2, v4 :: v_dual_cndmask_b32 v1, v1, v5
+; GFX11-NEXT:    v_cndmask_b32_e64 v0, -|v3|, v5, vcc_lo
+; GFX11-NEXT:    v_cndmask_b32_e32 v1, v2, v4, vcc_lo
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %neg.a = or i64 %a, u0x8000000000000000
   %cmp = icmp eq i64 %cond, zeroinitializer

>From bdb35f1ec7904c4c5db8525cbfb8502c5df2e878 Mon Sep 17 00:00:00 2001
From: Chris Jackson <chris.jackson at amd.com>
Date: Fri, 11 Jul 2025 12:27:01 -0500
Subject: [PATCH 17/17] Fix formatting

---
 llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 831c4456db08e..684fe6275640e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -4928,22 +4928,23 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
             SrcModTrue ? SrcModTrue.getValueType() : SrcModFalse.getValueType();
         SDValue FLHS =
             SrcModTrue ? SrcModTrue : DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
-        SDValue FRHS = SrcModFalse ? SrcModFalse
-                                   : DAG.getNode(ISD::BITCAST, SL, FVT, RHS);
+        SDValue FRHS =
+            SrcModFalse ? SrcModFalse : DAG.getNode(ISD::BITCAST, SL, FVT, RHS);
         SDValue FSelect = DAG.getNode(ISD::SELECT, SL, FVT, Cond, FLHS, FRHS);
         return DAG.getNode(ISD::BITCAST, SL, VT, FSelect);
-    }
-    return SDValue();
-  };
+      }
+      return SDValue();
+    };
 
     // Support source modifiers on integer operands.
     if (VT == MVT::i32 || VT == MVT::v2i32)
       if (SDValue F = FoldSrcMods(True, False, VT))
         return F;
 
-    // For i64 if a source modifier is to be folded in we split into two i32
-    // select of high and low values. The Operator need only be applied to the
-    // high values in order to change the sign bit.
+    // auto SplitSelect = [&]() -> std::pair(
+    //  For i64 if a source modifier is to be folded in we split into two i32
+    //  select of high and low values. The Operator need only be applied to the
+    //  high values in order to change the sign bit.
     if (VT == MVT::i64) {
       bool TrueHasModifierOp =
           (True.getOpcode() == ISD::AND || True.getOpcode() == ISD::OR ||
@@ -5024,7 +5025,7 @@ SDValue AMDGPUTargetLowering::performSelectCombine(SDNode *N,
         return Res;
       }
     }
-}
+  }
 
   // There's no reason to not do this if the condition has other uses.
   return performCtlz_CttzCombine(SDLoc(N), Cond, True, False, DCI);



More information about the llvm-commits mailing list