Skip to content

Commit a998dad

Browse files
Addressed the review comments3
1 parent 900ebab commit a998dad

File tree

5 files changed

+79
-73
lines changed

5 files changed

+79
-73
lines changed

llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -898,26 +898,23 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
898898
// Check if Src is a constant
899899
auto *SrcDef = MRI.getVRegDef(Src);
900900
Register RMBits;
901+
Register MXCSRRMBits;
902+
901903
if (SrcDef && SrcDef->getOpcode() == TargetOpcode::G_CONSTANT) {
902904
uint64_t RM = getIConstantFromReg(Src, MRI).getZExtValue();
903-
int FieldVal;
904-
switch (static_cast<RoundingMode>(RM)) {
905-
case RoundingMode::NearestTiesToEven:
906-
FieldVal = X86::rmToNearest;
907-
break;
908-
case RoundingMode::TowardNegative:
909-
FieldVal = X86::rmDownward;
910-
break;
911-
case RoundingMode::TowardPositive:
912-
FieldVal = X86::rmUpward;
913-
break;
914-
case RoundingMode::TowardZero:
915-
FieldVal = X86::rmTowardZero;
916-
break;
917-
default:
918-
report_fatal_error("rounding mode is not supported by X86 hardware");
905+
int FieldVal = X86::getRoundingModeX86(RM);
906+
907+
if (FieldVal == X86::rmInvalid) {
908+
LLVMContext &C = MF.getFunction().getContext();
909+
C.diagnose(DiagnosticInfoUnsupported(
910+
MF.getFunction(), "rounding mode is not supported by X86 hardware",
911+
DiagnosticLocation(MI.getDebugLoc()), DS_Error));
912+
return false;
919913
}
914+
915+
FieldVal = FieldVal << 3;
920916
RMBits = MIRBuilder.buildConstant(s16, FieldVal).getReg(0);
917+
MXCSRRMBits = MIRBuilder.buildConstant(s32, FieldVal).getReg(0);
921918
} else {
922919
// Convert Src (rounding mode) to bits for control word
923920
// (0xc9 << (2 * Src + 4)) & 0xc00
@@ -931,6 +928,12 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
931928
RMBits =
932929
MIRBuilder.buildAnd(s16, Shifted, MIRBuilder.buildConstant(s16, 0xc00))
933930
.getReg(0);
931+
932+
// For non-constant case, we still need to compute MXCSR bits dynamically
933+
auto RMBits32 = MIRBuilder.buildZExt(s32, RMBits);
934+
MXCSRRMBits =
935+
MIRBuilder.buildShl(s32, RMBits32, MIRBuilder.buildConstant(s32, 3))
936+
.getReg(0);
934937
}
935938
// Update rounding mode bits
936939
auto NewCWD =
@@ -966,11 +969,6 @@ bool X86LegalizerInfo::legalizeSETROUNDING(MachineInstr &MI,
966969
auto ClearedMXCSR = MIRBuilder.buildAnd(
967970
s32, MXCSR, MIRBuilder.buildConstant(s32, 0xffff9fff));
968971

969-
// Shift x87 RM bits from 11:10 to 14:13
970-
auto RMBits32 = MIRBuilder.buildZExt(s32, RMBits);
971-
auto MXCSRRMBits =
972-
MIRBuilder.buildShl(s32, RMBits32, MIRBuilder.buildConstant(s32, 3));
973-
974972
// Update rounding mode bits
975973
auto NewMXCSR = MIRBuilder.buildOr(s32, ClearedMXCSR, MXCSRRMBits);
976974

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5346,6 +5346,19 @@ bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs) {
53465346

53475347
return false;
53485348
}
5349+
5350+
int getRoundingModeX86(unsigned RM) {
5351+
switch (static_cast<::llvm::RoundingMode>(RM)) {
5352+
// clang-format off
5353+
case ::llvm::RoundingMode::NearestTiesToEven: return X86::rmToNearest; break;
5354+
case ::llvm::RoundingMode::TowardNegative: return X86::rmDownward; break;
5355+
case ::llvm::RoundingMode::TowardPositive: return X86::rmUpward; break;
5356+
case ::llvm::RoundingMode::TowardZero: return X86::rmTowardZero; break;
5357+
default:
5358+
return X86::rmInvalid; // Invalid rounding mode
5359+
}
5360+
}
5361+
53495362
} // namespace X86
53505363
} // namespace llvm
53515364

@@ -28698,16 +28711,14 @@ SDValue X86TargetLowering::LowerSET_ROUNDING(SDValue Op,
2869828711
SDValue RMBits;
2869928712
if (auto *CVal = dyn_cast<ConstantSDNode>(NewRM)) {
2870028713
uint64_t RM = CVal->getZExtValue();
28701-
int FieldVal;
28702-
switch (static_cast<RoundingMode>(RM)) {
28703-
// clang-format off
28704-
case RoundingMode::NearestTiesToEven: FieldVal = X86::rmToNearest; break;
28705-
case RoundingMode::TowardNegative: FieldVal = X86::rmDownward; break;
28706-
case RoundingMode::TowardPositive: FieldVal = X86::rmUpward; break;
28707-
case RoundingMode::TowardZero: FieldVal = X86::rmTowardZero; break;
28708-
default:
28709-
llvm_unreachable("rounding mode is not supported by X86 hardware");
28710-
// clang-format on
28714+
int FieldVal = X86::getRoundingModeX86(RM);
28715+
28716+
if (FieldVal == X86::rmInvalid) {
28717+
LLVMContext &C = MF.getFunction().getContext();
28718+
C.diagnose(DiagnosticInfoUnsupported(
28719+
MF.getFunction(), "rounding mode is not supported by X86 hardware",
28720+
DiagnosticLocation(DL.getDebugLoc()), DS_Error));
28721+
return {};
2871128722
}
2871228723
RMBits = DAG.getConstant(FieldVal, DL, MVT::i16);
2871328724
} else {

llvm/lib/Target/X86/X86ISelLowering.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,13 +1004,14 @@ namespace llvm {
10041004
/// Current rounding mode is represented in bits 11:10 of FPSR. These
10051005
/// values are same as corresponding constants for rounding mode used
10061006
/// in glibc.
1007-
enum RoundingMode {
1008-
rmToNearest = 0, // FE_TONEAREST
1009-
rmDownward = 1 << 10, // FE_DOWNWARD
1010-
rmUpward = 2 << 10, // FE_UPWARD
1011-
rmTowardZero = 3 << 10, // FE_TOWARDZERO
1012-
rmMask = 3 << 10 // Bit mask selecting rounding mode
1013-
};
1007+
enum RoundingMode {
1008+
rmInvalid = -1, // For handle Invalid rounding mode
1009+
rmToNearest = 0, // FE_TONEAREST
1010+
rmDownward = 1 << 10, // FE_DOWNWARD
1011+
rmUpward = 2 << 10, // FE_UPWARD
1012+
rmTowardZero = 3 << 10, // FE_TOWARDZERO
1013+
rmMask = 3 << 10 // Bit mask selecting rounding mode
1014+
};
10141015
}
10151016

10161017
/// Define some predicates that are used for node matching.
@@ -1058,6 +1059,10 @@ namespace llvm {
10581059
/// functions.
10591060
bool isExtendedSwiftAsyncFrameSupported(const X86Subtarget &Subtarget,
10601061
const MachineFunction &MF);
1062+
1063+
/// Convert LLVM rounding mode to X86 rounding mode.
1064+
int getRoundingModeX86(unsigned RM);
1065+
10611066
} // end namespace X86
10621067

10631068
//===--------------------------------------------------------------------===//

llvm/test/CodeGen/X86/isel-llvm.set.rounding.ll

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ define void @func_01() nounwind {
3030
; GISEL-X86-NOSSE-NEXT: fnstcw (%esp)
3131
; GISEL-X86-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
3232
; GISEL-X86-NOSSE-NEXT: andw (%esp), %ax
33-
; GISEL-X86-NOSSE-NEXT: orw $3072, %ax # imm = 0xC00
33+
; GISEL-X86-NOSSE-NEXT: orw $24576, %ax # imm = 0x6000
3434
; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp)
3535
; GISEL-X86-NOSSE-NEXT: fldcw (%esp)
3636
; GISEL-X86-NOSSE-NEXT: popl %eax
@@ -48,7 +48,7 @@ define void @func_01() nounwind {
4848
; GISEL-X64-NOSSE-NEXT: fnstcw -{{[0-9]+}}(%rsp)
4949
; GISEL-X64-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
5050
; GISEL-X64-NOSSE-NEXT: andw -{{[0-9]+}}(%rsp), %ax
51-
; GISEL-X64-NOSSE-NEXT: orw $3072, %ax # imm = 0xC00
51+
; GISEL-X64-NOSSE-NEXT: orw $24576, %ax # imm = 0x6000
5252
; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
5353
; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp)
5454
; GISEL-X64-NOSSE-NEXT: retq
@@ -68,7 +68,7 @@ define void @func_01() nounwind {
6868
; GISEL-X86-NEXT: fnstcw (%esp)
6969
; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF
7070
; GISEL-X86-NEXT: andw (%esp), %ax
71-
; GISEL-X86-NEXT: orw $3072, %ax # imm = 0xC00
71+
; GISEL-X86-NEXT: orw $24576, %ax # imm = 0x6000
7272
; GISEL-X86-NEXT: movw %ax, (%esp)
7373
; GISEL-X86-NEXT: fldcw (%esp)
7474
; GISEL-X86-NEXT: popl %eax
@@ -89,16 +89,14 @@ define void @func_01() nounwind {
8989
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
9090
; GISEL-X64-NEXT: movw $-3073, %ax # imm = 0xF3FF
9191
; GISEL-X64-NEXT: andw -{{[0-9]+}}(%rsp), %ax
92-
; GISEL-X64-NEXT: orw $3072, %ax # imm = 0xC00
92+
; GISEL-X64-NEXT: orw $24576, %ax # imm = 0x6000
9393
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
9494
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
9595
; GISEL-X64-NEXT: stmxcsr -{{[0-9]+}}(%rsp)
9696
; GISEL-X64-NEXT: movl $-24577, %eax # imm = 0x9FFF
9797
; GISEL-X64-NEXT: andl -{{[0-9]+}}(%rsp), %eax
98-
; GISEL-X64-NEXT: movl $3072, %ecx # imm = 0xC00
99-
; GISEL-X64-NEXT: shll $3, %ecx
100-
; GISEL-X64-NEXT: orl %eax, %ecx
101-
; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
98+
; GISEL-X64-NEXT: orl $24576, %eax # imm = 0x6000
99+
; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
102100
; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp)
103101
; GISEL-X64-NEXT: retq
104102
call void @llvm.set.rounding(i32 0) ; TowardZero (CW[11-10] = 11)
@@ -186,10 +184,8 @@ define void @func_02() nounwind {
186184
; GISEL-X64-NEXT: stmxcsr -{{[0-9]+}}(%rsp)
187185
; GISEL-X64-NEXT: movl $-24577, %eax # imm = 0x9FFF
188186
; GISEL-X64-NEXT: andl -{{[0-9]+}}(%rsp), %eax
189-
; GISEL-X64-NEXT: xorl %ecx, %ecx
190-
; GISEL-X64-NEXT: shll $3, %ecx
191-
; GISEL-X64-NEXT: orl %eax, %ecx
192-
; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
187+
; GISEL-X64-NEXT: orl $0, %eax
188+
; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
193189
; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp)
194190
; GISEL-X64-NEXT: retq
195191
call void @llvm.set.rounding(i32 1) ; ToNearestTiesToEven (CW[11-10] = 00)
@@ -215,7 +211,7 @@ define void @func_03() nounwind {
215211
; GISEL-X86-NOSSE-NEXT: fnstcw (%esp)
216212
; GISEL-X86-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
217213
; GISEL-X86-NOSSE-NEXT: andw (%esp), %ax
218-
; GISEL-X86-NOSSE-NEXT: orw $2048, %ax # imm = 0x800
214+
; GISEL-X86-NOSSE-NEXT: orw $16384, %ax # imm = 0x4000
219215
; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp)
220216
; GISEL-X86-NOSSE-NEXT: fldcw (%esp)
221217
; GISEL-X86-NOSSE-NEXT: popl %eax
@@ -236,7 +232,7 @@ define void @func_03() nounwind {
236232
; GISEL-X64-NOSSE-NEXT: fnstcw -{{[0-9]+}}(%rsp)
237233
; GISEL-X64-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
238234
; GISEL-X64-NOSSE-NEXT: andw -{{[0-9]+}}(%rsp), %ax
239-
; GISEL-X64-NOSSE-NEXT: orw $2048, %ax # imm = 0x800
235+
; GISEL-X64-NOSSE-NEXT: orw $16384, %ax # imm = 0x4000
240236
; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
241237
; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp)
242238
; GISEL-X64-NOSSE-NEXT: retq
@@ -259,7 +255,7 @@ define void @func_03() nounwind {
259255
; GISEL-X86-NEXT: fnstcw (%esp)
260256
; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF
261257
; GISEL-X86-NEXT: andw (%esp), %ax
262-
; GISEL-X86-NEXT: orw $2048, %ax # imm = 0x800
258+
; GISEL-X86-NEXT: orw $16384, %ax # imm = 0x4000
263259
; GISEL-X86-NEXT: movw %ax, (%esp)
264260
; GISEL-X86-NEXT: fldcw (%esp)
265261
; GISEL-X86-NEXT: popl %eax
@@ -286,16 +282,14 @@ define void @func_03() nounwind {
286282
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
287283
; GISEL-X64-NEXT: movw $-3073, %ax # imm = 0xF3FF
288284
; GISEL-X64-NEXT: andw -{{[0-9]+}}(%rsp), %ax
289-
; GISEL-X64-NEXT: orw $2048, %ax # imm = 0x800
285+
; GISEL-X64-NEXT: orw $16384, %ax # imm = 0x4000
290286
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
291287
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
292288
; GISEL-X64-NEXT: stmxcsr -{{[0-9]+}}(%rsp)
293289
; GISEL-X64-NEXT: movl $-24577, %eax # imm = 0x9FFF
294290
; GISEL-X64-NEXT: andl -{{[0-9]+}}(%rsp), %eax
295-
; GISEL-X64-NEXT: movl $2048, %ecx # imm = 0x800
296-
; GISEL-X64-NEXT: shll $3, %ecx
297-
; GISEL-X64-NEXT: orl %eax, %ecx
298-
; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
291+
; GISEL-X64-NEXT: orl $16384, %eax # imm = 0x4000
292+
; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
299293
; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp)
300294
; GISEL-X64-NEXT: retq
301295
call void @llvm.set.rounding(i32 2) ; Upward (CW[11-10] = 10)
@@ -321,7 +315,7 @@ define void @func_04() nounwind {
321315
; GISEL-X86-NOSSE-NEXT: fnstcw (%esp)
322316
; GISEL-X86-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
323317
; GISEL-X86-NOSSE-NEXT: andw (%esp), %ax
324-
; GISEL-X86-NOSSE-NEXT: orw $1024, %ax # imm = 0x400
318+
; GISEL-X86-NOSSE-NEXT: orw $8192, %ax # imm = 0x2000
325319
; GISEL-X86-NOSSE-NEXT: movw %ax, (%esp)
326320
; GISEL-X86-NOSSE-NEXT: fldcw (%esp)
327321
; GISEL-X86-NOSSE-NEXT: popl %eax
@@ -342,7 +336,7 @@ define void @func_04() nounwind {
342336
; GISEL-X64-NOSSE-NEXT: fnstcw -{{[0-9]+}}(%rsp)
343337
; GISEL-X64-NOSSE-NEXT: movw $-3073, %ax # imm = 0xF3FF
344338
; GISEL-X64-NOSSE-NEXT: andw -{{[0-9]+}}(%rsp), %ax
345-
; GISEL-X64-NOSSE-NEXT: orw $1024, %ax # imm = 0x400
339+
; GISEL-X64-NOSSE-NEXT: orw $8192, %ax # imm = 0x2000
346340
; GISEL-X64-NOSSE-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
347341
; GISEL-X64-NOSSE-NEXT: fldcw -{{[0-9]+}}(%rsp)
348342
; GISEL-X64-NOSSE-NEXT: retq
@@ -365,7 +359,7 @@ define void @func_04() nounwind {
365359
; GISEL-X86-NEXT: fnstcw (%esp)
366360
; GISEL-X86-NEXT: movw $-3073, %ax # imm = 0xF3FF
367361
; GISEL-X86-NEXT: andw (%esp), %ax
368-
; GISEL-X86-NEXT: orw $1024, %ax # imm = 0x400
362+
; GISEL-X86-NEXT: orw $8192, %ax # imm = 0x2000
369363
; GISEL-X86-NEXT: movw %ax, (%esp)
370364
; GISEL-X86-NEXT: fldcw (%esp)
371365
; GISEL-X86-NEXT: popl %eax
@@ -392,16 +386,14 @@ define void @func_04() nounwind {
392386
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
393387
; GISEL-X64-NEXT: movw $-3073, %ax # imm = 0xF3FF
394388
; GISEL-X64-NEXT: andw -{{[0-9]+}}(%rsp), %ax
395-
; GISEL-X64-NEXT: orw $1024, %ax # imm = 0x400
389+
; GISEL-X64-NEXT: orw $8192, %ax # imm = 0x2000
396390
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
397391
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
398392
; GISEL-X64-NEXT: stmxcsr -{{[0-9]+}}(%rsp)
399393
; GISEL-X64-NEXT: movl $-24577, %eax # imm = 0x9FFF
400394
; GISEL-X64-NEXT: andl -{{[0-9]+}}(%rsp), %eax
401-
; GISEL-X64-NEXT: movl $1024, %ecx # imm = 0x400
402-
; GISEL-X64-NEXT: shll $3, %ecx
403-
; GISEL-X64-NEXT: orl %eax, %ecx
404-
; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
395+
; GISEL-X64-NEXT: orl $8192, %eax # imm = 0x2000
396+
; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
405397
; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp)
406398
; GISEL-X64-NEXT: retq
407399
call void @llvm.set.rounding(i32 3) ; Downward (CW[11-10] = 01)
@@ -550,16 +542,16 @@ define void @func_05(i32 %x) nounwind {
550542
; GISEL-X64-NEXT: # kill: def $cl killed $cl killed $ecx
551543
; GISEL-X64-NEXT: shlw %cl, %dx
552544
; GISEL-X64-NEXT: andw $3072, %dx # imm = 0xC00
553-
; GISEL-X64-NEXT: orw %dx, %ax
554-
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
545+
; GISEL-X64-NEXT: movzwl %dx, %ecx
546+
; GISEL-X64-NEXT: leal (,%rcx,8), %edx
547+
; GISEL-X64-NEXT: orw %ax, %cx
548+
; GISEL-X64-NEXT: movw %cx, -{{[0-9]+}}(%rsp)
555549
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
556550
; GISEL-X64-NEXT: stmxcsr -{{[0-9]+}}(%rsp)
557551
; GISEL-X64-NEXT: movl $-24577, %eax # imm = 0x9FFF
558552
; GISEL-X64-NEXT: andl -{{[0-9]+}}(%rsp), %eax
559-
; GISEL-X64-NEXT: movzwl %dx, %ecx
560-
; GISEL-X64-NEXT: shll $3, %ecx
561-
; GISEL-X64-NEXT: orl %eax, %ecx
562-
; GISEL-X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
553+
; GISEL-X64-NEXT: orl %edx, %eax
554+
; GISEL-X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
563555
; GISEL-X64-NEXT: ldmxcsr -{{[0-9]+}}(%rsp)
564556
; GISEL-X64-NEXT: retq
565557
call void @llvm.set.rounding(i32 %x) ; Downward

llvm/test/TableGen/RegClassByHwMode.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ include "llvm/Target/Target.td"
5050
// INSTRINFO-NEXT: };
5151

5252
// INSTRINFO: static inline void InitMyTargetMCInstrInfo(
53-
// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, 321, &MyTargetRegClassByHwModeTables[0][0], 3);
53+
// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, {{[0-9]+}}, &MyTargetRegClassByHwModeTables[0][0], 3);
5454

5555

5656

0 commit comments

Comments
 (0)