[llvm] [AMDGPU] Custom lower get_fpmode for demanded-bits based read narrowing (PR #218137)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 22 08:43:39 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Madhur Kumar (MadhurKumar004)

<details>
<summary>Changes</summary>

Fixes the "TODO: Might be worth moving to custom lowering so the and is exposed to demanded bits optimizations."

---

Patch is 35.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218137.diff


4 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+77-1) 
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.h (+1) 
- (modified) llvm/lib/Target/AMDGPU/SOPInstructions.td (-39) 
- (modified) llvm/test/CodeGen/AMDGPU/llvm.get.fpmode.ll (+62-121) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 15053568da8dc..a274648e5eaed 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -1042,7 +1042,7 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
 
   // TODO: Could move this to custom lowering, could benefit from combines on
   // extract of relevant bits.
-  setOperationAction(ISD::GET_FPMODE, MVT::i32, Legal);
+  setOperationAction(ISD::GET_FPMODE, MVT::i32, Custom);
 
   setOperationAction(ISD::MUL, MVT::i1, Promote);
 
@@ -5085,6 +5085,36 @@ SDValue SITargetLowering::lowerSET_FPENV(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, SetTrapReg, SetModeReg);
 }
 
+SDValue SITargetLowering::lowerGET_FPMODE(SDValue Op, SelectionDAG &DAG) const {
+  SDLoc SL(Op);
+
+  unsigned Width;
+  uint32_t FPMask;
+  if (Subtarget->getGeneration() >= AMDGPUSubtarget::GFX9) {
+    Width = 24;
+    FPMask = 0x87F3FF;
+  } else {
+    Width = 19;
+    FPMask = 0x7F3FF;
+  }
+
+  uint32_t ModeHwReg =
+      AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_MODE, 0, Width);
+  SDValue ModeHwRegImm = DAG.getTargetConstant(ModeHwReg, SL, MVT::i32);
+
+  SDVTList VTList = DAG.getVTList(MVT::i32, MVT::Other);
+  SDValue IntrinID =
+      DAG.getTargetConstant(Intrinsic::amdgcn_s_getreg, SL, MVT::i32);
+  SDValue GetModeReg = DAG.getNode(ISD::INTRINSIC_W_CHAIN, SL, VTList,
+                                  Op.getOperand(0), IntrinID, ModeHwRegImm);
+
+  SDValue Mask = DAG.getConstant(FPMask, SL, MVT::i32);
+  SDValue Result = DAG.getNode(ISD::AND, SL, MVT::i32, GetModeReg, Mask);
+
+  return DAG.getMergeValues({Result, GetModeReg.getValue(1)}, SL);
+
+}
+
 Register SITargetLowering::getRegisterByName(const char *RegName, LLT VT,
                                              const MachineFunction &MF) const {
   const Function &Fn = MF.getFunction();
@@ -7826,6 +7856,8 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return lowerROTR(Op, DAG);
   case ISD::INLINEASM:
     return LowerINLINEASM(Op, DAG);
+  case ISD::GET_FPMODE:
+    return lowerGET_FPMODE(Op, DAG);
   }
   return SDValue();
 }
@@ -14935,6 +14967,50 @@ SDValue SITargetLowering::performAndCombine(SDNode *N,
       }
     }
 
+    if (CRHS && LHS.getOpcode() == ISD::INTRINSIC_W_CHAIN &&
+       LHS.hasOneUse()) {
+      unsigned IntrinID = LHS.getConstantOperandVal(1);
+      if (IntrinID == Intrinsic::amdgcn_s_getreg) {
+        uint32_t Simm16 = LHS.getConstantOperandVal(2);
+        auto [HwRegId, RegOffset, RegSize] =
+            AMDGPU::Hwreg::HwregEncoding::decode(Simm16);
+
+        if (HwRegId == AMDGPU::Hwreg::ID_MODE) {
+          uint64_t Mask = CRHS->getZExtValue();
+          APInt NeededInRead = APInt(32, Mask);
+
+          unsigned Lo = NeededInRead.countr_zero();
+          unsigned Hi = 32 - NeededInRead.countLeadingZeros() - 1;
+
+          APInt Contiguous =
+              APInt::getBitsSet(32, Lo, Hi+1);
+          if (NeededInRead == Contiguous) {
+            unsigned NewWidth = Hi + 1;
+
+            if (NewWidth < RegSize) {
+              SDLoc DL(N);
+              uint32_t NewSimm16 =
+                  AMDGPU::Hwreg::HwregEncoding::encode(
+                      AMDGPU::Hwreg::ID_MODE, RegOffset, NewWidth);
+              SDValue NewImm = DAG.getTargetConstant(NewSimm16, DL, MVT::i32);
+
+              SDValue NewIntrin = SDValue(
+                  DAG.UpdateNodeOperands(
+                      LHS.getNode(),
+                      LHS.getOperand(0),
+                      LHS.getOperand(1),
+                      NewImm), 0);
+
+              if (Lo == 0)
+                return NewIntrin;
+              return DAG.getNode(ISD::AND, DL, VT, NewIntrin,
+                                  DAG.getConstant(Mask, DL, VT));
+            }
+          }
+        }
+      }
+    }
+
     // and (perm x, y, c1), c2 -> perm x, y, permute_mask(c1, c2)
     if (LHS.hasOneUse() && LHS.getOpcode() == AMDGPUISD::PERM &&
         isa<ConstantSDNode>(LHS.getOperand(2))) {
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 8ece9f279a100..08c7d666fba4e 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -477,6 +477,7 @@ class SITargetLowering final : public AMDGPUTargetLowering {
   SDValue lowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerGET_FPENV(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerSET_FPENV(SDValue Op, SelectionDAG &DAG) const;
+  SDValue lowerGET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
   SDValue lowerROTR(SDValue Op, SelectionDAG &DAG) const;
 
   Register getRegisterByName(const char* RegName, LLT VT,
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index 2c5a2b1f7d0d7..6e76b97b35c2c 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -2012,45 +2012,6 @@ let SubtargetPredicate = isGFX11Plus in
 // Bits 19, 20, and 21 cover non-FP exceptions and differ between
 // gfx9/10/11, so we ignore them here.
 
-// TODO: Would it be cheaper to emit multiple s_getreg_b32 calls for
-// the ranges and combine the results?
-
-defvar fp_round_mask = !add(!shl(1, 4), -1);
-defvar fp_denorm_mask = !shl(!add(!shl(1, 4), -1), 4);
-defvar dx10_clamp_mask = !shl(1, 8);
-defvar ieee_mode_mask = !shl(1, 9);
-
-// Covers fp_round, fp_denorm, dx10_clamp, and IEEE bit.
-defvar fpmode_mask =
-  !or(fp_round_mask, fp_denorm_mask, dx10_clamp_mask, ieee_mode_mask);
-
-defvar fp_excp_en_mask = !shl(!add(!shl(1, 7), -1), 12);
-defvar fp16_ovfl = !shl(1, 23);
-defvar fpmode_mask_gfx6plus = !or(fpmode_mask, fp_excp_en_mask);
-defvar fpmode_mask_gfx9plus = !or(fpmode_mask_gfx6plus, fp16_ovfl);
-
-class GetFPModePat<int fpmode_mask> : GCNPat<
-  (i32 get_fpmode),
-  (S_AND_B32 (i32 fpmode_mask),
-             (S_GETREG_B32 getHwRegImm<
-                HWREG.MODE, 0,
-                !add(!logtwo(fpmode_mask), 1)>.ret))
->;
-
-// TODO: Might be worth moving to custom lowering so the and is
-// exposed to demanded bits optimizations. Most users probably only
-// care about the rounding or denorm mode bits. We also can reduce the
-// demanded read from the getreg immediate.
-let SubtargetPredicate = isGFX9Plus in {
-// Last bit = FP16_OVFL
-def : GetFPModePat<fpmode_mask_gfx9plus>;
-}
-
-// Last bit = EXCP_EN.int_div0
-let SubtargetPredicate = isNotGFX9Plus in {
-def : GetFPModePat<fpmode_mask_gfx6plus>;
-}
-
 let SubtargetPredicate = HasPopsExitingWaveID in
 def : GCNPat<
   (int_amdgcn_pops_exiting_wave_id),
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.get.fpmode.ll b/llvm/test/CodeGen/AMDGPU/llvm.get.fpmode.ll
index 90ed943e88068..6cae620f04092 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.get.fpmode.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.get.fpmode.ll
@@ -13,7 +13,7 @@ define i32 @func_fpmode_i32() {
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
+; GFX678-NEXT:    s_and_b32 s4, s4, 0x7f3ff
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -21,7 +21,7 @@ define i32 @func_fpmode_i32() {
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX9-NEXT:    s_and_b32 s4, s4, 0x87f3ff
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -29,7 +29,7 @@ define i32 @func_fpmode_i32() {
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX10-NEXT:    s_and_b32 s4, s4, 0x87f3ff
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -37,7 +37,7 @@ define i32 @func_fpmode_i32() {
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
+; GFX11-NEXT:    s_and_b32 s0, s0, 0x87f3ff
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %fpmode = call i32 @llvm.get.fpmode.i32()
@@ -49,7 +49,7 @@ define i32 @strictfp_func_fpmode_i32() strictfp {
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
+; GFX678-NEXT:    s_and_b32 s4, s4, 0x7f3ff
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -57,7 +57,7 @@ define i32 @strictfp_func_fpmode_i32() strictfp {
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX9-NEXT:    s_and_b32 s4, s4, 0x87f3ff
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -65,7 +65,7 @@ define i32 @strictfp_func_fpmode_i32() strictfp {
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX10-NEXT:    s_and_b32 s4, s4, 0x87f3ff
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
@@ -73,7 +73,7 @@ define i32 @strictfp_func_fpmode_i32() strictfp {
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
+; GFX11-NEXT:    s_and_b32 s0, s0, 0x87f3ff
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %fpmode = call i32 @llvm.get.fpmode.i32() strictfp
@@ -85,7 +85,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX6:       ; %bb.0:
 ; GFX6-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
 ; GFX6-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX6-NEXT:    s_and_b32 s4, 0x7f3ff, s4
+; GFX6-NEXT:    s_and_b32 s4, s4, 0x7f3ff
 ; GFX6-NEXT:    s_mov_b32 s3, 0xf000
 ; GFX6-NEXT:    s_mov_b32 s2, -1
 ; GFX6-NEXT:    v_mov_b32_e32 v0, s4
@@ -97,7 +97,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX7:       ; %bb.0:
 ; GFX7-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x9
 ; GFX7-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX7-NEXT:    s_and_b32 s4, 0x7f3ff, s4
+; GFX7-NEXT:    s_and_b32 s4, s4, 0x7f3ff
 ; GFX7-NEXT:    s_mov_b32 s3, 0xf000
 ; GFX7-NEXT:    s_mov_b32 s2, -1
 ; GFX7-NEXT:    v_mov_b32_e32 v0, s4
@@ -109,7 +109,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX8:       ; %bb.0:
 ; GFX8-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; GFX8-NEXT:    s_getreg_b32 s2, hwreg(HW_REG_MODE, 0, 19)
-; GFX8-NEXT:    s_and_b32 s2, 0x7f3ff, s2
+; GFX8-NEXT:    s_and_b32 s2, s2, 0x7f3ff
 ; GFX8-NEXT:    v_mov_b32_e32 v2, s2
 ; GFX8-NEXT:    s_waitcnt lgkmcnt(0)
 ; GFX8-NEXT:    v_mov_b32_e32 v0, s0
@@ -121,7 +121,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; GFX9-NEXT:    s_getreg_b32 s2, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s2, 0x87f3ff, s2
+; GFX9-NEXT:    s_and_b32 s2, s2, 0x87f3ff
 ; GFX9-NEXT:    v_mov_b32_e32 v0, 0
 ; GFX9-NEXT:    v_mov_b32_e32 v1, s2
 ; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
@@ -133,7 +133,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
 ; GFX10-NEXT:    s_getreg_b32 s2, hwreg(HW_REG_MODE, 0, 24)
 ; GFX10-NEXT:    v_mov_b32_e32 v0, 0
-; GFX10-NEXT:    s_and_b32 s2, 0x87f3ff, s2
+; GFX10-NEXT:    s_and_b32 s2, s2, 0x87f3ff
 ; GFX10-NEXT:    v_mov_b32_e32 v1, s2
 ; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
 ; GFX10-NEXT:    global_store_dword v0, v1, s[0:1]
@@ -143,7 +143,7 @@ define amdgpu_kernel void @kernel_fpmode_i32(ptr addrspace(1) %ptr) {
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_load_b64 s[0:1], s[4:5], 0x24
 ; GFX11-NEXT:    s_getreg_b32 s2, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s2, 0x87f3ff, s2
+; GFX11-NEXT:    s_and_b32 s2, s2, 0x87f3ff
 ; GFX11-NEXT:    v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s2
 ; GFX11-NEXT:    s_waitcnt lgkmcnt(0)
 ; GFX11-NEXT:    global_store_b32 v0, v1, s[0:1]
@@ -159,8 +159,7 @@ define i32 @func_fpmode_i32_denormonly() {
 ; GFX678-LABEL: func_fpmode_i32_denormonly:
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
+; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX678-NEXT:    s_and_b32 s4, s4, 0xf0
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
@@ -168,8 +167,7 @@ define i32 @func_fpmode_i32_denormonly() {
 ; GFX9-LABEL: func_fpmode_i32_denormonly:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX9-NEXT:    s_and_b32 s4, s4, 0xf0
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
@@ -177,8 +175,7 @@ define i32 @func_fpmode_i32_denormonly() {
 ; GFX10-LABEL: func_fpmode_i32_denormonly:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
+; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX10-NEXT:    s_and_b32 s4, s4, 0xf0
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
@@ -186,8 +183,7 @@ define i32 @func_fpmode_i32_denormonly() {
 ; GFX11-LABEL: func_fpmode_i32_denormonly:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
+; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 8)
 ; GFX11-NEXT:    s_and_b32 s0, s0, 0xf0
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
@@ -200,36 +196,28 @@ define i32 @func_fpmode_i32_roundonly() {
 ; GFX678-LABEL: func_fpmode_i32_roundonly:
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
-; GFX678-NEXT:    s_and_b32 s4, s4, 15
+; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 4)
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: func_fpmode_i32_roundonly:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX9-NEXT:    s_and_b32 s4, s4, 15
+; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 4)
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: func_fpmode_i32_roundonly:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX10-NEXT:    s_and_b32 s4, s4, 15
+; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 4)
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: func_fpmode_i32_roundonly:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
-; GFX11-NEXT:    s_and_b32 s0, s0, 15
+; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 4)
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %fpmode = call i32 @llvm.get.fpmode.i32()
@@ -241,36 +229,28 @@ define i32 @func_fpmode_i32_round_denorm_only() {
 ; GFX678-LABEL: func_fpmode_i32_round_denorm_only:
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
-; GFX678-NEXT:    s_and_b32 s4, s4, 0xff
+; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: func_fpmode_i32_round_denorm_only:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX9-NEXT:    s_and_b32 s4, s4, 0xff
+; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: func_fpmode_i32_round_denorm_only:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX10-NEXT:    s_and_b32 s4, s4, 0xff
+; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 8)
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: func_fpmode_i32_round_denorm_only:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
-; GFX11-NEXT:    s_and_b32 s0, s0, 0xff
+; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 8)
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %fpmode = call i32 @llvm.get.fpmode.i32()
@@ -282,36 +262,28 @@ define i32 @func_fpmode_i32_round_denorm_dx10_ieee() {
 ; GFX678-LABEL: func_fpmode_i32_round_denorm_dx10_ieee:
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
-; GFX678-NEXT:    s_and_b32 s4, s4, 0x3ff
+; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 10)
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: func_fpmode_i32_round_denorm_dx10_ieee:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX9-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX9-NEXT:    s_and_b32 s4, s4, 0x3ff
+; GFX9-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 10)
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX10-LABEL: func_fpmode_i32_round_denorm_dx10_ieee:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 24)
-; GFX10-NEXT:    s_and_b32 s4, 0x87f3ff, s4
-; GFX10-NEXT:    s_and_b32 s4, s4, 0x3ff
+; GFX10-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 10)
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-LABEL: func_fpmode_i32_round_denorm_dx10_ieee:
 ; GFX11:       ; %bb.0:
 ; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 24)
-; GFX11-NEXT:    s_and_b32 s0, 0x87f3ff, s0
-; GFX11-NEXT:    s_and_b32 s0, s0, 0x3ff
+; GFX11-NEXT:    s_getreg_b32 s0, hwreg(HW_REG_MODE, 0, 10)
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX11-NEXT:    s_setpc_b64 s[30:31]
   %fpmode = call i32 @llvm.get.fpmode.i32()
@@ -324,7 +296,6 @@ define i32 @func_fpmode_i32_excp_en() {
 ; GFX678:       ; %bb.0:
 ; GFX678-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; GFX678-NEXT:    s_getreg_b32 s4, hwreg(HW_REG_MODE, 0, 19)
-; GFX678-NEXT:    s_and_b32 s4, 0x7f3ff, s4
 ; GFX678-NEXT:    s_and_b32 s4, s4, 0x7f000
 ; GFX678-NEXT:    v_mov_b32_e32 v0, s4
 ; GFX678-NEXT:    s_setpc_b64 s[30:31]
@@ -332,8 +303,7 @@ define i32 @func_fpmode_i32_excp_en() {
 ; GFX9-LABEL: func_fpmode_i32_excp_en:
 ; G...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/218137


More information about the llvm-commits mailing list