BaseInsertOffset =
std::max(UserBBI.postOffset() - UPad - 8,
UserOffset + TII->getInstSizeInBytes(*UserMI) + 1);
+ // If the CP is referenced(ie, UserOffset) is in first four instructions
+ // after IT, this recalculated BaseInsertOffset could be in the middle of
+ // an IT block. If it is, change the BaseInsertOffset to just after the
+ // IT block. This still make the CP Entry is in range becuase of the
+ // following reasons.
+ // 1. The initial BaseseInsertOffset calculated is (UserOffset +
+ // U.getMaxDisp() - UPad).
+ // 2. An IT block is only at most 4 instructions plus the "it" itself (18
+ // bytes).
+ // 3. All the relevant instructions support much larger Maximum
+ // displacement.
+ MachineBasicBlock::iterator I = UserMI;
+ ++I;
+ for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI),
+ PredReg = 0;
+ I->getOpcode() != ARM::t2IT &&
+ getITInstrPredicate(*I, PredReg) != ARMCC::AL;
+ Offset += TII->getInstSizeInBytes(*I), I = std::next(I)) {
+ BaseInsertOffset =
+ std::max(BaseInsertOffset, Offset + TII->getInstSizeInBytes(*I) + 1);
+ assert(I != UserMBB->end() && "Fell off end of block");
+ }
LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset));
}
unsigned EndInsertOffset = BaseInsertOffset + 4 + UPad +
}
// We really must not split an IT block.
- LLVM_DEBUG(unsigned PredReg; assert(
- !isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL));
-
+#ifndef NDEBUG
+ unsigned PredReg;
+ assert(!isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL);
+#endif
NewMBB = splitBlockBeforeInstr(&*MI);
}
--- /dev/null
+# RUN: llc -run-pass=arm-cp-islands %s -o - | FileCheck %s
+
+# This test make sure that the constant pool does not keep in the middle of an IT block
+# when needs to split a block to place them.
+#
+
+--- |
+ ; ModuleID = '<stdin>'
+ source_filename = "<stdin>"
+ target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+ target triple = "thumbv8m.main-arm-none-eabi"
+
+ %struct.e = type { double, double, double }
+
+ declare i32 @llvm.arm.space(i32, i32)
+
+ define hidden arm_aapcs_vfpcc %struct.e @h() {
+ unreachable
+ }
+
+...
+---
+name: h
+alignment: 2
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+failedISel: false
+tracksRegLiveness: true
+hasWinCFI: false
+registers: []
+liveins: []
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 64
+ offsetAdjustment: -40
+ maxAlignment: 4
+ adjustsStack: true
+ hasCalls: true
+ maxCallFrameSize: 0
+ cvBytesOfCalleeSavedRegisters: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ localFrameSize: 28
+ savePoint: ''
+ restorePoint: ''
+fixedStack: []
+callSites: []
+constants:
+ - id: 0
+ value: 'double 0.000000e+00'
+ alignment: 8
+ isTargetSpecific: false
+ - id: 1
+ value: 'double 7.020000e+02'
+ alignment: 8
+ isTargetSpecific: false
+ - id: 2
+ value: 'double 2.020000e+02'
+ alignment: 8
+ isTargetSpecific: false
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ successors: %bb.1(0x80000000)
+
+ renamable $d0 = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
+ dead renamable $r0 = SPACE 40, undef renamable $r0
+
+ bb.1:
+ successors: %bb.2(0x80000000)
+
+ dead renamable $r0 = SPACE 790, undef renamable $r0
+
+ bb.2:
+ successors:
+
+ renamable $r0 = t2MOVi 0, 14, _, _
+ t2CMPri $r0, 32, 14, $noreg, implicit-def $cpsr
+ renamable $r0 = SPACE 200, undef renamable $r0
+ ; CHECK: t2IT 0, 1, implicit-def $itstate
+ ; CHECK-NEXT: renamable $d0 = VLDRD %const.7, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ ; CHECK-NEXT: renamable $d1 = VLDRD %const.5, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ ; CHECK-NEXT: renamable $d2 = VLDRD %const.6, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ ; CHECK-NEXT: $r0 = t2SUBri $r0, 12, 0, $cpsr, $noreg, implicit killed $itstate
+ t2IT 0, 1, implicit-def $itstate
+ renamable $d0 = VLDRD %const.1, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ renamable $d1 = VLDRD %const.2, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ renamable $d2 = VLDRD %const.0, 0, 0, $cpsr, implicit $itstate :: (load 8 from constant-pool)
+ $r0 = t2SUBri $r0, 12, 0, $cpsr, $noreg, implicit killed $itstate
+ t2IT 0, 4, implicit-def $itstate
+ $sp = tMOVr $r0, 0, $cpsr, implicit $itstate
+ $sp = t2LDMIA_RET $sp, 0, killed $cpsr, def $r4, def $r5, def $r6, def $r7, def $r8, def $r9, def $r10, def $r11, def $pc, implicit killed $d0, implicit killed $d1, implicit killed $d2, implicit $sp, implicit killed $itstate
+ tBL 14, $noreg, &__stack_chk_fail, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+
+ bb.3:
+ successors: %bb.3(0x80000000)
+ liveins: $r0
+
+ dead renamable $r0 = SPACE 4000, undef renamable $r0
+ t2B %bb.3, 14, $noreg
+