Skip to content

Commit 6f375b3

Browse files
committed
[Xtensa] Implement lowering constant FP and blockaddress.
1 parent 3f58dbe commit 6f375b3

File tree

6 files changed

+203
-29
lines changed

6 files changed

+203
-29
lines changed

llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp

+92-26
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//===----------------------------------------------------------------------===//
1515

1616
#include "XtensaAsmPrinter.h"
17+
#include "XtensaConstantPoolValue.h"
1718
#include "TargetInfo/XtensaTargetInfo.h"
1819
#include "XtensaMCInstLower.h"
1920
#include "llvm/ADT/StringExtras.h"
@@ -30,13 +31,103 @@
3031

3132
using namespace llvm;
3233

34+
static MCSymbolRefExpr::VariantKind
35+
getModifierVariantKind(XtensaCP::XtensaCPModifier Modifier) {
36+
switch (Modifier) {
37+
case XtensaCP::no_modifier:
38+
return MCSymbolRefExpr::VK_None;
39+
case XtensaCP::TPOFF:
40+
return MCSymbolRefExpr::VK_TPOFF;
41+
}
42+
report_fatal_error("Invalid XtensaCPModifier!");
43+
}
44+
3345
void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
3446
XtensaMCInstLower Lower(MF->getContext(), *this);
3547
MCInst LoweredMI;
3648
Lower.lower(MI, LoweredMI);
3749
EmitToStreamer(*OutStreamer, LoweredMI);
3850
}
3951

52+
void XtensaAsmPrinter::emitMachineConstantPoolValue(
53+
MachineConstantPoolValue *MCPV) {
54+
XtensaConstantPoolValue *ACPV = static_cast<XtensaConstantPoolValue *>(MCPV);
55+
56+
MCSymbol *MCSym;
57+
if (ACPV->isBlockAddress()) {
58+
const BlockAddress *BA =
59+
cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();
60+
MCSym = GetBlockAddressSymbol(BA);
61+
} else {
62+
report_fatal_error(
63+
"This constant type is not supported yet in constantpool");
64+
}
65+
66+
MCSymbol *LblSym = GetCPISymbol(ACPV->getLabelId());
67+
// TODO find a better way to check whether we emit data to .s file
68+
if (OutStreamer->hasRawTextSupport()) {
69+
std::string SymName("\t.literal ");
70+
SymName += LblSym->getName();
71+
SymName += ", ";
72+
SymName += MCSym->getName();
73+
74+
StringRef Modifier = ACPV->getModifierText();
75+
SymName += Modifier;
76+
77+
OutStreamer->emitRawText(StringRef(SymName));
78+
} else {
79+
MCSymbolRefExpr::VariantKind VK =
80+
getModifierVariantKind(ACPV->getModifier());
81+
82+
if (ACPV->getModifier() != XtensaCP::no_modifier) {
83+
std::string SymName(MCSym->getName());
84+
MCSym = GetExternalSymbolSymbol(StringRef(SymName));
85+
}
86+
87+
const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, VK, OutContext);
88+
uint64_t Size = getDataLayout().getTypeAllocSize(ACPV->getType());
89+
OutStreamer->emitCodeAlignment(
90+
Align(4), OutStreamer->getContext().getSubtargetInfo());
91+
OutStreamer->emitLabel(LblSym);
92+
OutStreamer->emitValue(Expr, Size);
93+
}
94+
}
95+
96+
void XtensaAsmPrinter::emitMachineConstantPoolEntry(
97+
const MachineConstantPoolEntry &CPE, int i) {
98+
if (CPE.isMachineConstantPoolEntry()) {
99+
XtensaConstantPoolValue *ACPV =
100+
static_cast<XtensaConstantPoolValue *>(CPE.Val.MachineCPVal);
101+
ACPV->setLabelId(i);
102+
emitMachineConstantPoolValue(CPE.Val.MachineCPVal);
103+
} else {
104+
MCSymbol *LblSym = GetCPISymbol(i);
105+
// TODO find a better way to check whether we emit data to .s file
106+
if (OutStreamer->hasRawTextSupport()) {
107+
std::string str("\t.literal ");
108+
str += LblSym->getName();
109+
str += ", ";
110+
const Constant *C = CPE.Val.ConstVal;
111+
112+
if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
113+
str += toString(CFP->getValueAPF().bitcastToAPInt(), 10, true);
114+
} else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
115+
str += toString(CI->getValue(), 10, true);
116+
} else {
117+
report_fatal_error(
118+
"This constant type is not supported yet in constantpool");
119+
}
120+
121+
OutStreamer->emitRawText(StringRef(str));
122+
} else {
123+
OutStreamer->emitCodeAlignment(
124+
Align(4), OutStreamer->getContext().getSubtargetInfo());
125+
OutStreamer->emitLabel(LblSym);
126+
emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);
127+
}
128+
}
129+
}
130+
40131
/// EmitConstantPool - Print to the current output stream assembly
41132
/// representations of the constants in the constant pool MCP. This is
42133
/// used to print out constants which have been "spilled to memory" by
@@ -82,32 +173,7 @@ void XtensaAsmPrinter::emitConstantPool() {
82173
}
83174
}
84175

85-
if (CPE.isMachineConstantPoolEntry()) {
86-
report_fatal_error("This constantpool type is not supported yet");
87-
} else {
88-
MCSymbol *LblSym = GetCPISymbol(i);
89-
// TODO find a better way to check whether we emit data to .s file
90-
if (OutStreamer->hasRawTextSupport()) {
91-
std::string str("\t.literal ");
92-
str += LblSym->getName();
93-
str += ", ";
94-
const Constant *C = CPE.Val.ConstVal;
95-
96-
if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
97-
str += toString(CFP->getValueAPF().bitcastToAPInt(), 10, true);
98-
} else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
99-
str += toString(CI->getValue(), 10, true);
100-
} else {
101-
report_fatal_error(
102-
"This constant type is not supported yet in constantpool");
103-
}
104-
105-
OutStreamer->emitRawText(StringRef(str));
106-
} else {
107-
OutStreamer->emitLabel(LblSym);
108-
emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);
109-
}
110-
}
176+
emitMachineConstantPoolEntry(CPE, i);
111177
}
112178
}
113179

llvm/lib/Target/Xtensa/XtensaAsmPrinter.h

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "XtensaTargetMachine.h"
1919
#include "llvm/CodeGen/AsmPrinter.h"
20+
#include "llvm/CodeGen/MachineConstantPool.h"
2021
#include "llvm/Support/Compiler.h"
2122

2223
namespace llvm {
@@ -37,6 +38,8 @@ class LLVM_LIBRARY_VISIBILITY XtensaAsmPrinter : public AsmPrinter {
3738
StringRef getPassName() const override { return "Xtensa Assembly Printer"; }
3839
void emitInstruction(const MachineInstr *MI) override;
3940
void emitConstantPool() override;
41+
void emitMachineConstantPoolEntry(const MachineConstantPoolEntry &CPE, int i);
42+
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
4043
};
4144
} // end namespace llvm
4245

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

+43-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//
1414
//===----------------------------------------------------------------------===//
1515

16+
#include "XtensaConstantPoolValue.h"
1617
#include "XtensaISelLowering.h"
1718
#include "XtensaSubtarget.h"
1819
#include "XtensaTargetMachine.h"
@@ -49,6 +50,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
4950

5051
setOperationAction(ISD::Constant, MVT::i32, Custom);
5152
setOperationAction(ISD::Constant, MVT::i64, Expand);
53+
setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
54+
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
5255

5356
// No sign extend instructions for i1
5457
for (MVT VT : MVT::integer_valuetypes()) {
@@ -58,11 +61,17 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
5861
}
5962

6063
setOperationAction(ISD::ConstantPool, PtrVT, Custom);
64+
setOperationAction(ISD::BlockAddress, PtrVT, Custom);
6165

6266
// Compute derived properties from the register classes
6367
computeRegisterProperties(STI.getRegisterInfo());
6468
}
6569

70+
bool XtensaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
71+
bool ForCodeSize) const {
72+
return false;
73+
}
74+
6675
//===----------------------------------------------------------------------===//
6776
// Calling conventions
6877
//===----------------------------------------------------------------------===//
@@ -343,6 +352,31 @@ SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
343352
return Op;
344353
}
345354

355+
SDValue XtensaTargetLowering::LowerImmediateFP(SDValue Op, SelectionDAG & DAG)
356+
const {
357+
if (Op.getValueType() != MVT::f32)
358+
return Op;
359+
const ConstantFPSDNode *CN = cast<ConstantFPSDNode>(Op);
360+
SDLoc DL(CN);
361+
APFloat apval = CN->getValueAPF();
362+
int64_t value = llvm::bit_cast<uint32_t>(apval.convertToFloat());
363+
Type *Ty = Type::getInt32Ty(*DAG.getContext());
364+
Constant *CV = ConstantInt::get(Ty, value);
365+
SDValue CP = DAG.getConstantPool(CV, MVT::i32);
366+
return DAG.getNode(ISD::BITCAST, DL, MVT::f32, CP);
367+
}
368+
369+
SDValue XtensaTargetLowering::LowerBlockAddress(BlockAddressSDNode *Node,
370+
SelectionDAG &DAG) const {
371+
const BlockAddress *BA = Node->getBlockAddress();
372+
EVT PtrVT = getPointerTy(DAG.getDataLayout());
373+
XtensaConstantPoolValue *CPV =
374+
XtensaConstantPoolConstant::Create(BA, 0, XtensaCP::CPBlockAddress);
375+
SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
376+
SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
377+
return CPWrap;
378+
}
379+
346380
SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
347381
SelectionDAG &DAG) const {
348382
SDLoc DL(Op);
@@ -354,11 +388,13 @@ SDValue XtensaTargetLowering::LowerConstantPool(ConstantPoolSDNode *CP,
354388
SelectionDAG &DAG) const {
355389
EVT PtrVT = getPointerTy(DAG.getDataLayout());
356390
SDValue Result;
357-
if (!CP->isMachineConstantPoolEntry()) {
391+
392+
if (CP->isMachineConstantPoolEntry()) {
393+
Result =
394+
DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, CP->getAlign());
395+
} else {
358396
Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
359397
CP->getOffset());
360-
} else {
361-
report_fatal_error("This constantpool type is not supported yet");
362398
}
363399

364400
return getAddrPCRel(Result, DAG);
@@ -369,6 +405,10 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
369405
switch (Op.getOpcode()) {
370406
case ISD::Constant:
371407
return LowerImmediate(Op, DAG);
408+
case ISD::ConstantFP:
409+
return LowerImmediateFP(Op, DAG);
410+
case ISD::BlockAddress:
411+
return LowerBlockAddress(cast<BlockAddressSDNode>(Op), DAG);
372412
case ISD::ConstantPool:
373413
return LowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
374414
default:

llvm/lib/Target/Xtensa/XtensaISelLowering.h

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class XtensaTargetLowering : public TargetLowering {
3838
explicit XtensaTargetLowering(const TargetMachine &TM,
3939
const XtensaSubtarget &STI);
4040

41+
bool isFPImmLegal(const APFloat &Imm, EVT VT,
42+
bool ForCodeSize) const override;
4143
const char *getTargetNodeName(unsigned Opcode) const override;
4244
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
4345
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
@@ -60,6 +62,8 @@ class XtensaTargetLowering : public TargetLowering {
6062
const XtensaSubtarget &Subtarget;
6163

6264
SDValue LowerImmediate(SDValue Op, SelectionDAG &DAG) const;
65+
SDValue LowerImmediateFP(SDValue Op, SelectionDAG &DAG) const;
66+
SDValue LowerBlockAddress(BlockAddressSDNode *Node, SelectionDAG &DAG) const;
6367
SDValue LowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
6468

6569
SDValue getAddrPCRel(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/Xtensa/XtensaMCInstLower.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ XtensaMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
4242
XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
4343

4444
switch (MOTy) {
45+
case MachineOperand::MO_MachineBasicBlock:
46+
Symbol = MO.getMBB()->getSymbol();
47+
break;
48+
case MachineOperand::MO_BlockAddress:
49+
Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
50+
Offset += MO.getOffset();
51+
break;
4552
case MachineOperand::MO_ConstantPoolIndex:
4653
Symbol = GetConstantPoolIndexSymbol(MO);
4754
Offset += MO.getOffset();
@@ -79,6 +86,8 @@ MCOperand XtensaMCInstLower::lowerOperand(const MachineOperand &MO,
7986
return MCOperand::createImm(MO.getImm() + Offset);
8087
case MachineOperand::MO_RegisterMask:
8188
break;
89+
case MachineOperand::MO_MachineBasicBlock:
90+
case MachineOperand::MO_BlockAddress:
8291
case MachineOperand::MO_ConstantPoolIndex:
8392
return LowerSymbolOperand(MO, MOTy, Offset);
8493
default:

llvm/test/CodeGen/Xtensa/constantpool.ll

+52
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,55 @@ define dso_local i64 @const_int64() #0 {
2626
%2 = load i64, ptr %1, align 8
2727
ret i64 %2
2828
}
29+
30+
define dso_local float @const_fp() #0 {
31+
; CHECK: .literal_position
32+
; CHECK-NEXT: .literal .LCPI2_0, 1092721050
33+
; CHECK-LABEL: const_fp:
34+
; CHECK: l32r a2, .LCPI2_0
35+
%1 = alloca float, align 4
36+
store float 0x4024333340000000, ptr %1, align 4
37+
%2 = load float, ptr %1, align 4
38+
ret float %2
39+
}
40+
41+
define dso_local i64 @const_double() #0 {
42+
; CHECK: .literal_position
43+
; CHECK-NEXT: .literal .LCPI3_0, 1070945621
44+
; CHECK-NEXT: .literal .LCPI3_1, 1371607770
45+
; CHECK-LABEL: const_double:
46+
; CHECK: l32r a3, .LCPI3_0
47+
; CHECK: l32r a2, .LCPI3_1
48+
%1 = alloca double, align 8
49+
%2 = alloca double, align 8
50+
store double 0x3FD5555551C112DA, ptr %2, align 8
51+
%3 = load double, ptr %2, align 8
52+
store double %3, ptr %1, align 8
53+
%4 = load i64, ptr %1, align 8
54+
ret i64 %4
55+
}
56+
57+
; Test placement of the block address in constantpool
58+
59+
define dso_local i32 @const_blockaddress(i32 noundef %0) #0 {
60+
; CHECK: .literal_position
61+
; CHECK-NEXT: .literal .LCPI4_0, .Ltmp0
62+
; CHECK-LABEL: const_blockaddress:
63+
; CHECK: l32r a8, .LCPI4_0
64+
; CHECK: jx a8
65+
; CHECK-NEXT: .Ltmp0:
66+
%2 = alloca i32, align 4
67+
%3 = alloca ptr, align 4
68+
store i32 %0, ptr %2, align 4
69+
store ptr blockaddress(@const_blockaddress, %5), ptr %3, align 4
70+
%4 = load ptr, ptr %3, align 4
71+
br label %7
72+
73+
5: ; preds = %7
74+
%6 = load i32, ptr %2, align 4
75+
ret i32 %6
76+
77+
7: ; preds = %1
78+
%8 = phi ptr [ %4, %1 ]
79+
indirectbr ptr %8, [label %5]
80+
}

0 commit comments

Comments
 (0)