[llvm] 0c1087b - [X86][GlobalISel] Added support for llvm.set.rounding (#156591)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 25 06:44:51 PDT 2025
Author: JaydeepChauhan14
Date: 2025-09-25T22:44:47+09:00
New Revision: 0c1087b377b49dafaa7d82942db11c2fd3fd4c11
URL: https://github.com/llvm/llvm-project/commit/0c1087b377b49dafaa7d82942db11c2fd3fd4c11
DIFF: https://github.com/llvm/llvm-project/commit/0c1087b377b49dafaa7d82942db11c2fd3fd4c11.diff
LOG: [X86][GlobalISel] Added support for llvm.set.rounding (#156591)
- This implementation is adapted from **SDAG
X86TargetLowering::LowerSET_ROUNDING**.
Added:
llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll
Modified:
llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
llvm/include/llvm/Support/TargetOpcodes.def
llvm/include/llvm/Target/GenericOpcodes.td
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/lib/Target/X86/X86ISelLowering.h
llvm/lib/Target/X86/X86InstrGISel.td
llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll
llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
llvm/test/TableGen/RegClassByHwMode.td
Removed:
################################################################################
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 12b735e053bde..56e13f075aaac 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 2c752457d165e..ee9760f881ae9 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;
@@ -110,7 +111,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}) {
@@ -617,6 +619,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");
}
@@ -859,6 +863,133 @@ 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));
+
+ // 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 = 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
+ 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);
+
+ // 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 =
+ MIRBuilder.buildOr(s16, ClearedCWD, RMBits, MachineInstr::Disjoint);
+
+ // 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));
+
+ // 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/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<ConstantSDNode>(NewRM)) {
uint64_t RM = CVal->getZExtValue();
- int FieldVal;
- switch (static_cast<RoundingMode>(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/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 86084ae531cdb..7204064a07f40 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -635,6 +635,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..d271e97d8832a 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,18 @@ 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: orw $24576, %ax # imm = 0x6000
+; GISEL-X86-NOSSE-NEXT: movw %ax, (%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 +43,16 @@ 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: 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
+;
; X86-LABEL: func_01:
; X86: # %bb.0:
; X86-NEXT: pushl %eax
@@ -40,6 +62,18 @@ 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: orw $24576, %ax # imm = 0x6000
+; GISEL-X86-NEXT: movw %ax, (%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 +83,22 @@ 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: 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: 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)
ret void
}
@@ -63,6 +113,18 @@ 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: 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
+;
; X64-NOSSE-LABEL: func_02:
; X64-NOSSE: # %bb.0:
; X64-NOSSE-NEXT: fnstcw -{{[0-9]+}}(%rsp)
@@ -70,6 +132,16 @@ 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: 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
+;
; X86-LABEL: func_02:
; X86: # %bb.0:
; X86-NEXT: pushl %eax
@@ -79,6 +151,18 @@ 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: orw $0, %ax
+; GISEL-X86-NEXT: movw %ax, (%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 +172,22 @@ 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: 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: 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)
ret void
}
@@ -105,6 +205,18 @@ 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: orw $16384, %ax # imm = 0x4000
+; GISEL-X86-NOSSE-NEXT: movw %ax, (%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 +227,16 @@ 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: 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
+;
; X86-LABEL: func_03:
; X86: # %bb.0:
; X86-NEXT: pushl %eax
@@ -127,6 +249,18 @@ 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: orw $16384, %ax # imm = 0x4000
+; GISEL-X86-NEXT: movw %ax, (%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 +276,22 @@ 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: 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: 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)
ret void
}
@@ -159,6 +309,18 @@ 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: orw $8192, %ax # imm = 0x2000
+; GISEL-X86-NOSSE-NEXT: movw %ax, (%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 +331,16 @@ 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: 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
+;
; X86-LABEL: func_04:
; X86: # %bb.0:
; X86-NEXT: pushl %eax
@@ -181,6 +353,18 @@ 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: orw $8192, %ax # imm = 0x2000
+; GISEL-X86-NEXT: movw %ax, (%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 +380,22 @@ 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: 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: 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)
ret void
}
@@ -219,6 +419,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 +454,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 +489,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 +529,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: 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: 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
ret void
}
@@ -284,10 +564,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/CodeGen/X86/isel-set-invalid-rounding.ll b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll
new file mode 100644
index 0000000000000..9fed9945532a0
--- /dev/null
+++ b/llvm/test/CodeGen/X86/isel-set-invalid-rounding.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; 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
+
+define void @foo() !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)
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,
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);
More information about the llvm-commits
mailing list