Skip to content

Commit c582d6e

Browse files
committedJun 14, 2017
[ARM] Support constant pools in data when generating execute-only code.
The ARM backend asserts against constant pool lowering when it generates execute-only code in order to prevent the generation of constant pools in the text section. It appears that target independent optimizations might generate DAG nodes that represent constant pools. By lowering such nodes as global addresses we don't violate the semantics of execute-only code and also it is guaranteed that execute-only behaves correct with the position-independent addressing modes that support execute-only code. Differential Revision: https://reviews.llvm.org/D33773 llvm-svn: 305387
1 parent ffc498d commit c582d6e

File tree

4 files changed

+93
-15
lines changed

4 files changed

+93
-15
lines changed
 

‎llvm/lib/Target/ARM/ARMAsmPrinter.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1504,6 +1504,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
15041504
return;
15051505
}
15061506
case ARM::CONSTPOOL_ENTRY: {
1507+
if (Subtarget->genExecuteOnly())
1508+
llvm_unreachable("execute-only should not generate constant pools");
1509+
15071510
/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
15081511
/// in the function. The first operand is the ID# for this instruction, the
15091512
/// second is the index into the MachineConstantPool that this is, the third

‎llvm/lib/Target/ARM/ARMISelLowering.cpp

+38-15
Original file line numberDiff line numberDiff line change
@@ -2669,12 +2669,34 @@ static SDValue LowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) {
26692669
// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
26702670
// be used to form addressing mode. These wrapped nodes will be selected
26712671
// into MOVi.
2672-
static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
2672+
SDValue ARMTargetLowering::LowerConstantPool(SDValue Op,
2673+
SelectionDAG &DAG) const {
26732674
EVT PtrVT = Op.getValueType();
26742675
// FIXME there is no actual debug info here
26752676
SDLoc dl(Op);
26762677
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
26772678
SDValue Res;
2679+
2680+
// When generating execute-only code Constant Pools must be promoted to the
2681+
// global data section. It's a bit ugly that we can't share them across basic
2682+
// blocks, but this way we guarantee that execute-only behaves correct with
2683+
// position-independent addressing modes.
2684+
if (Subtarget->genExecuteOnly()) {
2685+
auto AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
2686+
auto T = const_cast<Type*>(CP->getType());
2687+
auto C = const_cast<Constant*>(CP->getConstVal());
2688+
auto M = const_cast<Module*>(DAG.getMachineFunction().
2689+
getFunction()->getParent());
2690+
auto L = Twine(DAG.getDataLayout().getPrivateGlobalPrefix()) + "CP" +
2691+
Twine(DAG.getMachineFunction().getFunctionNumber()) + "_" +
2692+
Twine(AFI->createPICLabelUId());
2693+
auto GV = new GlobalVariable(*M, T, /*isConstant=*/true,
2694+
GlobalVariable::InternalLinkage, C, L);
2695+
SDValue GA = DAG.getTargetGlobalAddress(dyn_cast<GlobalValue>(GV),
2696+
dl, PtrVT);
2697+
return LowerGlobalAddress(GA, DAG);
2698+
}
2699+
26782700
if (CP->isMachineConstantPoolEntry())
26792701
Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT,
26802702
CP->getAlignment());
@@ -3118,6 +3140,19 @@ static bool isReadOnly(const GlobalValue *GV) {
31183140
isa<Function>(GV);
31193141
}
31203142

3143+
SDValue ARMTargetLowering::LowerGlobalAddress(SDValue Op,
3144+
SelectionDAG &DAG) const {
3145+
switch (Subtarget->getTargetTriple().getObjectFormat()) {
3146+
default: llvm_unreachable("unknown object format");
3147+
case Triple::COFF:
3148+
return LowerGlobalAddressWindows(Op, DAG);
3149+
case Triple::ELF:
3150+
return LowerGlobalAddressELF(Op, DAG);
3151+
case Triple::MachO:
3152+
return LowerGlobalAddressDarwin(Op, DAG);
3153+
}
3154+
}
3155+
31213156
SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
31223157
SelectionDAG &DAG) const {
31233158
EVT PtrVT = getPointerTy(DAG.getDataLayout());
@@ -7634,21 +7669,9 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
76347669
switch (Op.getOpcode()) {
76357670
default: llvm_unreachable("Don't know how to custom lower this!");
76367671
case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);
7637-
case ISD::ConstantPool:
7638-
if (Subtarget->genExecuteOnly())
7639-
llvm_unreachable("execute-only should not generate constant pools");
7640-
return LowerConstantPool(Op, DAG);
7672+
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
76417673
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
7642-
case ISD::GlobalAddress:
7643-
switch (Subtarget->getTargetTriple().getObjectFormat()) {
7644-
default: llvm_unreachable("unknown object format");
7645-
case Triple::COFF:
7646-
return LowerGlobalAddressWindows(Op, DAG);
7647-
case Triple::ELF:
7648-
return LowerGlobalAddressELF(Op, DAG);
7649-
case Triple::MachO:
7650-
return LowerGlobalAddressDarwin(Op, DAG);
7651-
}
7674+
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
76527675
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
76537676
case ISD::SELECT: return LowerSELECT(Op, DAG);
76547677
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);

‎llvm/lib/Target/ARM/ARMISelLowering.h

+2
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ class InstrItineraryData;
601601
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
602602
const ARMSubtarget *Subtarget) const;
603603
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
604+
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
605+
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
604606
SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
605607
SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;
606608
SDValue LowerGlobalAddressWindows(SDValue Op, SelectionDAG &DAG) const;

‎llvm/test/CodeGen/ARM/constantfp.ll

+50
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
; RUN: llc -mtriple=thumbv7meb -arm-execute-only -mcpu=cortex-m4 %s -o - \
1212
; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s
1313

14+
; RUN: llc -mtriple=thumbv7m -arm-execute-only -mcpu=cortex-m4 -relocation-model=ropi %s -o - \
15+
; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s
16+
1417
; RUN: llc -mtriple=thumbv8m.main -mattr=fp-armv8 %s -o - \
1518
; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s
1619

@@ -20,6 +23,8 @@
2023
; RUN: llc -mtriple=thumbv8m.maineb -arm-execute-only -mattr=fp-armv8 %s -o - \
2124
; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s
2225

26+
; RUN: llc -mtriple=thumbv8m.main -arm-execute-only -mattr=fp-armv8 -relocation-model=ropi %s -o - \
27+
; RUN: | FileCheck --check-prefix=CHECK-XO-ROPI %s
2328

2429
define arm_aapcs_vfpcc float @test_vmov_f32() {
2530
; CHECK-LABEL: test_vmov_f32:
@@ -176,3 +181,48 @@ define arm_aapcs_vfpcc double @lower_const_f64_xo() {
176181
; CHECK-XO-DOUBLE-BE-NOT: vldr
177182
ret double 3.140000e-01
178183
}
184+
185+
; This is a target independent optimization, performed by the
186+
; DAG Combiner, which promotes floating point literals into
187+
; constant pools:
188+
;
189+
; (a cond b) ? 1.0f : 2.0f -> load (ConstPoolAddr + ((a cond b) ? 0 : 4)
190+
;
191+
; We need to make sure that the constant pools are placed in
192+
; the data section when generating execute-only code:
193+
194+
define arm_aapcs_vfpcc float @lower_fpconst_select(float %f) {
195+
196+
; CHECK-NO-XO-LABEL: lower_fpconst_select
197+
; CHECK-NO-XO: adr [[REG:r[0-9]+]], [[LABEL:.?LCPI[0-9]+_[0-9]+]]
198+
; CHECK-NO-XO: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
199+
; CHECK-NO-XO-NOT: .rodata
200+
; CHECK-NO-XO: [[LABEL]]:
201+
; CHECK-NO-XO: .long 1335165689
202+
; CHECK-NO-XO: .long 1307470632
203+
204+
; CHECK-XO-FLOAT-LABEL: lower_fpconst_select
205+
; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], :lower16:[[LABEL:.?LCP[0-9]+_[0-9]+]]
206+
; CHECK-XO-FLOAT: movt [[REG]], :upper16:[[LABEL]]
207+
; CHECK-XO-FLOAT: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
208+
; CHECK-XO-FLOAT: .rodata
209+
; CHECK-XO-FLOAT-NOT: .text
210+
; CHECK-XO-FLOAT: [[LABEL]]:
211+
; CHECK-XO-FLOAT: .long 1335165689
212+
; CHECK-XO-FLOAT: .long 1307470632
213+
214+
; CHECK-XO-ROPI-LABEL: lower_fpconst_select
215+
; CHECK-XO-ROPI: movw [[REG:r[0-9]+]], :lower16:([[LABEL1:.?LCP[0-9]+_[0-9]+]]-([[LABEL2:.?LPC[0-9]+_[0-9]+]]+4))
216+
; CHECK-XO-ROPI: movt [[REG]], :upper16:([[LABEL1]]-([[LABEL2]]+4))
217+
; CHECK-XO-ROPI: [[LABEL2]]:
218+
; CHECK-XO-ROPI: vldr {{s[0-9]+}}, {{[[]}}[[REG]]{{[]]}}
219+
; CHECK-XO-ROPI: .rodata
220+
; CHECK-XO-ROPI-NOT: .text
221+
; CHECK-XO-ROPI: [[LABEL1]]:
222+
; CHECK-XO-ROPI: .long 1335165689
223+
; CHECK-XO-ROPI: .long 1307470632
224+
225+
%cmp = fcmp nnan oeq float %f, 0.000000e+00
226+
%sel = select i1 %cmp, float 5.000000e+08, float 5.000000e+09
227+
ret float %sel
228+
}

0 commit comments

Comments
 (0)
Please sign in to comment.