[llvm] [X86][GlobalISel] Added support for llvm.set.rounding (PR #156591)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 10 08:29:21 PDT 2025


https://github.com/JaydeepChauhan14 updated https://github.com/llvm/llvm-project/pull/156591

>From 24e063122dad4685315c7b69ef70b611b70750bb Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Tue, 2 Sep 2025 23:25:02 -0700
Subject: [PATCH 1/3] [X86][GlobalISel] Added support for llvm.set.rounding

---
 .../CodeGen/GlobalISel/MachineIRBuilder.h     |   5 +
 llvm/include/llvm/Support/TargetOpcodes.def   |   1 +
 llvm/include/llvm/Target/GenericOpcodes.td    |   6 +
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |   3 +
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 116 +++++-
 llvm/lib/Target/X86/GISel/X86LegalizerInfo.h  |   3 +
 llvm/lib/Target/X86/X86InstrGISel.td          |   8 +
 .../GlobalISel/legalizer-info-validation.mir  |   3 +
 .../GlobalISel/legalizer-info-validation.mir  |   3 +
 .../CodeGen/X86/isel-llvm.set.rounding.ll     | 348 +++++++++++++++++-
 .../FixedLenDecoderEmitter/big-filter.td      |   4 +-
 .../GlobalISelEmitter/GlobalISelEmitter.td    |   2 +-
 12 files changed, 490 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 99d3cd0aac85c..0b6033b4ba60a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -2463,6 +2463,11 @@ class LLVM_ABI MachineIRBuilder {
     return buildInstr(TargetOpcode::G_GET_ROUNDING, {Dst}, {});
   }
 
+  /// Build and insert G_SET_ROUNDING
+  MachineInstrBuilder buildSetRounding(const SrcOp &Src) {
+    return buildInstr(TargetOpcode::G_SET_ROUNDING, {}, {Src});
+  }
+
   virtual MachineInstrBuilder
   buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps, ArrayRef<SrcOp> SrcOps,
              std::optional<unsigned> Flags = std::nullopt);
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index b905576b61791..7710e2fc2f22b 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -745,6 +745,7 @@ HANDLE_TARGET_OPCODE(G_SET_FPMODE)
 HANDLE_TARGET_OPCODE(G_RESET_FPMODE)
 
 HANDLE_TARGET_OPCODE(G_GET_ROUNDING)
+HANDLE_TARGET_OPCODE(G_SET_ROUNDING)
 
 /// Generic pointer offset
 HANDLE_TARGET_OPCODE(G_PTR_ADD)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index ce4750db88c9a..733d10b1c5f3c 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -1273,6 +1273,12 @@ def G_GET_ROUNDING : GenericInstruction {
   let hasSideEffects = true;
 }
 
+def G_SET_ROUNDING : GenericInstruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins type0:$src);
+  let hasSideEffects = true;
+}
+
 //------------------------------------------------------------------------------
 // Memory ops
 //------------------------------------------------------------------------------
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 541269ab6bfce..dbf482dba7c44 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2607,6 +2607,9 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
   case Intrinsic::get_rounding:
     MIRBuilder.buildGetRounding(getOrCreateVReg(CI));
     return true;
+  case Intrinsic::set_rounding:
+    MIRBuilder.buildSetRounding(getOrCreateVReg(*CI.getOperand(0)));
+    return true;
   case Intrinsic::vscale: {
     MIRBuilder.buildVScale(getOrCreateVReg(CI), 1);
     return true;
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 7fe58539cd4ec..6a63cb327b783 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/IntrinsicsX86.h"
 #include "llvm/IR/Type.h"
 
 using namespace llvm;
@@ -109,7 +110,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
       .legalFor(HasSSE2 || UseX87, {s64})
       .legalFor(UseX87, {s80});
 
-  getActionDefinitionsBuilder(G_GET_ROUNDING).customFor({s32});
+  getActionDefinitionsBuilder({G_GET_ROUNDING, G_SET_ROUNDING})
+      .customFor({s32});
 
   // merge/unmerge
   for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
@@ -616,6 +618,8 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
     return legalizeFPTOSI(MI, MRI, Helper);
   case TargetOpcode::G_GET_ROUNDING:
     return legalizeGETROUNDING(MI, MRI, Helper);
+  case TargetOpcode::G_SET_ROUNDING:
+    return legalizeSETROUNDING(MI, MRI, Helper);
   }
   llvm_unreachable("expected switch to return");
 }
@@ -858,6 +862,116 @@ bool X86LegalizerInfo::legalizeGETROUNDING(MachineInstr &MI,
   return true;
 }
 
+bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
+                                           MachineRegisterInfo &MRI,
+                                           LegalizerHelper &Helper) const {
+  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
+  MachineFunction &MF = MIRBuilder.getMF();
+  Register Src = MI.getOperand(0).getReg();
+  const LLT s8 = LLT::scalar(8);
+  const LLT s16 = LLT::scalar(16);
+  const LLT s32 = LLT::scalar(32);
+
+  // Allocate stack slot for control word and MXCSR (4 bytes).
+  int MemSize = 4;
+  Align Alignment = Align(4);
+  MachinePointerInfo PtrInfo;
+  auto StackTemp = Helper.createStackTemporary(TypeSize::getFixed(MemSize),
+                                               Alignment, PtrInfo);
+  Register StackPtr = StackTemp.getReg(0);
+
+  auto StoreMMO =
+      MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore, 2, Align(2));
+  MIRBuilder.buildInstr(X86::G_FNSTCW16)
+      .addUse(StackPtr)
+      .addMemOperand(StoreMMO);
+
+  auto LoadMMO =
+      MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad, 2, Align(2));
+  auto CWD16 = MIRBuilder.buildLoad(s16, StackPtr, *LoadMMO);
+
+  // Clear RM field (bits 11:10)
+  auto ClearedCWD =
+      MIRBuilder.buildAnd(s16, CWD16, MIRBuilder.buildConstant(s16, 0xf3ff));
+
+  // Convert Src (rounding mode) to bits for control word
+  // (0xc9 << (2 * Src + 4)) & 0xc00
+  LLT SrcTy = MRI.getType(Src);
+  Register Src32;
+  if (SrcTy.getSizeInBits() < 32)
+    Src32 = MIRBuilder.buildZExt(s32, Src).getReg(0);
+  else if (SrcTy.getSizeInBits() > 32)
+    Src32 = MIRBuilder.buildTrunc(s32, Src).getReg(0);
+  else
+    Src32 = Src;
+  auto ShiftAmt = MIRBuilder.buildAdd(
+      s32, MIRBuilder.buildShl(s32, Src32, MIRBuilder.buildConstant(s32, 1)),
+      MIRBuilder.buildConstant(s32, 4));
+  auto ShiftAmt8 = MIRBuilder.buildTrunc(s8, ShiftAmt);
+  auto Shifted =
+      MIRBuilder.buildShl(s16, MIRBuilder.buildConstant(s16, 0xc9), ShiftAmt8);
+  auto RMBits =
+      MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00));
+
+  // Update rounding mode bits
+  auto NewCWD = MIRBuilder.buildOr(s16, ClearedCWD, RMBits);
+
+  // Store new FP Control Word to stack
+  auto StoreNewMMO =
+      MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore, 2, Align(2));
+  MIRBuilder.buildStore(NewCWD, StackPtr, *StoreNewMMO);
+
+  // Load FP control word from the slot using G_FLDCW16
+  auto LoadNewMMO =
+      MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad, 2, Align(2));
+  MIRBuilder.buildInstr(X86::G_FLDCW16)
+      .addUse(StackPtr)
+      .addMemOperand(LoadNewMMO);
+
+  if (Subtarget.hasSSE1()) {
+    // Store MXCSR to stack (use STMXCSR)
+    auto StoreMXCSRMMO = MF.getMachineMemOperand(
+        PtrInfo, MachineMemOperand::MOStore, 4, Align(4));
+    MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS)
+        .addIntrinsicID(Intrinsic::x86_sse_stmxcsr)
+        .addUse(StackPtr)
+        .addMemOperand(StoreMXCSRMMO);
+
+    // Load MXCSR from stack
+    auto LoadMXCSRMMO = MF.getMachineMemOperand(
+        PtrInfo, MachineMemOperand::MOLoad, 4, Align(4));
+    auto MXCSR = MIRBuilder.buildLoad(s32, StackPtr, *LoadMXCSRMMO);
+
+    // Clear RM field (bits 14:13)
+    auto ClearedMXCSR = MIRBuilder.buildAnd(
+        s32, MXCSR, MIRBuilder.buildConstant(s32, 0xffff9fff));
+
+    // Shift x87 RM bits from 11:10 to 14:13
+    auto RMBits32 = MIRBuilder.buildZExt(s32, RMBits);
+    auto MXCSRRMBits =
+        MIRBuilder.buildShl(s32, RMBits32, MIRBuilder.buildConstant(s32, 3));
+
+    // Update rounding mode bits
+    auto NewMXCSR = MIRBuilder.buildOr(s32, ClearedMXCSR, MXCSRRMBits);
+
+    // Store new MXCSR to stack
+    auto StoreNewMXCSRMMO = MF.getMachineMemOperand(
+        PtrInfo, MachineMemOperand::MOStore, 4, Align(4));
+    MIRBuilder.buildStore(NewMXCSR, StackPtr, *StoreNewMXCSRMMO);
+
+    // Load MXCSR from stack (use LDMXCSR)
+    auto LoadNewMXCSRMMO = MF.getMachineMemOperand(
+        PtrInfo, MachineMemOperand::MOLoad, 4, Align(4));
+    MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS)
+        .addIntrinsicID(Intrinsic::x86_sse_ldmxcsr)
+        .addUse(StackPtr)
+        .addMemOperand(LoadNewMXCSRMMO);
+  }
+
+  MI.eraseFromParent();
+  return true;
+}
+
 bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
                                          MachineInstr &MI) const {
   return true;
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index 0003552d70ee0..09c727c8e8685 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -57,6 +57,9 @@ class X86LegalizerInfo : public LegalizerInfo {
 
   bool legalizeGETROUNDING(MachineInstr &MI, MachineRegisterInfo &MRI,
                            LegalizerHelper &Helper) const;
+
+  bool legalizeSETROUNDING(MachineInstr &MI, MachineRegisterInfo &MRI,
+                           LegalizerHelper &Helper) const;
 };
 } // namespace llvm
 #endif
diff --git a/llvm/lib/Target/X86/X86InstrGISel.td b/llvm/lib/Target/X86/X86InstrGISel.td
index 39198214037a3..b0c6bb6f61ad8 100644
--- a/llvm/lib/Target/X86/X86InstrGISel.td
+++ b/llvm/lib/Target/X86/X86InstrGISel.td
@@ -34,6 +34,14 @@ def G_FNSTCW16 : X86GenericInstruction {
   let mayStore = true;
 }
 
+def G_FLDCW16 : X86GenericInstruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins ptype0:$src);
+  let hasSideEffects = true;
+  let mayLoad = true;
+}
+
 def : GINodeEquiv<G_FILD, X86fild>;
 def : GINodeEquiv<G_FIST, X86fp_to_mem>;
 def : GINodeEquiv<G_FNSTCW16, X86fp_cwd_get16>;
+def : GINodeEquiv<G_FLDCW16, X86fp_cwd_set16>;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 040f97f96ee21..9ad28a5487233 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -642,6 +642,9 @@
 # DEBUG-NEXT: G_GET_ROUNDING (opcode {{[0-9]+}}): 1 type index, 0 imm indices
 # DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
 # DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_SET_ROUNDING (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
 # DEBUG-NEXT: G_PTR_ADD (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
 # DEBUG-NEXT: .. the first uncovered type index: 2, OK
 # DEBUG-NEXT: .. the first uncovered imm index: 0, OK
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 9d68a6d72c486..f56e78a645d50 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -629,6 +629,9 @@
 # DEBUG-NEXT: G_GET_ROUNDING (opcode {{[0-9]+}}): 1 type index, 0 imm indices
 # DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
 # DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_SET_ROUNDING (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
 # DEBUG-NEXT: G_PTR_ADD (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
 # DEBUG-NEXT: .. the first uncovered type index: 2, OK
 # DEBUG-NEXT: .. the first uncovered imm index: 0, OK
diff --git a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
index 688add1e92ab1..f589c16ff18da 100644
--- a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
+++ b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
@@ -1,16 +1,16 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=i686-- -mattr=-sse | FileCheck %s --check-prefixes=X86-NOSSE,SDAG-X86-NOSSE
 ; RUN: llc < %s -mtriple=i686-- -fast-isel -fast-isel-abort=1 -mattr=-sse | FileCheck %s --check-prefixes=X86-NOSSE,FASTISEL-X86-NOSSE
-; RUN: llc < %s -mtriple=i686-- -global-isel -global-isel-abort=2 -mattr=-sse | FileCheck %s --check-prefixes=X86-NOSSE,GISEL-X86-NOSSE
+; RUN: llc < %s -mtriple=i686-- -global-isel -global-isel-abort=1 -mattr=-sse | FileCheck %s --check-prefixes=GISEL-X86-NOSSE
 ; RUN: llc < %s -mtriple=x86_64-- -mattr=-sse | FileCheck %s --check-prefixes=X64-NOSSE,SDAG-X64-NOSSE
 ; RUN: llc < %s -mtriple=x86_64-- -fast-isel -fast-isel-abort=1 -mattr=-sse | FileCheck %s --check-prefixes=X64-NOSSE,FASTISEL-X64-NOSSE
-; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=2 -mattr=-sse | FileCheck %s --check-prefixes=X64-NOSSE,GISEL-X64-NOSSE
+; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 -mattr=-sse | FileCheck %s --check-prefixes=GISEL-X64-NOSSE
 ; RUN: llc < %s -mtriple=i686-- | FileCheck %s --check-prefixes=X86,SDAG-X86
 ; RUN: llc < %s -mtriple=i686-- -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefixes=X86,FASTISEL-X86
-; RUN: llc < %s -mtriple=i686-- -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X86,GISEL-X86
+; RUN: llc < %s -mtriple=i686-- -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X86
 ; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefixes=X64,SDAG-X64
 ; RUN: llc < %s -mtriple=x86_64-- -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefixes=X64,FASTISEL-X64
-; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X64,GISEL-X64
+; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X64
 
 declare void @llvm.set.rounding(i32 %x)
 
@@ -24,6 +24,21 @@ define void @func_01() nounwind {
 ; X86-NOSSE-NEXT:    popl %eax
 ; X86-NOSSE-NEXT:    retl
 ;
+; GISEL-X86-NOSSE-LABEL: func_01:
+; GISEL-X86-NOSSE:       # %bb.0:
+; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
+; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X86-NOSSE-NEXT:    shlw $4, %cx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    popl %eax
+; GISEL-X86-NOSSE-NEXT:    retl
+;
 ; X64-NOSSE-LABEL: func_01:
 ; X64-NOSSE:       # %bb.0:
 ; X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -31,6 +46,19 @@ define void @func_01() nounwind {
 ; X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; X64-NOSSE-NEXT:    retq
 ;
+; GISEL-X64-NOSSE-LABEL: func_01:
+; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X64-NOSSE-NEXT:    shlw $4, %cx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    retq
+;
 ; X86-LABEL: func_01:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
@@ -40,6 +68,21 @@ define void @func_01() nounwind {
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
+; GISEL-X86-LABEL: func_01:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    fnstcw (%esp)
+; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NEXT:    andw (%esp), %ax
+; GISEL-X86-NEXT:    movw $201, %cx
+; GISEL-X86-NEXT:    shlw $4, %cx
+; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %cx
+; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    fldcw (%esp)
+; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    retl
+;
 ; X64-LABEL: func_01:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -49,6 +92,27 @@ define void @func_01() nounwind {
 ; X64-NEXT:    orb $96, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: func_01:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NEXT:    movw $201, %cx
+; GISEL-X64-NEXT:    shlw $4, %cx
+; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
+; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    shll $3, %ecx
+; GISEL-X64-NEXT:    orl %eax, %ecx
+; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    retq
   call void @llvm.set.rounding(i32 0)  ; TowardZero (CW[11-10] = 11)
   ret void
 }
@@ -63,6 +127,21 @@ define void @func_02() nounwind {
 ; X86-NOSSE-NEXT:    popl %eax
 ; X86-NOSSE-NEXT:    retl
 ;
+; GISEL-X86-NOSSE-LABEL: func_02:
+; GISEL-X86-NOSSE:       # %bb.0:
+; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
+; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X86-NOSSE-NEXT:    shlw $6, %cx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    popl %eax
+; GISEL-X86-NOSSE-NEXT:    retl
+;
 ; X64-NOSSE-LABEL: func_02:
 ; X64-NOSSE:       # %bb.0:
 ; X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -70,6 +149,19 @@ define void @func_02() nounwind {
 ; X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; X64-NOSSE-NEXT:    retq
 ;
+; GISEL-X64-NOSSE-LABEL: func_02:
+; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X64-NOSSE-NEXT:    shlw $6, %cx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    retq
+;
 ; X86-LABEL: func_02:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
@@ -79,6 +171,21 @@ define void @func_02() nounwind {
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
+; GISEL-X86-LABEL: func_02:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    fnstcw (%esp)
+; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NEXT:    andw (%esp), %ax
+; GISEL-X86-NEXT:    movw $201, %cx
+; GISEL-X86-NEXT:    shlw $6, %cx
+; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %cx
+; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    fldcw (%esp)
+; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    retl
+;
 ; X64-LABEL: func_02:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -88,6 +195,27 @@ define void @func_02() nounwind {
 ; X64-NEXT:    andb $-97, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: func_02:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NEXT:    movw $201, %cx
+; GISEL-X64-NEXT:    shlw $6, %cx
+; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
+; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    shll $3, %ecx
+; GISEL-X64-NEXT:    orl %eax, %ecx
+; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    retq
   call void @llvm.set.rounding(i32 1)  ; ToNearestTiesToEven (CW[11-10] = 00)
   ret void
 }
@@ -105,6 +233,21 @@ define void @func_03() nounwind {
 ; X86-NOSSE-NEXT:    popl %eax
 ; X86-NOSSE-NEXT:    retl
 ;
+; GISEL-X86-NOSSE-LABEL: func_03:
+; GISEL-X86-NOSSE:       # %bb.0:
+; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
+; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X86-NOSSE-NEXT:    shlw $8, %cx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    popl %eax
+; GISEL-X86-NOSSE-NEXT:    retl
+;
 ; X64-NOSSE-LABEL: func_03:
 ; X64-NOSSE:       # %bb.0:
 ; X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -115,6 +258,19 @@ define void @func_03() nounwind {
 ; X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; X64-NOSSE-NEXT:    retq
 ;
+; GISEL-X64-NOSSE-LABEL: func_03:
+; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X64-NOSSE-NEXT:    shlw $8, %cx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    retq
+;
 ; X86-LABEL: func_03:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
@@ -127,6 +283,21 @@ define void @func_03() nounwind {
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
+; GISEL-X86-LABEL: func_03:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    fnstcw (%esp)
+; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NEXT:    andw (%esp), %ax
+; GISEL-X86-NEXT:    movw $201, %cx
+; GISEL-X86-NEXT:    shlw $8, %cx
+; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %cx
+; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    fldcw (%esp)
+; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    retl
+;
 ; X64-LABEL: func_03:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -142,6 +313,27 @@ define void @func_03() nounwind {
 ; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: func_03:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NEXT:    movw $201, %cx
+; GISEL-X64-NEXT:    shlw $8, %cx
+; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
+; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    shll $3, %ecx
+; GISEL-X64-NEXT:    orl %eax, %ecx
+; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    retq
   call void @llvm.set.rounding(i32 2)  ; Upward (CW[11-10] = 10)
   ret void
 }
@@ -159,6 +351,21 @@ define void @func_04() nounwind {
 ; X86-NOSSE-NEXT:    popl %eax
 ; X86-NOSSE-NEXT:    retl
 ;
+; GISEL-X86-NOSSE-LABEL: func_04:
+; GISEL-X86-NOSSE:       # %bb.0:
+; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
+; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X86-NOSSE-NEXT:    shlw $10, %cx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    popl %eax
+; GISEL-X86-NOSSE-NEXT:    retl
+;
 ; X64-NOSSE-LABEL: func_04:
 ; X64-NOSSE:       # %bb.0:
 ; X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -169,6 +376,19 @@ define void @func_04() nounwind {
 ; X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; X64-NOSSE-NEXT:    retq
 ;
+; GISEL-X64-NOSSE-LABEL: func_04:
+; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
+; GISEL-X64-NOSSE-NEXT:    shlw $10, %cx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
+; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    retq
+;
 ; X86-LABEL: func_04:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
@@ -181,6 +401,21 @@ define void @func_04() nounwind {
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
+; GISEL-X86-LABEL: func_04:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    fnstcw (%esp)
+; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NEXT:    andw (%esp), %ax
+; GISEL-X86-NEXT:    movw $201, %cx
+; GISEL-X86-NEXT:    shlw $10, %cx
+; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %cx
+; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    fldcw (%esp)
+; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    retl
+;
 ; X64-LABEL: func_04:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
@@ -196,6 +431,27 @@ define void @func_04() nounwind {
 ; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: func_04:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NEXT:    movw $201, %cx
+; GISEL-X64-NEXT:    shlw $10, %cx
+; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
+; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    shll $3, %ecx
+; GISEL-X64-NEXT:    orl %eax, %ecx
+; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    retq
   call void @llvm.set.rounding(i32 3)  ; Downward (CW[11-10] = 01)
   ret void
 }
@@ -219,6 +475,25 @@ define void @func_05(i32 %x) nounwind {
 ; X86-NOSSE-NEXT:    popl %eax
 ; X86-NOSSE-NEXT:    retl
 ;
+; GISEL-X86-NOSSE-LABEL: func_05:
+; GISEL-X86-NOSSE:       # %bb.0:
+; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
+; GISEL-X86-NOSSE-NEXT:    addl %ecx, %ecx
+; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
+; GISEL-X86-NOSSE-NEXT:    popl %eax
+; GISEL-X86-NOSSE-NEXT:    retl
+;
 ; X64-NOSSE-LABEL: func_05:
 ; X64-NOSSE:       # %bb.0:
 ; X64-NOSSE-NEXT:    # kill: def $edi killed $edi def $rdi
@@ -235,6 +510,23 @@ define void @func_05(i32 %x) nounwind {
 ; X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; X64-NOSSE-NEXT:    retq
 ;
+; GISEL-X64-NOSSE-LABEL: func_05:
+; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    # kill: def $edi killed $edi def $rdi
+; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NOSSE-NEXT:    leal (%rdi,%rdi), %ecx
+; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    retq
+;
 ; X86-LABEL: func_05:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
@@ -253,6 +545,25 @@ define void @func_05(i32 %x) nounwind {
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
+; GISEL-X86-LABEL: func_05:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    fnstcw (%esp)
+; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X86-NEXT:    andw (%esp), %ax
+; GISEL-X86-NEXT:    addl %ecx, %ecx
+; GISEL-X86-NEXT:    addl $4, %ecx
+; GISEL-X86-NEXT:    movw $201, %dx
+; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NEXT:    shlw %cl, %dx
+; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %dx
+; GISEL-X86-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NEXT:    fldcw (%esp)
+; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    retl
+;
 ; X64-LABEL: func_05:
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
@@ -274,6 +585,31 @@ define void @func_05(i32 %x) nounwind {
 ; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: func_05:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    # kill: def $edi killed $edi def $rdi
+; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
+; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
+; GISEL-X64-NEXT:    leal (%rdi,%rdi), %ecx
+; GISEL-X64-NEXT:    addl $4, %ecx
+; GISEL-X64-NEXT:    movw $201, %dx
+; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NEXT:    shlw %cl, %dx
+; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %dx, %ax
+; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
+; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movzwl %dx, %ecx
+; GISEL-X64-NEXT:    shll $3, %ecx
+; GISEL-X64-NEXT:    orl %eax, %ecx
+; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    retq
   call void @llvm.set.rounding(i32 %x)  ; Downward
   ret void
 }
@@ -284,10 +620,6 @@ attributes #0 = { nounwind "use-soft-float"="true" }
 ; FASTISEL-X64-NOSSE: {{.*}}
 ; FASTISEL-X86: {{.*}}
 ; FASTISEL-X86-NOSSE: {{.*}}
-; GISEL-X64: {{.*}}
-; GISEL-X64-NOSSE: {{.*}}
-; GISEL-X86: {{.*}}
-; GISEL-X86-NOSSE: {{.*}}
 ; SDAG-X64: {{.*}}
 ; SDAG-X64-NOSSE: {{.*}}
 ; SDAG-X86: {{.*}}
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td b/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
index 7e2cda1bae9ed..56fc14d0fe775 100644
--- a/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/big-filter.td
@@ -15,10 +15,10 @@ class I : Instruction {
 // CHECK-NEXT:    MCD::OPC_ExtractField, 0, 64,
 // CHECK-NEXT:    MCD::OPC_FilterValue, 1, 8, 0,
 // CHECK-NEXT:    MCD::OPC_CheckFieldOrFail, 127, 1, 1,
-// CHECK-NEXT:    MCD::OPC_Decode, 187, 2, 0,
+// CHECK-NEXT:    MCD::OPC_Decode, 188, 2, 0,
 // CHECK-NEXT:    MCD::OPC_FilterValueOrFail, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1,
 // CHECK-NEXT:    MCD::OPC_CheckFieldOrFail, 127, 1, 0,
-// CHECK-NEXT:    MCD::OPC_Decode, 186, 2, 0,
+// CHECK-NEXT:    MCD::OPC_Decode, 187, 2, 0,
 // CHECK-NEXT:  };
 
 def I1 : I {
diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
index 7a86b5b726a82..6be1720a6da23 100644
--- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
@@ -535,7 +535,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
 // R00O-NEXT:  GIM_Reject,
 // R00O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
 // R00O-NEXT:  GIM_Reject,
-// R00O-NEXT:  }; // Size: 1894 bytes
+// R00O-NEXT:  }; // Size: 1898 bytes
 
 def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
                  [(set GPR32:$dst,

>From 954395e45923b0863b5d53f1463213ada91b21cc Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 4 Sep 2025 10:56:03 -0700
Subject: [PATCH 2/3] Addressed the review comments1

---
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |  12 +-
 .../CodeGen/X86/isel-llvm.set.rounding.ll     | 220 +++++++++++-------
 2 files changed, 143 insertions(+), 89 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 6a63cb327b783..957c176f798e0 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -896,14 +896,7 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
 
   // Convert Src (rounding mode) to bits for control word
   // (0xc9 << (2 * Src + 4)) & 0xc00
-  LLT SrcTy = MRI.getType(Src);
-  Register Src32;
-  if (SrcTy.getSizeInBits() < 32)
-    Src32 = MIRBuilder.buildZExt(s32, Src).getReg(0);
-  else if (SrcTy.getSizeInBits() > 32)
-    Src32 = MIRBuilder.buildTrunc(s32, Src).getReg(0);
-  else
-    Src32 = Src;
+  auto Src32 = MIRBuilder.buildZExtOrTrunc(s32, Src);
   auto ShiftAmt = MIRBuilder.buildAdd(
       s32, MIRBuilder.buildShl(s32, Src32, MIRBuilder.buildConstant(s32, 1)),
       MIRBuilder.buildConstant(s32, 4));
@@ -914,7 +907,8 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
       MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00));
 
   // Update rounding mode bits
-  auto NewCWD = MIRBuilder.buildOr(s16, ClearedCWD, RMBits);
+  auto NewCWD =
+      MIRBuilder.buildOr(s16, ClearedCWD, RMBits, MachineInstr::Disjoint);
 
   // Store new FP Control Word to stack
   auto StoreNewMMO =
diff --git a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
index f589c16ff18da..303aab03dbb1e 100644
--- a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
+++ b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
@@ -27,14 +27,17 @@ define void @func_01() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_01:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    xorl %ecx, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X86-NOSSE-NEXT:    shlw $4, %cx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -48,14 +51,17 @@ define void @func_01() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_01:
 ; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    xorl %ecx, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X64-NOSSE-NEXT:    shlw $4, %cx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -71,14 +77,17 @@ define void @func_01() nounwind {
 ; GISEL-X86-LABEL: func_01:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    xorl %ecx, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    movw $201, %cx
-; GISEL-X86-NEXT:    shlw $4, %cx
-; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %cx
-; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    addl $4, %ecx
+; GISEL-X86-NEXT:    movw $201, %dx
+; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NEXT:    shlw %cl, %dx
+; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %dx
+; GISEL-X86-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -95,19 +104,22 @@ define void @func_01() nounwind {
 ;
 ; GISEL-X64-LABEL: func_01:
 ; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    movw $201, %cx
-; GISEL-X64-NEXT:    shlw $4, %cx
-; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    addl $4, %ecx
+; GISEL-X64-NEXT:    movw $201, %dx
+; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NEXT:    shlw %cl, %dx
+; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %dx, %ax
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    movzwl %dx, %ecx
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -130,14 +142,18 @@ define void @func_02() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_02:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    movl $1, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X86-NOSSE-NEXT:    shlw $6, %cx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    addl $1, %ecx
+; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -151,14 +167,18 @@ define void @func_02() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_02:
 ; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    movl $1, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X64-NOSSE-NEXT:    shlw $6, %cx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    addl $1, %ecx
+; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -174,14 +194,18 @@ define void @func_02() nounwind {
 ; GISEL-X86-LABEL: func_02:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    movl $1, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    movw $201, %cx
-; GISEL-X86-NEXT:    shlw $6, %cx
-; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %cx
-; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    addl $1, %ecx
+; GISEL-X86-NEXT:    addl $4, %ecx
+; GISEL-X86-NEXT:    movw $201, %dx
+; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NEXT:    shlw %cl, %dx
+; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %dx
+; GISEL-X86-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -198,19 +222,23 @@ define void @func_02() nounwind {
 ;
 ; GISEL-X64-LABEL: func_02:
 ; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    movl $1, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    movw $201, %cx
-; GISEL-X64-NEXT:    shlw $6, %cx
-; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    addl $1, %ecx
+; GISEL-X64-NEXT:    addl $4, %ecx
+; GISEL-X64-NEXT:    movw $201, %dx
+; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NEXT:    shlw %cl, %dx
+; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %dx, %ax
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    movzwl %dx, %ecx
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -236,14 +264,18 @@ define void @func_03() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_03:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    movl $2, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X86-NOSSE-NEXT:    shlw $8, %cx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    addl $2, %ecx
+; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -260,14 +292,18 @@ define void @func_03() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_03:
 ; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    movl $2, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X64-NOSSE-NEXT:    shlw $8, %cx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    addl $2, %ecx
+; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -286,14 +322,18 @@ define void @func_03() nounwind {
 ; GISEL-X86-LABEL: func_03:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    movl $2, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    movw $201, %cx
-; GISEL-X86-NEXT:    shlw $8, %cx
-; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %cx
-; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    addl $2, %ecx
+; GISEL-X86-NEXT:    addl $4, %ecx
+; GISEL-X86-NEXT:    movw $201, %dx
+; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NEXT:    shlw %cl, %dx
+; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %dx
+; GISEL-X86-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -316,19 +356,23 @@ define void @func_03() nounwind {
 ;
 ; GISEL-X64-LABEL: func_03:
 ; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    movl $2, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    movw $201, %cx
-; GISEL-X64-NEXT:    shlw $8, %cx
-; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    addl $2, %ecx
+; GISEL-X64-NEXT:    addl $4, %ecx
+; GISEL-X64-NEXT:    movw $201, %dx
+; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NEXT:    shlw %cl, %dx
+; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %dx, %ax
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    movzwl %dx, %ecx
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -354,14 +398,18 @@ define void @func_04() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_04:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
+; GISEL-X86-NOSSE-NEXT:    movl $3, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X86-NOSSE-NEXT:    shlw $10, %cx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X86-NOSSE-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    addl $3, %ecx
+; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -378,14 +426,18 @@ define void @func_04() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_04:
 ; GISEL-X64-NOSSE:       # %bb.0:
+; GISEL-X64-NOSSE-NEXT:    movl $3, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    movw $201, %cx
-; GISEL-X64-NOSSE-NEXT:    shlw $10, %cx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %cx
-; GISEL-X64-NOSSE-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    addl $3, %ecx
+; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
+; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
+; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
+; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
+; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -404,14 +456,18 @@ define void @func_04() nounwind {
 ; GISEL-X86-LABEL: func_04:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    movl $3, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    movw $201, %cx
-; GISEL-X86-NEXT:    shlw $10, %cx
-; GISEL-X86-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %cx
-; GISEL-X86-NEXT:    movw %cx, (%esp)
+; GISEL-X86-NEXT:    addl $3, %ecx
+; GISEL-X86-NEXT:    addl $4, %ecx
+; GISEL-X86-NEXT:    movw $201, %dx
+; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X86-NEXT:    shlw %cl, %dx
+; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X86-NEXT:    orw %ax, %dx
+; GISEL-X86-NEXT:    movw %dx, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -434,19 +490,23 @@ define void @func_04() nounwind {
 ;
 ; GISEL-X64-LABEL: func_04:
 ; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    movl $3, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    movw $201, %cx
-; GISEL-X64-NEXT:    shlw $10, %cx
-; GISEL-X64-NEXT:    andw $3072, %cx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %cx, %ax
+; GISEL-X64-NEXT:    addl $3, %ecx
+; GISEL-X64-NEXT:    addl $4, %ecx
+; GISEL-X64-NEXT:    movw $201, %dx
+; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
+; GISEL-X64-NEXT:    shlw %cl, %dx
+; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
+; GISEL-X64-NEXT:    orw %dx, %ax
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %cx, %ecx
+; GISEL-X64-NEXT:    movzwl %dx, %ecx
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)

>From 1fed64e1295545f43a48393c4aadc362d56befff Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Wed, 10 Sep 2025 08:29:05 -0700
Subject: [PATCH 3/3] Addressed the review comments2

---
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |  49 +++--
 .../CodeGen/X86/isel-llvm.set.rounding.ll     | 172 ++++--------------
 .../additional-encoding.td                    |   8 +-
 3 files changed, 73 insertions(+), 156 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 957c176f798e0..9a88e9a101ead 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -894,18 +894,43 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
   auto ClearedCWD =
       MIRBuilder.buildAnd(s16, CWD16, MIRBuilder.buildConstant(s16, 0xf3ff));
 
-  // Convert Src (rounding mode) to bits for control word
-  // (0xc9 << (2 * Src + 4)) & 0xc00
-  auto Src32 = MIRBuilder.buildZExtOrTrunc(s32, Src);
-  auto ShiftAmt = MIRBuilder.buildAdd(
-      s32, MIRBuilder.buildShl(s32, Src32, MIRBuilder.buildConstant(s32, 1)),
-      MIRBuilder.buildConstant(s32, 4));
-  auto ShiftAmt8 = MIRBuilder.buildTrunc(s8, ShiftAmt);
-  auto Shifted =
-      MIRBuilder.buildShl(s16, MIRBuilder.buildConstant(s16, 0xc9), ShiftAmt8);
-  auto RMBits =
-      MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00));
-
+  // Check if Src is a constant
+  auto *SrcDef = MRI.getVRegDef(Src);
+  Register RMBits;
+  if (SrcDef && SrcDef->getOpcode() == TargetOpcode::G_CONSTANT) {
+    uint64_t RM = getIConstantFromReg(Src, MRI).getZExtValue();
+    int FieldVal;
+    switch (static_cast<RoundingMode>(RM)) {
+    case RoundingMode::NearestTiesToEven:
+      FieldVal = X86::rmToNearest;
+      break;
+    case RoundingMode::TowardNegative:
+      FieldVal = X86::rmDownward;
+      break;
+    case RoundingMode::TowardPositive:
+      FieldVal = X86::rmUpward;
+      break;
+    case RoundingMode::TowardZero:
+      FieldVal = X86::rmTowardZero;
+      break;
+    default:
+      report_fatal_error("rounding mode is not supported by X86 hardware");
+    }
+    RMBits = MIRBuilder.buildConstant(s16, FieldVal).getReg(0);
+  } else {
+    // Convert Src (rounding mode) to bits for control word
+    // (0xc9 << (2 * Src + 4)) & 0xc00
+    auto Src32 = MIRBuilder.buildZExtOrTrunc(s32, Src);
+    auto ShiftAmt = MIRBuilder.buildAdd(
+        s32, MIRBuilder.buildShl(s32, Src32, MIRBuilder.buildConstant(s32, 1)),
+        MIRBuilder.buildConstant(s32, 4));
+    auto ShiftAmt8 = MIRBuilder.buildTrunc(s8, ShiftAmt);
+    auto Shifted = MIRBuilder.buildShl(s16, MIRBuilder.buildConstant(s16, 0xc9),
+                                       ShiftAmt8);
+    RMBits =
+        MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00))
+            .getReg(0);
+  }
   // Update rounding mode bits
   auto NewCWD =
       MIRBuilder.buildOr(s16, ClearedCWD, RMBits, MachineInstr::Disjoint);
diff --git a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
index 303aab03dbb1e..49f9c386e91ed 100644
--- a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
+++ b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
@@ -27,17 +27,11 @@ define void @func_01() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_01:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
-; GISEL-X86-NOSSE-NEXT:    xorl %ecx, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    orw $3072, %ax # imm = 0xC00
+; GISEL-X86-NOSSE-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -51,17 +45,11 @@ define void @func_01() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_01:
 ; GISEL-X64-NOSSE:       # %bb.0:
-; GISEL-X64-NOSSE-NEXT:    xorl %ecx, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    orw $3072, %ax # imm = 0xC00
+; GISEL-X64-NOSSE-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -77,17 +65,11 @@ define void @func_01() nounwind {
 ; GISEL-X86-LABEL: func_01:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
-; GISEL-X86-NEXT:    xorl %ecx, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    addl $4, %ecx
-; GISEL-X86-NEXT:    movw $201, %dx
-; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NEXT:    shlw %cl, %dx
-; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %dx
-; GISEL-X86-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NEXT:    orw $3072, %ax # imm = 0xC00
+; GISEL-X86-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -104,22 +86,16 @@ define void @func_01() nounwind {
 ;
 ; GISEL-X64-LABEL: func_01:
 ; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    xorl %ecx, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    addl $4, %ecx
-; GISEL-X64-NEXT:    movw $201, %dx
-; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NEXT:    shlw %cl, %dx
-; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %dx, %ax
+; GISEL-X64-NEXT:    orw $3072, %ax # imm = 0xC00
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %dx, %ecx
+; GISEL-X64-NEXT:    movl $3072, %ecx # imm = 0xC00
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -142,18 +118,11 @@ define void @func_02() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_02:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
-; GISEL-X86-NOSSE-NEXT:    movl $1, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    addl $1, %ecx
-; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    orw $0, %ax
+; GISEL-X86-NOSSE-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -167,18 +136,11 @@ define void @func_02() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_02:
 ; GISEL-X64-NOSSE:       # %bb.0:
-; GISEL-X64-NOSSE-NEXT:    movl $1, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    addl $1, %ecx
-; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    orw $0, %ax
+; GISEL-X64-NOSSE-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -194,18 +156,11 @@ define void @func_02() nounwind {
 ; GISEL-X86-LABEL: func_02:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
-; GISEL-X86-NEXT:    movl $1, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    addl $1, %ecx
-; GISEL-X86-NEXT:    addl $4, %ecx
-; GISEL-X86-NEXT:    movw $201, %dx
-; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NEXT:    shlw %cl, %dx
-; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %dx
-; GISEL-X86-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NEXT:    orw $0, %ax
+; GISEL-X86-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -222,23 +177,16 @@ define void @func_02() nounwind {
 ;
 ; GISEL-X64-LABEL: func_02:
 ; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    movl $1, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    addl $1, %ecx
-; GISEL-X64-NEXT:    addl $4, %ecx
-; GISEL-X64-NEXT:    movw $201, %dx
-; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NEXT:    shlw %cl, %dx
-; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %dx, %ax
+; GISEL-X64-NEXT:    orw $0, %ax
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %dx, %ecx
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -264,18 +212,11 @@ define void @func_03() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_03:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
-; GISEL-X86-NOSSE-NEXT:    movl $2, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    addl $2, %ecx
-; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    orw $2048, %ax # imm = 0x800
+; GISEL-X86-NOSSE-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -292,18 +233,11 @@ define void @func_03() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_03:
 ; GISEL-X64-NOSSE:       # %bb.0:
-; GISEL-X64-NOSSE-NEXT:    movl $2, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    addl $2, %ecx
-; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    orw $2048, %ax # imm = 0x800
+; GISEL-X64-NOSSE-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -322,18 +256,11 @@ define void @func_03() nounwind {
 ; GISEL-X86-LABEL: func_03:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
-; GISEL-X86-NEXT:    movl $2, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    addl $2, %ecx
-; GISEL-X86-NEXT:    addl $4, %ecx
-; GISEL-X86-NEXT:    movw $201, %dx
-; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NEXT:    shlw %cl, %dx
-; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %dx
-; GISEL-X86-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NEXT:    orw $2048, %ax # imm = 0x800
+; GISEL-X86-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -356,23 +283,16 @@ define void @func_03() nounwind {
 ;
 ; GISEL-X64-LABEL: func_03:
 ; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    movl $2, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    addl $2, %ecx
-; GISEL-X64-NEXT:    addl $4, %ecx
-; GISEL-X64-NEXT:    movw $201, %dx
-; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NEXT:    shlw %cl, %dx
-; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %dx, %ax
+; GISEL-X64-NEXT:    orw $2048, %ax # imm = 0x800
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %dx, %ecx
+; GISEL-X64-NEXT:    movl $2048, %ecx # imm = 0x800
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
@@ -398,18 +318,11 @@ define void @func_04() nounwind {
 ; GISEL-X86-NOSSE-LABEL: func_04:
 ; GISEL-X86-NOSSE:       # %bb.0:
 ; GISEL-X86-NOSSE-NEXT:    pushl %eax
-; GISEL-X86-NOSSE-NEXT:    movl $3, %ecx
 ; GISEL-X86-NOSSE-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NOSSE-NEXT:    andw (%esp), %ax
-; GISEL-X86-NOSSE-NEXT:    addl $3, %ecx
-; GISEL-X86-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X86-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X86-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X86-NOSSE-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NOSSE-NEXT:    orw $1024, %ax # imm = 0x400
+; GISEL-X86-NOSSE-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NOSSE-NEXT:    fldcw (%esp)
 ; GISEL-X86-NOSSE-NEXT:    popl %eax
 ; GISEL-X86-NOSSE-NEXT:    retl
@@ -426,18 +339,11 @@ define void @func_04() nounwind {
 ;
 ; GISEL-X64-NOSSE-LABEL: func_04:
 ; GISEL-X64-NOSSE:       # %bb.0:
-; GISEL-X64-NOSSE-NEXT:    movl $3, %ecx
 ; GISEL-X64-NOSSE-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NOSSE-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NOSSE-NEXT:    addl $3, %ecx
-; GISEL-X64-NOSSE-NEXT:    addl $4, %ecx
-; GISEL-X64-NOSSE-NEXT:    movw $201, %dx
-; GISEL-X64-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NOSSE-NEXT:    shlw %cl, %dx
-; GISEL-X64-NOSSE-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NOSSE-NEXT:    orw %ax, %dx
-; GISEL-X64-NOSSE-NEXT:    movw %dx, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NOSSE-NEXT:    orw $1024, %ax # imm = 0x400
+; GISEL-X64-NOSSE-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NOSSE-NEXT:    retq
 ;
@@ -456,18 +362,11 @@ define void @func_04() nounwind {
 ; GISEL-X86-LABEL: func_04:
 ; GISEL-X86:       # %bb.0:
 ; GISEL-X86-NEXT:    pushl %eax
-; GISEL-X86-NEXT:    movl $3, %ecx
 ; GISEL-X86-NEXT:    fnstcw (%esp)
 ; GISEL-X86-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X86-NEXT:    andw (%esp), %ax
-; GISEL-X86-NEXT:    addl $3, %ecx
-; GISEL-X86-NEXT:    addl $4, %ecx
-; GISEL-X86-NEXT:    movw $201, %dx
-; GISEL-X86-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X86-NEXT:    shlw %cl, %dx
-; GISEL-X86-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X86-NEXT:    orw %ax, %dx
-; GISEL-X86-NEXT:    movw %dx, (%esp)
+; GISEL-X86-NEXT:    orw $1024, %ax # imm = 0x400
+; GISEL-X86-NEXT:    movw %ax, (%esp)
 ; GISEL-X86-NEXT:    fldcw (%esp)
 ; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    retl
@@ -490,23 +389,16 @@ define void @func_04() nounwind {
 ;
 ; GISEL-X64-LABEL: func_04:
 ; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    movl $3, %ecx
 ; GISEL-X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movw $-3073, %ax # imm = 0xF3FF
 ; GISEL-X64-NEXT:    andw -{{[0-9]+}}(%rsp), %ax
-; GISEL-X64-NEXT:    addl $3, %ecx
-; GISEL-X64-NEXT:    addl $4, %ecx
-; GISEL-X64-NEXT:    movw $201, %dx
-; GISEL-X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; GISEL-X64-NEXT:    shlw %cl, %dx
-; GISEL-X64-NEXT:    andw $3072, %dx # imm = 0xC00
-; GISEL-X64-NEXT:    orw %dx, %ax
+; GISEL-X64-NEXT:    orw $1024, %ax # imm = 0x400
 ; GISEL-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
 ; GISEL-X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
-; GISEL-X64-NEXT:    movzwl %dx, %ecx
+; GISEL-X64-NEXT:    movl $1024, %ecx # imm = 0x400
 ; GISEL-X64-NEXT:    shll $3, %ecx
 ; GISEL-X64-NEXT:    orl %eax, %ecx
 ; GISEL-X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td b/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
index ec7e35e1ecac7..47c9335f6cdf2 100644
--- a/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/additional-encoding.td
@@ -35,22 +35,22 @@ class I<dag out_ops, dag in_ops> : Instruction {
 // CHECK-NEXT: /* 7 */  MCD::OPC_Scope, 8, 0, // Skip to: 18
 // CHECK-NEXT: /* 10 */ MCD::OPC_CheckField, 6, 6, 0,
 // CHECK-NEXT: /* 14 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 18 */ MCD::OPC_TryDecode, 187, 2, 1,
+// CHECK-NEXT: /* 18 */ MCD::OPC_TryDecode, {{[0-9]+}}, 2, 1,
 // CHECK-NEXT: /* 22 */ MCD::OPC_FilterValueOrSkip, 1, 15, 0, // Skip to: 41
 // CHECK-NEXT: /* 26 */ MCD::OPC_Scope, 8, 0, // Skip to: 37
 // CHECK-NEXT: /* 29 */ MCD::OPC_CheckField, 6, 6, 0,
 // CHECK-NEXT: /* 33 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 37 */ MCD::OPC_TryDecode, 188, 2, 1,
+// CHECK-NEXT: /* 37 */ MCD::OPC_TryDecode, {{[0-9]+}}, 2, 1,
 // CHECK-NEXT: /* 41 */ MCD::OPC_FilterValueOrSkip, 2, 15, 0, // Skip to: 60
 // CHECK-NEXT: /* 45 */ MCD::OPC_Scope, 8, 0, // Skip to: 56
 // CHECK-NEXT: /* 48 */ MCD::OPC_CheckField, 6, 6, 0,
 // CHECK-NEXT: /* 52 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 56 */ MCD::OPC_TryDecode, 189, 2, 1,
+// CHECK-NEXT: /* 56 */ MCD::OPC_TryDecode, {{[0-9]+}}, 2, 1,
 // CHECK-NEXT: /* 60 */ MCD::OPC_FilterValue, 3,
 // CHECK-NEXT: /* 62 */ MCD::OPC_Scope, 8, 0, // Skip to: 73
 // CHECK-NEXT: /* 65 */ MCD::OPC_CheckField, 6, 6, 0,
 // CHECK-NEXT: /* 69 */ MCD::OPC_Decode, {{[0-9]+}}, 2, 0, // Opcode: {{.*}}:NOP, DecodeIdx: 0
-// CHECK-NEXT: /* 73 */ MCD::OPC_TryDecode, 190, 2, 1,
+// CHECK-NEXT: /* 73 */ MCD::OPC_TryDecode, {{[0-9]+}}, 2, 1,
 
 
 class SHIFT<bits<2> opc> : I<(outs), (ins ShAmtOp:$shamt)>, EncSHIFT<opc>;



More information about the llvm-commits mailing list