llvm.org GIT mirror llvm / 929bdb2
Enable generating legacy IT block for AArch32 By default, the behavior of IT block generation will be determinated dynamically base on the arch (armv8 vs armv7). This patch adds backend options: -arm-restrict-it and -arm-no-restrict-it. The former one restricts the generation of IT blocks (the same behavior as thumbv8) for both arches. The later one allows the generation of legacy IT block (the same behavior as ARMv7 Thumb2) for both arches. Clang will support -mrestrict-it and -mno-restrict-it, which is compatible with GCC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194592 91177308-0d34-0410-b5e6-96231b3b80d8 Weiming Zhao 6 years ago
14 changed file(s) with 57 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
524524 MI->getParent()->getParent()->getInfo();
525525
526526 if (AFI->isThumb2Function()) {
527 if (getSubtarget().hasV8Ops())
527 if (getSubtarget().restrictIT())
528528 return isV8EligibleForIT(MI);
529529 } else { // non-Thumb
530530 if ((MI->getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON)
5555 clEnumValN(NoStrictAlign, "arm-no-strict-align",
5656 "Allow unaligned memory accesses"),
5757 clEnumValEnd));
58
59 enum ITMode {
60 DefaultIT,
61 RestrictedIT,
62 NoRestrictedIT
63 };
64
65 static cl::opt
66 IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT),
67 cl::ZeroOrMore,
68 cl::values(clEnumValN(DefaultIT, "arm-default-it",
69 "Generate IT block based on arch"),
70 clEnumValN(RestrictedIT, "arm-restrict-it",
71 "Disallow deprecated IT based on ARMv8"),
72 clEnumValN(NoRestrictedIT, "arm-no-restrict-it",
73 "Allow IT blocks based on ARMv7"),
74 clEnumValEnd));
5875
5976 ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
6077 const std::string &FS, const TargetOptions &Options)
216233 break;
217234 }
218235
236 switch (IT) {
237 case DefaultIT:
238 RestrictIT = hasV8Ops() ? true : false;
239 break;
240 case RestrictedIT:
241 RestrictIT = true;
242 break;
243 case NoRestrictedIT:
244 RestrictIT = false;
245 break;
246 }
247
219248 // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
220249 uint64_t Bits = getFeatureBits();
221250 if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters
175175 /// accesses for some types. For details, see
176176 /// ARMTargetLowering::allowsUnalignedMemoryAccesses().
177177 bool AllowsUnalignedMem;
178
179 /// RestrictIT - If true, the subtarget disallows generation of deprecated IT
180 /// blocks to conform to ARMv8 rule.
181 bool RestrictIT;
178182
179183 /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith
180184 /// and such) instructions in Thumb2 code.
326330
327331 bool allowsUnalignedMem() const { return AllowsUnalignedMem; }
328332
333 bool restrictIT() const { return RestrictIT; }
334
329335 const std::string & getCPUString() const { return CPUString; }
330336
331337 unsigned getMispredictionPenalty() const;
197197 if (getOptLevel() != CodeGenOpt::None) {
198198 if (!getARMSubtarget().isThumb1Only()) {
199199 // in v8, IfConversion depends on Thumb instruction widths
200 if (getARMSubtarget().hasV8Ops() &&
200 if (getARMSubtarget().restrictIT() &&
201201 !getARMSubtarget().prefers32BitThumb())
202202 addPass(createThumb2SizeReductionPass());
203203 addPass(&IfConverterID);
2727 static char ID;
2828 Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
2929
30 bool hasV8Ops;
30 bool restrictIT;
3131 const Thumb2InstrInfo *TII;
3232 const TargetRegisterInfo *TRI;
3333 ARMFunctionInfo *AFI;
193193 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
194194 unsigned Mask = 0, Pos = 3;
195195
196 // v8 IT blocks are limited to one conditional op: skip the loop
197 if (!hasV8Ops) {
196 // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
197 // is set: skip the loop
198 if (!restrictIT) {
198199 // Branches, including tricky ones like LDM_RET, need to end an IT
199200 // block so check the instruction we just put in the block.
200201 for (; MBBI != E && Pos &&
254255 AFI = Fn.getInfo();
255256 TII = static_cast(TM.getInstrInfo());
256257 TRI = TM.getRegisterInfo();
257 hasV8Ops = TM.getSubtarget().hasV8Ops();
258 restrictIT = TM.getSubtarget().restrictIT();
258259
259260 if (!AFI->isThumbFunction())
260261 return false;
0 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s
11 ; RUN: llc < %s -mtriple=thumbv8 | FileCheck -check-prefix=CHECK-V8 %s
2 ; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck -check-prefix=CHECK-V8 %s
23 ; rdar://13782395
34
45 define i32 @t1(i32 %a, i32 %b, i8** %retaddr) {
0 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
1
1 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s
2 ; RUN: llc < %s -mtriple=thumbv8 -arm-no-restrict-it |FileCheck %s
23 define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
34 ; CHECK-LABEL: t1:
45 ; CHECK: ittt ne
7374 ; CHECK-LABEL: t3:
7475 ; CHECK: itt ge
7576 ; CHECK: movge r0, r1
76 ; CHECK: blge _foo
77 ; CHECK: blge {{_?}}foo
7778 %tmp1 = icmp sgt i32 %a, 10 ; [#uses=1]
7879 br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
7980
0 ; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-default-it | FileCheck %s
2 ; RUN: llc < %s -mtriple=thumbv8-apple-ios -arm-no-restrict-it | FileCheck %s
13
24 define void @foo(i32 %X, i32 %Y) {
35 entry:
0 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s
2 ; RUN: llc < %s -mtriple=thumbv8-apple-darwin -arm-no-restrict-it | FileCheck %s
13
24 ; There shouldn't be a unconditional branch at end of bb52.
35 ; rdar://7184787
0 ; RUN: llc < %s -mtriple=thumbv8 -mattr=+neon | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7 -mattr=+neon -arm-restrict-it | FileCheck %s
12
23 ;CHECK-LABEL: select_s_v_v:
34 ;CHECK-NOT: it
0 ; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck %s
12
23 %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
34
0 ; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck %s
12 ; RUN: llc < %s -mtriple=thumbv8 -relocation-model=pic | FileCheck %s --check-prefix=CHECK-PIC
3 ; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it -relocation-model=pic | FileCheck %s --check-prefix=CHECK-PIC
24
35 %struct.FF = type { i32 (i32*)*, i32 (i32*, i32*, i32, i32, i32, i32)*, i32 (i32, i32, i8*)*, void ()*, i32 (i32, i8*, i32*)*, i32 ()* }
46 %struct.BD = type { %struct.BD*, i32, i32, i32, i32, i64, i32 (%struct.BD*, i8*, i64, i32)*, i32 (%struct.BD*, i8*, i32, i32)*, i32 (%struct.BD*, i8*, i64, i32)*, i32 (%struct.BD*, i8*, i32, i32)*, i32 (%struct.BD*, i64, i32)*, [16 x i8], i64, i64 }
0 ; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7-eabi -float-abi=hard -arm-restrict-it | FileCheck %s
12 ; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard -regalloc=basic | FileCheck %s
3 ; RUN: llc < %s -mtriple=thumbv7-eabi -float-abi=hard -regalloc=basic -arm-restrict-it | FileCheck %s
24
35 %"struct.__gnu_cxx::__normal_iterator, std::allocator > >" = type { i8* }
46 %"struct.__gnu_cxx::new_allocator" = type <{ i8 }>
0 ; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s
1 ; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck %s
12 ; CHECK: it ne
23 ; CHECK-NEXT: cmpne
34 ; CHECK-NEXT: beq