From 24e063122dad4685315c7b69ef70b611b70750bb Mon Sep 17 00:00:00 2001 From: Chauhan Jaydeep Ashwinbhai Date: Tue, 2 Sep 2025 23:25:02 -0700 Subject: [PATCH 1/8] [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 DstOps, ArrayRef SrcOps, std::optional 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; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; 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 Date: Thu, 4 Sep 2025 10:56:03 -0700 Subject: [PATCH 2/8] 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 Date: Wed, 10 Sep 2025 08:29:05 -0700 Subject: [PATCH 3/8] 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(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 : 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 opc> : I<(outs), (ins ShAmtOp:$shamt)>, EncSHIFT; From a998dad3b193cdd0296773afbcf05990c4c22bb1 Mon Sep 17 00:00:00 2001 From: Chauhan Jaydeep Ashwinbhai Date: Tue, 23 Sep 2025 09:24:29 -0700 Subject: [PATCH 4/8] Addressed the review comments3 --- .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 40 ++++++------- llvm/lib/Target/X86/X86ISelLowering.cpp | 31 ++++++---- llvm/lib/Target/X86/X86ISelLowering.h | 19 +++--- .../CodeGen/X86/isel-llvm.set.rounding.ll | 60 ++++++++----------- llvm/test/TableGen/RegClassByHwMode.td | 2 +- 5 files changed, 79 insertions(+), 73 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 6f0efe1071f07..ee9760f881ae9 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -898,26 +898,23 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI, // Check if Src is a constant auto *SrcDef = MRI.getVRegDef(Src); Register RMBits; + Register MXCSRRMBits; + if (SrcDef && SrcDef->getOpcode() == TargetOpcode::G_CONSTANT) { uint64_t RM = getIConstantFromReg(Src, MRI).getZExtValue(); - int FieldVal; - switch (static_cast(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"); + int FieldVal = X86::getRoundingModeX86(RM); + + if (FieldVal == X86::rmInvalid) { + LLVMContext &C = MF.getFunction().getContext(); + C.diagnose(DiagnosticInfoUnsupported( + MF.getFunction(), "rounding mode is not supported by X86 hardware", + DiagnosticLocation(MI.getDebugLoc()), DS_Error)); + return false; } + + FieldVal = FieldVal << 3; RMBits = MIRBuilder.buildConstant(s16, FieldVal).getReg(0); + MXCSRRMBits = MIRBuilder.buildConstant(s32, FieldVal).getReg(0); } else { // Convert Src (rounding mode) to bits for control word // (0xc9 << (2 * Src + 4)) & 0xc00 @@ -931,6 +928,12 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI, RMBits = MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00)) .getReg(0); + + // For non-constant case, we still need to compute MXCSR bits dynamically + auto RMBits32 = MIRBuilder.buildZExt(s32, RMBits); + MXCSRRMBits = + MIRBuilder.buildShl(s32, RMBits32, MIRBuilder.buildConstant(s32, 3)) + .getReg(0); } // Update rounding mode bits auto NewCWD = @@ -966,11 +969,6 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI, 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); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 1c8de3a8df6e2..80fbcaa562032 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5346,6 +5346,19 @@ bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs) { return false; } + +int getRoundingModeX86(unsigned RM) { + switch (static_cast<::llvm::RoundingMode>(RM)) { + // clang-format off + case ::llvm::RoundingMode::NearestTiesToEven: return X86::rmToNearest; break; + case ::llvm::RoundingMode::TowardNegative: return X86::rmDownward; break; + case ::llvm::RoundingMode::TowardPositive: return X86::rmUpward; break; + case ::llvm::RoundingMode::TowardZero: return X86::rmTowardZero; break; + default: + return X86::rmInvalid; // Invalid rounding mode + } +} + } // namespace X86 } // namespace llvm @@ -28698,16 +28711,14 @@ SDValue X86TargetLowering::LowerSET_ROUNDING(SDValue Op, SDValue RMBits; if (auto *CVal = dyn_cast(NewRM)) { uint64_t RM = CVal->getZExtValue(); - int FieldVal; - switch (static_cast(RM)) { - // clang-format off - 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: - llvm_unreachable("rounding mode is not supported by X86 hardware"); - // clang-format on + int FieldVal = X86::getRoundingModeX86(RM); + + if (FieldVal == X86::rmInvalid) { + LLVMContext &C = MF.getFunction().getContext(); + C.diagnose(DiagnosticInfoUnsupported( + MF.getFunction(), "rounding mode is not supported by X86 hardware", + DiagnosticLocation(DL.getDebugLoc()), DS_Error)); + return {}; } RMBits = DAG.getConstant(FieldVal, DL, MVT::i16); } else { diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 0c9ba591b03eb..8ab8c66d76814 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1004,13 +1004,14 @@ namespace llvm { /// Current rounding mode is represented in bits 11:10 of FPSR. These /// values are same as corresponding constants for rounding mode used /// in glibc. - enum RoundingMode { - rmToNearest = 0, // FE_TONEAREST - rmDownward = 1 << 10, // FE_DOWNWARD - rmUpward = 2 << 10, // FE_UPWARD - rmTowardZero = 3 << 10, // FE_TOWARDZERO - rmMask = 3 << 10 // Bit mask selecting rounding mode - }; + enum RoundingMode { + rmInvalid = -1, // For handle Invalid rounding mode + rmToNearest = 0, // FE_TONEAREST + rmDownward = 1 << 10, // FE_DOWNWARD + rmUpward = 2 << 10, // FE_UPWARD + rmTowardZero = 3 << 10, // FE_TOWARDZERO + rmMask = 3 << 10 // Bit mask selecting rounding mode + }; } /// Define some predicates that are used for node matching. @@ -1058,6 +1059,10 @@ namespace llvm { /// functions. bool isExtendedSwiftAsyncFrameSupported(const X86Subtarget &Subtarget, const MachineFunction &MF); + + /// Convert LLVM rounding mode to X86 rounding mode. + int getRoundingModeX86(unsigned RM); + } // end namespace X86 //===--------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll index 49f9c386e91ed..d271e97d8832a 100644 --- a/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll +++ b/llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll @@ -30,7 +30,7 @@ define void @func_01() nounwind { ; 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: orw $3072, %ax # imm = 0xC00 +; GISEL-X86-NOSSE-NEXT: orw $24576, %ax # imm = 0x6000 ; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp) ; GISEL-X86-NOSSE-NEXT: fldcw (%esp) ; GISEL-X86-NOSSE-NEXT: popl %eax @@ -48,7 +48,7 @@ define void @func_01() nounwind { ; 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: orw $3072, %ax # imm = 0xC00 +; GISEL-X64-NOSSE-NEXT: orw $24576, %ax # imm = 0x6000 ; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: retq @@ -68,7 +68,7 @@ define void @func_01() nounwind { ; GISEL-X86-NEXT: fnstcw (%esp) ; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF ; GISEL-X86-NEXT: andw (%esp), %ax -; GISEL-X86-NEXT: orw $3072, %ax # imm = 0xC00 +; GISEL-X86-NEXT: orw $24576, %ax # imm = 0x6000 ; GISEL-X86-NEXT: movw %ax, (%esp) ; GISEL-X86-NEXT: fldcw (%esp) ; GISEL-X86-NEXT: popl %eax @@ -89,16 +89,14 @@ define void @func_01() nounwind { ; 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: orw $3072, %ax # imm = 0xC00 +; GISEL-X64-NEXT: orw $24576, %ax # imm = 0x6000 ; 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: 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) +; GISEL-X64-NEXT: orl $24576, %eax # imm = 0x6000 +; GISEL-X64-NEXT: movl %eax, -{{[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) @@ -186,10 +184,8 @@ define void @func_02() nounwind { ; 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: xorl %ecx, %ecx -; GISEL-X64-NEXT: shll $3, %ecx -; GISEL-X64-NEXT: orl %eax, %ecx -; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp) +; GISEL-X64-NEXT: orl $0, %eax +; GISEL-X64-NEXT: movl %eax, -{{[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) @@ -215,7 +211,7 @@ define void @func_03() nounwind { ; 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: orw $2048, %ax # imm = 0x800 +; GISEL-X86-NOSSE-NEXT: orw $16384, %ax # imm = 0x4000 ; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp) ; GISEL-X86-NOSSE-NEXT: fldcw (%esp) ; GISEL-X86-NOSSE-NEXT: popl %eax @@ -236,7 +232,7 @@ define void @func_03() nounwind { ; 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: orw $2048, %ax # imm = 0x800 +; GISEL-X64-NOSSE-NEXT: orw $16384, %ax # imm = 0x4000 ; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: retq @@ -259,7 +255,7 @@ define void @func_03() nounwind { ; GISEL-X86-NEXT: fnstcw (%esp) ; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF ; GISEL-X86-NEXT: andw (%esp), %ax -; GISEL-X86-NEXT: orw $2048, %ax # imm = 0x800 +; GISEL-X86-NEXT: orw $16384, %ax # imm = 0x4000 ; GISEL-X86-NEXT: movw %ax, (%esp) ; GISEL-X86-NEXT: fldcw (%esp) ; GISEL-X86-NEXT: popl %eax @@ -286,16 +282,14 @@ define void @func_03() nounwind { ; 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: orw $2048, %ax # imm = 0x800 +; GISEL-X64-NEXT: orw $16384, %ax # imm = 0x4000 ; 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: 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) +; GISEL-X64-NEXT: orl $16384, %eax # imm = 0x4000 +; GISEL-X64-NEXT: movl %eax, -{{[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) @@ -321,7 +315,7 @@ define void @func_04() nounwind { ; 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: orw $1024, %ax # imm = 0x400 +; GISEL-X86-NOSSE-NEXT: orw $8192, %ax # imm = 0x2000 ; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp) ; GISEL-X86-NOSSE-NEXT: fldcw (%esp) ; GISEL-X86-NOSSE-NEXT: popl %eax @@ -342,7 +336,7 @@ define void @func_04() nounwind { ; 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: orw $1024, %ax # imm = 0x400 +; GISEL-X64-NOSSE-NEXT: orw $8192, %ax # imm = 0x2000 ; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp) ; GISEL-X64-NOSSE-NEXT: retq @@ -365,7 +359,7 @@ define void @func_04() nounwind { ; GISEL-X86-NEXT: fnstcw (%esp) ; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF ; GISEL-X86-NEXT: andw (%esp), %ax -; GISEL-X86-NEXT: orw $1024, %ax # imm = 0x400 +; GISEL-X86-NEXT: orw $8192, %ax # imm = 0x2000 ; GISEL-X86-NEXT: movw %ax, (%esp) ; GISEL-X86-NEXT: fldcw (%esp) ; GISEL-X86-NEXT: popl %eax @@ -392,16 +386,14 @@ define void @func_04() nounwind { ; 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: orw $1024, %ax # imm = 0x400 +; GISEL-X64-NEXT: orw $8192, %ax # imm = 0x2000 ; 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: 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) +; GISEL-X64-NEXT: orl $8192, %eax # imm = 0x2000 +; GISEL-X64-NEXT: movl %eax, -{{[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) @@ -550,16 +542,16 @@ define void @func_05(i32 %x) nounwind { ; 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: movzwl %dx, %ecx +; GISEL-X64-NEXT: leal (,%rcx,8), %edx +; GISEL-X64-NEXT: orw %ax, %cx +; GISEL-X64-NEXT: movw %cx, -{{[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: orl %edx, %eax +; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp) ; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp) ; GISEL-X64-NEXT: retq call void @llvm.set.rounding(i32 %x) ; Downward diff --git a/llvm/test/TableGen/RegClassByHwMode.td b/llvm/test/TableGen/RegClassByHwMode.td index 5d813d2bfc83a..ca72cfbd403bf 100644 --- a/llvm/test/TableGen/RegClassByHwMode.td +++ b/llvm/test/TableGen/RegClassByHwMode.td @@ -50,7 +50,7 @@ include "llvm/Target/Target.td" // INSTRINFO-NEXT: }; // INSTRINFO: static inline void InitMyTargetMCInstrInfo( -// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, 321, &MyTargetRegClassByHwModeTables[0][0], 3); +// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, {{[0-9]+}}, &MyTargetRegClassByHwModeTables[0][0], 3); From 6437739489dec6b7130ebfb10084e8b190eedafd Mon Sep 17 00:00:00 2001 From: Chauhan Jaydeep Ashwinbhai Date: Thu, 25 Sep 2025 03:53:48 -0700 Subject: [PATCH 5/8] Added testcases for invalid rounding mode --- .../CodeGen/X86/isel-set-invalid-rounding.ll | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll diff --git a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll new file mode 100644 index 0000000000000..f00ff94a4fcc7 --- /dev/null +++ b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: not llc < %s -mtriple=i686-- -fast-isel -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=i686-- -global-isel=0 -fast-isel=0 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=i686-- -global-isel -global-isel-abort=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -fast-isel -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -global-isel=0 -fast-isel=0 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR + +; ERROR: error: isel-set-invalid-rounding:3:3: in function foo void (): rounding mode is not supported by X86 hardware + +source_filename = "isel-set-invalid-rounding" + +define dso_local void @foo() local_unnamed_addr !dbg !9 { +entry: + tail call void @llvm.set.rounding(i32 99), !dbg !12 + ret void, !dbg !13 +} + +declare void @llvm.set.rounding(i32) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7} +!llvm.ident = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "isel-set-invalid-rounding", directory: "/tmp") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{!"clang"} +!9 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !10, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true) +!10 = !DISubroutineType(types: !11) +!11 = !{null} +!12 = !DILocation(line: 3, column: 3, scope: !9) +!13 = !DILocation(line: 4, column: 1, scope: !9, atomGroup: 1, atomRank: 1) From 77e5d231682ac7d4007e5653ce04d48db906047f Mon Sep 17 00:00:00 2001 From: JaydeepChauhan14 Date: Thu, 25 Sep 2025 16:33:37 +0530 Subject: [PATCH 6/8] Update llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll Co-authored-by: Matt Arsenault --- llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll index f00ff94a4fcc7..b7b43b2993954 100644 --- a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll +++ b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll @@ -1,10 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 -; RUN: not llc < %s -mtriple=i686-- -fast-isel -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR -; RUN: not llc < %s -mtriple=i686-- -global-isel=0 -fast-isel=0 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR -; RUN: not llc < %s -mtriple=i686-- -global-isel -global-isel-abort=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR -; RUN: not llc < %s -mtriple=x86_64-- -fast-isel -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR -; RUN: not llc < %s -mtriple=x86_64-- -global-isel=0 -fast-isel=0 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR -; RUN: not llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=i686-- -fast-isel -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=i686-- -global-isel=0 -fast-isel=0 -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=i686-- -global-isel -global-isel-abort=1 -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -fast-isel -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -global-isel=0 -fast-isel=0 -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR +; RUN: not llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 -filetype=null 2>&1 | FileCheck %s --check-prefixes=ERROR ; ERROR: error: isel-set-invalid-rounding:3:3: in function foo void (): rounding mode is not supported by X86 hardware From af930007c8bc911d6b5587e93d2a189c5f3c9209 Mon Sep 17 00:00:00 2001 From: JaydeepChauhan14 Date: Thu, 25 Sep 2025 16:33:54 +0530 Subject: [PATCH 7/8] Update llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll Co-authored-by: Matt Arsenault --- llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll index b7b43b2993954..b1a73d3629b50 100644 --- a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll +++ b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll @@ -8,8 +8,6 @@ ; ERROR: error: isel-set-invalid-rounding:3:3: in function foo void (): rounding mode is not supported by X86 hardware -source_filename = "isel-set-invalid-rounding" - define dso_local void @foo() local_unnamed_addr !dbg !9 { entry: tail call void @llvm.set.rounding(i32 99), !dbg !12 From 2ce0c0484a6de21f407a00c4661bf8276156c456 Mon Sep 17 00:00:00 2001 From: JaydeepChauhan14 Date: Thu, 25 Sep 2025 16:34:05 +0530 Subject: [PATCH 8/8] Update llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll Co-authored-by: Matt Arsenault --- llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll index b1a73d3629b50..9fed9945532a0 100644 --- a/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll +++ b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll @@ -8,7 +8,7 @@ ; ERROR: error: isel-set-invalid-rounding:3:3: in function foo void (): rounding mode is not supported by X86 hardware -define dso_local void @foo() local_unnamed_addr !dbg !9 { +define void @foo() !dbg !9 { entry: tail call void @llvm.set.rounding(i32 99), !dbg !12 ret void, !dbg !13