[ARM] Undeprecate complex IT blocks

AArch32/Armv8A  introduced the performance deprecation of certain patterns
of IT instructions.  After some debate internal to ARM, this is now being
reverted; i.e. no IT instruction patterns are performance deprecated
anymore, as the perfomance degredation is not significant enough.

This reverts the following:

"ARMv8-A deprecates some uses of the T32 IT instruction. All uses of
IT that apply to instructions other than a single subsequent 16-bit
instruction from a restricted set are deprecated, as are explicit
references to the PC within that single 16-bit instruction. This permits
the non-deprecated forms of IT and subsequent instructions to be treated
as a single 32-bit conditional instruction."

The deprecation no longer applies, but the behaviour may be controlled
by the -arm-restrict-it and -arm-no-restrict-it command-line options,
with the latter being the default. No warnings about complex IT blocks
will be generated.

Reviewed By: dmgreen

Differential Revision: https://reviews.llvm.org/D118044
This commit is contained in:
Mark Murray 2022-01-24 10:39:03 +00:00
parent cdc0573f75
commit 3d7662142d
33 changed files with 605 additions and 7027 deletions

View File

@ -3313,7 +3313,7 @@ Disallow use of CRC instructions (ARM only)
.. option:: -mrestrict-it, -mno-restrict-it
Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.
Disallow generation of complex IT blocks. It is off by default.
.. option:: -mtp=<arg>

View File

@ -3325,9 +3325,9 @@ def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, F
HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">;
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
HelpText<"Disallow generation of complex IT blocks.">;
def mno_restrict_it: Flag<["-"], "mno-restrict-it">, Group<m_arm_Features_Group>,
HelpText<"Allow generation of deprecated IT blocks for ARMv8. It is off by default for ARMv8 Thumb mode">;
HelpText<"Allow generation of complex IT blocks.">;
def marm : Flag<["-"], "marm">, Alias<mno_thumb>;
def ffixed_r9 : Flag<["-"], "ffixed-r9">, Group<m_arm_Features_Group>,
HelpText<"Reserve the r9 register (ARM only)">;

View File

@ -6129,14 +6129,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-arm-restrict-it");
} else {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-arm-no-restrict-it");
CmdArgs.push_back("-arm-default-it");
}
} else if (Triple.isOSWindows() &&
(Triple.getArch() == llvm::Triple::arm ||
Triple.getArch() == llvm::Triple::thumb)) {
// Windows on ARM expects restricted IT blocks
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-arm-restrict-it");
}
// Forward -cl options to -cc1

View File

@ -12,4 +12,4 @@
// RUN: %clang -target armv8a-none-gnueabi -mno-restrict-it -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-NO-RESTRICTED < %t %s
// CHECK-NO-RESTRICTED: "-mllvm" "-arm-no-restrict-it"
// CHECK-NO-RESTRICTED: "-mllvm" "-arm-default-it"

View File

@ -1,4 +0,0 @@
// RUN: %clang -target armv7-windows -### %s 2>&1 | FileCheck %s
// CHECK: "-mllvm" "-arm-restrict-it"

View File

@ -70,6 +70,15 @@ Changes to the AArch64 Backend
Changes to the ARM Backend
--------------------------
* Added support for the Armv9-A, Armv9.1-A and Armv9.2-A architectures.
* Added support for the Armv8.1-M PACBTI-M extension.
* Added support for the Armv9-A, Armv9.1-A and Armv9.2-A architectures.
* Added support for the Armv8.1-M PACBTI-M extension.
* Removed the deprecation of ARMv8-A T32 Complex IT blocks. No deprecation
warnings will be generated and -mrestrict-it is now always off by default.
Previously it was on by default for Armv8 and off for all other architecture
versions.
Changes to the MIPS Target
--------------------------

View File

@ -6415,8 +6415,7 @@ def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm",
// 'it' blocks in ARM mode just validate the predicates. The IT itself
// is discarded.
def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>,
ComplexDeprecationPredicate<"IT">;
def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>;
let mayLoad = 1, mayStore =1, hasSideEffects = 1, hasNoSchedulingInfo = 1 in
def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn),

View File

@ -3964,8 +3964,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
let Defs = [ITSTATE] in
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
AddrModeNone, 2, IIC_iALUx,
"it$mask\t$cc", "", []>,
ComplexDeprecationPredicate<"IT"> {
"it$mask\t$cc", "", []> {
// 16-bit instruction.
let Inst{31-16} = 0x0000;
let Inst{15-8} = 0b10111111;

View File

@ -52,19 +52,16 @@ UseFusedMulOps("arm-use-mulops",
enum ITMode {
DefaultIT,
RestrictedIT,
NoRestrictedIT
RestrictedIT
};
static cl::opt<ITMode>
IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT),
cl::ZeroOrMore,
cl::values(clEnumValN(DefaultIT, "arm-default-it",
"Generate IT block based on arch"),
"Generate any type of IT block"),
clEnumValN(RestrictedIT, "arm-restrict-it",
"Disallow deprecated IT based on ARMv8"),
clEnumValN(NoRestrictedIT, "arm-no-restrict-it",
"Allow IT blocks based on ARMv7")));
"Disallow complex IT blocks")));
/// ForceFastISel - Use the fast-isel, even for subtargets where it is not
/// currently supported (for testing only).
@ -237,14 +234,11 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
switch (IT) {
case DefaultIT:
RestrictIT = hasV8Ops() && !hasMinSize();
RestrictIT = false;
break;
case RestrictedIT:
RestrictIT = true;
break;
case NoRestrictedIT:
RestrictIT = false;
break;
}
// NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.

View File

@ -453,8 +453,8 @@ protected:
/// ARMTargetLowering::allowsMisalignedMemoryAccesses().
bool StrictAlign = false;
/// RestrictIT - If true, the subtarget disallows generation of deprecated IT
/// blocks to conform to ARMv8 rule.
/// RestrictIT - If true, the subtarget disallows generation of complex IT
/// blocks.
bool RestrictIT = false;
/// HasDSP - If true, the subtarget supports the DSP (saturating arith

View File

@ -10958,9 +10958,7 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return true;
}
{ // processInstruction() updates inITBlock state, we need to save it away
bool wasInITBlock = inITBlock();
{
// Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other. E.g.,
@ -10969,12 +10967,6 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
LLVM_DEBUG(dbgs() << "Changed to: ";
Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
dbgs() << "\n");
// Only after the instruction is fully processed, we can validate it
if (wasInITBlock && hasV8Ops() && isThumb() &&
!isV8EligibleForIT(&Inst) && !getTargetOptions().MCNoDeprecatedWarn) {
Warning(IDLoc, "deprecated instruction in IT block");
}
}
// Only move forward at the very end so that everything in validate

View File

@ -87,18 +87,6 @@ static bool getMRCDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
return false;
}
static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
std::string &Info) {
if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
MI.getOperand(1).getImm() != 8) {
Info = "applying IT instruction to more than one subsequent instruction is "
"deprecated";
return true;
}
return false;
}
static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
std::string &Info) {
assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&

View File

@ -226,9 +226,10 @@ bool Thumb2ITBlock::InsertITInstructions(MachineBasicBlock &MBB) {
ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
unsigned Mask = 0, Pos = 3;
// v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
// IT blocks are limited to one conditional op if -arm-restrict-it
// is set: skip the loop
if (!restrictIT) {
LLVM_DEBUG(dbgs() << "Allowing complex IT block\n";);
// Branches, including tricky ones like LDM_RET, need to end an IT
// block so check the instruction we just put in the block.
for (; MBBI != E && Pos &&

View File

@ -1,11 +1,63 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8 | FileCheck -check-prefix=CHECK-V8 %s
; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck -check-prefix=CHECK-V8 %s
; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck -check-prefix=CHECK-RESTRICT-IT %s
define i32 @t1(i32 %a, i32 %b, i8** %retaddr) {
; CHECK-LABEL: t1:
; CHECK: Block address taken
; CHECK-NOT: Address of block that was removed by CodeGen
; CHECK: @ %bb.0:
; CHECK-NEXT: ldr r3, LCPI0_0
; CHECK-NEXT: cmp r0, #0
; CHECK-NEXT: LPC0_0:
; CHECK-NEXT: add r3, pc
; CHECK-NEXT: str r3, [r2]
; CHECK-NEXT: mov.w r2, #1
; CHECK-NEXT: it eq
; CHECK-NEXT: moveq.w r2, #-1
; CHECK-NEXT: Ltmp0: @ Block address taken
; CHECK-NEXT: @ %bb.1: @ %common.ret
; CHECK-NEXT: adds r0, r1, r2
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.2:
; CHECK-NEXT: .data_region
; CHECK-NEXT: LCPI0_0:
; CHECK-NEXT: .long Ltmp0-(LPC0_0+4)
; CHECK-NEXT: .end_data_region
;
; CHECK-V8-LABEL: t1:
; CHECK-V8: @ %bb.0:
; CHECK-V8-NEXT: ldr r3, .LCPI0_0
; CHECK-V8-NEXT: cmp r0, #0
; CHECK-V8-NEXT: str r3, [r2]
; CHECK-V8-NEXT: mov.w r2, #1
; CHECK-V8-NEXT: it eq
; CHECK-V8-NEXT: moveq.w r2, #-1
; CHECK-V8-NEXT: .Ltmp0: @ Block address taken
; CHECK-V8-NEXT: @ %bb.1: @ %common.ret
; CHECK-V8-NEXT: adds r0, r1, r2
; CHECK-V8-NEXT: bx lr
; CHECK-V8-NEXT: .p2align 2
; CHECK-V8-NEXT: @ %bb.2:
; CHECK-V8-NEXT: .LCPI0_0:
; CHECK-V8-NEXT: .long .Ltmp0
;
; CHECK-RESTRICT-IT-LABEL: t1:
; CHECK-RESTRICT-IT: @ %bb.0:
; CHECK-RESTRICT-IT-NEXT: ldr r3, .LCPI0_0
; CHECK-RESTRICT-IT-NEXT: str r3, [r2]
; CHECK-RESTRICT-IT-NEXT: movs r2, #1
; CHECK-RESTRICT-IT-NEXT: cmp r0, #0
; CHECK-RESTRICT-IT-NEXT: it eq
; CHECK-RESTRICT-IT-NEXT: moveq.w r2, #-1
; CHECK-RESTRICT-IT-NEXT: .Ltmp0: @ Block address taken
; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %common.ret
; CHECK-RESTRICT-IT-NEXT: adds r0, r1, r2
; CHECK-RESTRICT-IT-NEXT: bx lr
; CHECK-RESTRICT-IT-NEXT: .p2align 2
; CHECK-RESTRICT-IT-NEXT: @ %bb.2:
; CHECK-RESTRICT-IT-NEXT: .LCPI0_0:
; CHECK-RESTRICT-IT-NEXT: .long .Ltmp0
store i8* blockaddress(@t1, %cond_true), i8** %retaddr
%tmp2 = icmp eq i32 %a, 0
br i1 %tmp2, label %cond_false, label %cond_true
@ -21,10 +73,78 @@ cond_false:
define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d, i8** %retaddr) {
; CHECK-LABEL: t2:
; CHECK: Block address taken
; CHECK: %cond_true
; CHECK: add
; CHECK: bx lr
; CHECK: @ %bb.0:
; CHECK-NEXT: ldr.w r9, [sp]
; CHECK-NEXT: add r0, r1
; CHECK-NEXT: ldr.w r12, LCPI1_0
; CHECK-NEXT: cmp r3, #3
; CHECK-NEXT: LPC1_0:
; CHECK-NEXT: add r12, pc
; CHECK-NEXT: str.w r12, [r9]
; CHECK-NEXT: it gt
; CHECK-NEXT: bxgt lr
; CHECK-NEXT: LBB1_1:
; CHECK-NEXT: cmp r2, #10
; CHECK-NEXT: ble LBB1_3
; CHECK-NEXT: Ltmp1: @ Block address taken
; CHECK-NEXT: @ %bb.2: @ %cond_true
; CHECK-NEXT: add r0, r2
; CHECK-NEXT: subs r0, r0, r3
; CHECK-NEXT: LBB1_3: @ %common.ret
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.4:
; CHECK-NEXT: .data_region
; CHECK-NEXT: LCPI1_0:
; CHECK-NEXT: .long Ltmp1-(LPC1_0+4)
; CHECK-NEXT: .end_data_region
;
; CHECK-V8-LABEL: t2:
; CHECK-V8: @ %bb.0:
; CHECK-V8-NEXT: push {r7, lr}
; CHECK-V8-NEXT: ldr.w r12, [sp, #8]
; CHECK-V8-NEXT: add r0, r1
; CHECK-V8-NEXT: ldr.w lr, .LCPI1_0
; CHECK-V8-NEXT: cmp r3, #3
; CHECK-V8-NEXT: str.w lr, [r12]
; CHECK-V8-NEXT: it gt
; CHECK-V8-NEXT: popgt {r7, pc}
; CHECK-V8-NEXT: .LBB1_1:
; CHECK-V8-NEXT: cmp r2, #10
; CHECK-V8-NEXT: ble .LBB1_3
; CHECK-V8-NEXT: .Ltmp1: @ Block address taken
; CHECK-V8-NEXT: @ %bb.2: @ %cond_true
; CHECK-V8-NEXT: add r0, r2
; CHECK-V8-NEXT: subs r0, r0, r3
; CHECK-V8-NEXT: .LBB1_3: @ %common.ret
; CHECK-V8-NEXT: pop {r7, pc}
; CHECK-V8-NEXT: .p2align 2
; CHECK-V8-NEXT: @ %bb.4:
; CHECK-V8-NEXT: .LCPI1_0:
; CHECK-V8-NEXT: .long .Ltmp1
;
; CHECK-RESTRICT-IT-LABEL: t2:
; CHECK-RESTRICT-IT: @ %bb.0:
; CHECK-RESTRICT-IT-NEXT: push {r7, lr}
; CHECK-RESTRICT-IT-NEXT: ldr.w r12, [sp, #8]
; CHECK-RESTRICT-IT-NEXT: add r0, r1
; CHECK-RESTRICT-IT-NEXT: ldr.w lr, .LCPI1_0
; CHECK-RESTRICT-IT-NEXT: cmp r3, #3
; CHECK-RESTRICT-IT-NEXT: str.w lr, [r12]
; CHECK-RESTRICT-IT-NEXT: bgt .LBB1_3
; CHECK-RESTRICT-IT-NEXT: @ %bb.1:
; CHECK-RESTRICT-IT-NEXT: cmp r2, #10
; CHECK-RESTRICT-IT-NEXT: ble .LBB1_3
; CHECK-RESTRICT-IT-NEXT: .Ltmp1: @ Block address taken
; CHECK-RESTRICT-IT-NEXT: @ %bb.2: @ %cond_true
; CHECK-RESTRICT-IT-NEXT: add r0, r2
; CHECK-RESTRICT-IT-NEXT: subs r0, r0, r3
; CHECK-RESTRICT-IT-NEXT: .LBB1_3: @ %common.ret
; CHECK-RESTRICT-IT-NEXT: pop {r7, pc}
; CHECK-RESTRICT-IT-NEXT: .p2align 2
; CHECK-RESTRICT-IT-NEXT: @ %bb.4:
; CHECK-RESTRICT-IT-NEXT: .LCPI1_0:
; CHECK-RESTRICT-IT-NEXT: .long .Ltmp1
store i8* blockaddress(@t2, %cond_true), i8** %retaddr
%tmp2 = icmp sgt i32 %c, 10
%tmp5 = icmp slt i32 %d, 4
@ -43,8 +163,44 @@ UnifiedReturnBlock:
define hidden fastcc void @t3(i8** %retaddr, i1 %tst, i8* %p8) {
; CHECK-LABEL: t3:
; CHECK: Block address taken
; CHECK-NOT: Address of block that was removed by CodeGen
; CHECK: @ %bb.0: @ %bb
; CHECK-NEXT: ldr r1, LCPI2_0
; CHECK-NEXT: LPC2_0:
; CHECK-NEXT: add r1, pc
; CHECK-NEXT: str r1, [r0]
; CHECK-NEXT: Ltmp2: @ Block address taken
; CHECK-NEXT: @ %bb.1: @ %common.ret
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.2:
; CHECK-NEXT: .data_region
; CHECK-NEXT: LCPI2_0:
; CHECK-NEXT: .long Ltmp2-(LPC2_0+4)
; CHECK-NEXT: .end_data_region
;
; CHECK-V8-LABEL: t3:
; CHECK-V8: @ %bb.0: @ %bb
; CHECK-V8-NEXT: ldr r1, .LCPI2_0
; CHECK-V8-NEXT: str r1, [r0]
; CHECK-V8-NEXT: .Ltmp2: @ Block address taken
; CHECK-V8-NEXT: @ %bb.1: @ %common.ret
; CHECK-V8-NEXT: bx lr
; CHECK-V8-NEXT: .p2align 2
; CHECK-V8-NEXT: @ %bb.2:
; CHECK-V8-NEXT: .LCPI2_0:
; CHECK-V8-NEXT: .long .Ltmp2
;
; CHECK-RESTRICT-IT-LABEL: t3:
; CHECK-RESTRICT-IT: @ %bb.0: @ %bb
; CHECK-RESTRICT-IT-NEXT: ldr r1, .LCPI2_0
; CHECK-RESTRICT-IT-NEXT: str r1, [r0]
; CHECK-RESTRICT-IT-NEXT: .Ltmp2: @ Block address taken
; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %common.ret
; CHECK-RESTRICT-IT-NEXT: bx lr
; CHECK-RESTRICT-IT-NEXT: .p2align 2
; CHECK-RESTRICT-IT-NEXT: @ %bb.2:
; CHECK-RESTRICT-IT-NEXT: .LCPI2_0:
; CHECK-RESTRICT-IT-NEXT: .long .Ltmp2
bb:
store i8* blockaddress(@t3, %KBBlockZero_return_1), i8** %retaddr
br i1 %tst, label %bb77, label %bb7.i
@ -73,9 +229,53 @@ KBBlockZero.exit: ; preds = %bb2.i
@foo = global i32 ()* null
define i32 @t4(i32 %x, i32 ()* %p_foo) {
; CHECK-LABEL: t4:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: push {r4, lr}
; CHECK-NEXT: mov r4, r0
; CHECK-NEXT: cmp r0, #59
; CHECK-NEXT: ittt gt
; CHECK-NEXT: mvngt r0, #119
; CHECK-NEXT: addgt r0, r4
; CHECK-NEXT: popgt {r4, pc}
; CHECK-NEXT: LBB3_1: @ %if.then
; CHECK-NEXT: blx r1
; CHECK-NEXT: mov.w r0, #-1
; CHECK-NEXT: add r0, r4
; CHECK-NEXT: pop {r4, pc}
;
; CHECK-V8-LABEL: t4:
; CHECK-V8: @ %bb.0: @ %entry
; CHECK-V8-NEXT: push {r4, lr}
; CHECK-V8-NEXT: mov r4, r0
; CHECK-V8-NEXT: cmp r0, #59
; CHECK-V8-NEXT: bgt .LBB3_2
; CHECK-V8-NEXT: @ %bb.1: @ %if.then
; CHECK-V8-NEXT: blx r1
; CHECK-V8-NEXT: mov.w r0, #-1
; CHECK-V8-NEXT: add r0, r4
; CHECK-V8-NEXT: pop {r4, pc}
; CHECK-V8-NEXT: .LBB3_2:
; CHECK-V8-NEXT: mvn r0, #119
; CHECK-V8-NEXT: add r0, r4
; CHECK-V8-NEXT: pop {r4, pc}
;
; CHECK-RESTRICT-IT-LABEL: t4:
; CHECK-RESTRICT-IT: @ %bb.0: @ %entry
; CHECK-RESTRICT-IT-NEXT: push {r4, lr}
; CHECK-RESTRICT-IT-NEXT: mov r4, r0
; CHECK-RESTRICT-IT-NEXT: cmp r0, #59
; CHECK-RESTRICT-IT-NEXT: bgt .LBB3_2
; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %if.then
; CHECK-RESTRICT-IT-NEXT: blx r1
; CHECK-RESTRICT-IT-NEXT: mov.w r0, #-1
; CHECK-RESTRICT-IT-NEXT: add r0, r4
; CHECK-RESTRICT-IT-NEXT: pop {r4, pc}
; CHECK-RESTRICT-IT-NEXT: .LBB3_2:
; CHECK-RESTRICT-IT-NEXT: mvn r0, #119
; CHECK-RESTRICT-IT-NEXT: add r0, r4
; CHECK-RESTRICT-IT-NEXT: pop {r4, pc}
entry:
;CHECK-LABEL: t4:
;CHECK-V8-LABEL: t4:
%cmp = icmp slt i32 %x, 60
br i1 %cmp, label %if.then, label %if.else
@ -99,51 +299,67 @@ return: ; preds = %if.end5, %if.then4,
; predicated block.
; B can be predicated with A.BrToBPredicate into A iff B.Predicate is less
; "permissive" than A.BrToBPredicate, i.e., iff A.BrToBPredicate subsumes
; B.Predicate.
; Hard-coded registers comes from the ABI.
; CHECK-LABEL: wrapDistance:
; CHECK: cmp r1, #59
; CHECK-NEXT: itt le
; CHECK-NEXT: suble r0, r2, #1
; CHECK-NEXT: bxle lr
; CHECK-NEXT: LBB{{.*}}:
; CHECK-NEXT: subs [[REG:r[0-9]+]], #120
; CHECK-NEXT: cmp [[REG]], r1
; CHECK-NOT: it lt
; CHECK-NEXT: bge [[LABEL:.+]]
; Next BB
; CHECK-NOT: cmplt
; CHECK: cmp r0, #119
; CHECK-NEXT: itt le
; CHECK-NEXT: addle r0, r1, #1
; CHECK-NEXT: bxle lr
; Next BB
; CHECK: [[LABEL]]:
; CHECK-NEXT: subs r0, r1, r0
; CHECK-NEXT: bx lr
; CHECK-V8-LABEL: wrapDistance:
; CHECK-V8: cmp r1, #59
; CHECK-V8-NEXT: bgt
; CHECK-V8-NEXT: %if.then
; CHECK-V8-NEXT: subs r0, r2, #1
; CHECK-V8-NEXT: bx lr
; CHECK-V8-NEXT: %if.else
; CHECK-V8-NEXT: subs [[REG:r[0-9]+]], #120
; CHECK-V8-NEXT: cmp [[REG]], r1
; CHECK-V8-NEXT: bge
; CHECK-V8-NEXT: %if.else
; CHECK-V8-NEXT: cmp r0, #119
; CHECK-V8-NEXT: bgt
; CHECK-V8-NEXT: %if.then4
; CHECK-V8-NEXT: adds r0, r1, #1
; CHECK-V8-NEXT: bx lr
; CHECK-V8-NEXT: %if.end5
; CHECK-V8-NEXT: subs r0, r1, r0
; CHECK-V8-NEXT: bx lr
; B.Predicate.
define i32 @wrapDistance(i32 %tx, i32 %sx, i32 %w) {
; CHECK-LABEL: wrapDistance:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: cmp r1, #59
; CHECK-NEXT: itt le
; CHECK-NEXT: suble r0, r2, #1
; CHECK-NEXT: bxle lr
; CHECK-NEXT: LBB4_1: @ %if.else
; CHECK-NEXT: subs r2, #120
; CHECK-NEXT: cmp r2, r1
; CHECK-NEXT: bge LBB4_3
; CHECK-NEXT: @ %bb.2: @ %if.else
; CHECK-NEXT: cmp r0, #119
; CHECK-NEXT: itt le
; CHECK-NEXT: addle r0, r1, #1
; CHECK-NEXT: bxle lr
; CHECK-NEXT: LBB4_3: @ %if.end5
; CHECK-NEXT: subs r0, r1, r0
; CHECK-NEXT: bx lr
;
; CHECK-V8-LABEL: wrapDistance:
; CHECK-V8: @ %bb.0: @ %entry
; CHECK-V8-NEXT: cmp r1, #59
; CHECK-V8-NEXT: itt le
; CHECK-V8-NEXT: suble r0, r2, #1
; CHECK-V8-NEXT: bxle lr
; CHECK-V8-NEXT: .LBB4_1: @ %if.else
; CHECK-V8-NEXT: subs r2, #120
; CHECK-V8-NEXT: cmp r2, r1
; CHECK-V8-NEXT: bge .LBB4_3
; CHECK-V8-NEXT: @ %bb.2: @ %if.else
; CHECK-V8-NEXT: cmp r0, #119
; CHECK-V8-NEXT: itt le
; CHECK-V8-NEXT: addle r0, r1, #1
; CHECK-V8-NEXT: bxle lr
; CHECK-V8-NEXT: .LBB4_3: @ %if.end5
; CHECK-V8-NEXT: subs r0, r1, r0
; CHECK-V8-NEXT: bx lr
;
; CHECK-RESTRICT-IT-LABEL: wrapDistance:
; CHECK-RESTRICT-IT: @ %bb.0: @ %entry
; CHECK-RESTRICT-IT-NEXT: cmp r1, #59
; CHECK-RESTRICT-IT-NEXT: bgt .LBB4_2
; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %if.then
; CHECK-RESTRICT-IT-NEXT: subs r0, r2, #1
; CHECK-RESTRICT-IT-NEXT: bx lr
; CHECK-RESTRICT-IT-NEXT: .LBB4_2: @ %if.else
; CHECK-RESTRICT-IT-NEXT: subs r2, #120
; CHECK-RESTRICT-IT-NEXT: cmp r2, r1
; CHECK-RESTRICT-IT-NEXT: bge .LBB4_5
; CHECK-RESTRICT-IT-NEXT: @ %bb.3: @ %if.else
; CHECK-RESTRICT-IT-NEXT: cmp r0, #119
; CHECK-RESTRICT-IT-NEXT: bgt .LBB4_5
; CHECK-RESTRICT-IT-NEXT: @ %bb.4: @ %if.then4
; CHECK-RESTRICT-IT-NEXT: adds r0, r1, #1
; CHECK-RESTRICT-IT-NEXT: bx lr
; CHECK-RESTRICT-IT-NEXT: .LBB4_5: @ %if.end5
; CHECK-RESTRICT-IT-NEXT: subs r0, r1, r0
; CHECK-RESTRICT-IT-NEXT: bx lr
entry:
%cmp = icmp slt i32 %sx, 60
br i1 %cmp, label %if.then, label %if.else

View File

@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=arm-eabi -arm-atomic-cfg-tidy=0 %s -o - | FileCheck -check-prefix=ARM %s
; RUN: llc -mtriple=thumb-eabi -arm-atomic-cfg-tidy=0 %s -o - | FileCheck -check-prefix=THUMB %s
; RUN: llc -mtriple=thumb-eabi -arm-atomic-cfg-tidy=0 -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck -check-prefix=T2 %s
@ -11,6 +12,152 @@
; THUMB-LABEL: foo:
; T2-LABEL: foo:
define %struct.Foo* @foo(%struct.Foo* %this, i32 %acc) nounwind readonly align 2 {
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: add r2, r0, #4
; ARM-NEXT: mov r12, #1
; ARM-NEXT: b .LBB0_3
; ARM-NEXT: .LBB0_1: @ %tailrecurse.switch
; ARM-NEXT: @ in Loop: Header=BB0_3 Depth=1
; ARM-NEXT: cmp r3, #1
; ARM-NEXT: movne pc, lr
; ARM-NEXT: .LBB0_2: @ %sw.bb
; ARM-NEXT: @ in Loop: Header=BB0_3 Depth=1
; ARM-NEXT: orr r1, r3, r1, lsl #1
; ARM-NEXT: add r2, r2, #4
; ARM-NEXT: add r12, r12, #1
; ARM-NEXT: .LBB0_3: @ %tailrecurse
; ARM-NEXT: @ =>This Inner Loop Header: Depth=1
; ARM-NEXT: ldr r3, [r2, #-4]
; ARM-NEXT: ands r3, r3, #3
; ARM-NEXT: beq .LBB0_2
; ARM-NEXT: @ %bb.4: @ %tailrecurse.switch
; ARM-NEXT: @ in Loop: Header=BB0_3 Depth=1
; ARM-NEXT: cmp r3, #3
; ARM-NEXT: moveq r0, r2
; ARM-NEXT: moveq pc, lr
; ARM-NEXT: .LBB0_5: @ %tailrecurse.switch
; ARM-NEXT: @ in Loop: Header=BB0_3 Depth=1
; ARM-NEXT: cmp r3, #2
; ARM-NEXT: bne .LBB0_1
; ARM-NEXT: @ %bb.6: @ %sw.bb8
; ARM-NEXT: add r1, r1, r12
; ARM-NEXT: add r0, r0, r1, lsl #2
; ARM-NEXT: mov pc, lr
;
; THUMB: @ %bb.0: @ %entry
; THUMB-NEXT: .save {r4, r5, r7, lr}
; THUMB-NEXT: push {r4, r5, r7, lr}
; THUMB-NEXT: movs r2, #1
; THUMB-NEXT: movs r3, r0
; THUMB-NEXT: .LBB0_1: @ %tailrecurse
; THUMB-NEXT: @ =>This Inner Loop Header: Depth=1
; THUMB-NEXT: ldr r5, [r3]
; THUMB-NEXT: movs r4, #3
; THUMB-NEXT: ands r4, r5
; THUMB-NEXT: beq .LBB0_5
; THUMB-NEXT: @ %bb.2: @ %tailrecurse.switch
; THUMB-NEXT: @ in Loop: Header=BB0_1 Depth=1
; THUMB-NEXT: cmp r4, #3
; THUMB-NEXT: beq .LBB0_6
; THUMB-NEXT: @ %bb.3: @ %tailrecurse.switch
; THUMB-NEXT: @ in Loop: Header=BB0_1 Depth=1
; THUMB-NEXT: cmp r4, #2
; THUMB-NEXT: beq .LBB0_7
; THUMB-NEXT: @ %bb.4: @ %tailrecurse.switch
; THUMB-NEXT: @ in Loop: Header=BB0_1 Depth=1
; THUMB-NEXT: cmp r4, #1
; THUMB-NEXT: bne .LBB0_9
; THUMB-NEXT: .LBB0_5: @ %sw.bb
; THUMB-NEXT: @ in Loop: Header=BB0_1 Depth=1
; THUMB-NEXT: lsls r1, r1, #1
; THUMB-NEXT: orrs r4, r1
; THUMB-NEXT: adds r3, r3, #4
; THUMB-NEXT: adds r2, r2, #1
; THUMB-NEXT: movs r1, r4
; THUMB-NEXT: b .LBB0_1
; THUMB-NEXT: .LBB0_6: @ %sw.bb6
; THUMB-NEXT: adds r0, r3, #4
; THUMB-NEXT: b .LBB0_8
; THUMB-NEXT: .LBB0_7: @ %sw.bb8
; THUMB-NEXT: adds r1, r1, r2
; THUMB-NEXT: lsls r1, r1, #2
; THUMB-NEXT: adds r0, r0, r1
; THUMB-NEXT: .LBB0_8: @ %sw.bb6
; THUMB-NEXT: pop {r4, r5, r7}
; THUMB-NEXT: pop {r1}
; THUMB-NEXT: bx r1
; THUMB-NEXT: .LBB0_9: @ %sw.epilog
; THUMB-NEXT: pop {r4, r5, r7}
; THUMB-NEXT: pop {r0}
; THUMB-NEXT: bx r0
;
; T2: @ %bb.0: @ %entry
; T2-NEXT: adds r2, r0, #4
; T2-NEXT: mov.w r12, #1
; T2-NEXT: b .LBB0_3
; T2-NEXT: .LBB0_1: @ %tailrecurse.switch
; T2-NEXT: @ in Loop: Header=BB0_3 Depth=1
; T2-NEXT: cmp r3, #1
; T2-NEXT: it ne
; T2-NEXT: bxne lr
; T2-NEXT: .LBB0_2: @ %sw.bb
; T2-NEXT: @ in Loop: Header=BB0_3 Depth=1
; T2-NEXT: orr.w r1, r3, r1, lsl #1
; T2-NEXT: adds r2, #4
; T2-NEXT: add.w r12, r12, #1
; T2-NEXT: .LBB0_3: @ %tailrecurse
; T2-NEXT: @ =>This Inner Loop Header: Depth=1
; T2-NEXT: ldr r3, [r2, #-4]
; T2-NEXT: ands r3, r3, #3
; T2-NEXT: beq .LBB0_2
; T2-NEXT: @ %bb.4: @ %tailrecurse.switch
; T2-NEXT: @ in Loop: Header=BB0_3 Depth=1
; T2-NEXT: cmp r3, #3
; T2-NEXT: itt eq
; T2-NEXT: moveq r0, r2
; T2-NEXT: bxeq lr
; T2-NEXT: .LBB0_5: @ %tailrecurse.switch
; T2-NEXT: @ in Loop: Header=BB0_3 Depth=1
; T2-NEXT: cmp r3, #2
; T2-NEXT: bne .LBB0_1
; T2-NEXT: @ %bb.6: @ %sw.bb8
; T2-NEXT: add r1, r12
; T2-NEXT: add.w r0, r0, r1, lsl #2
; T2-NEXT: bx lr
;
; V8: @ %bb.0: @ %entry
; V8-NEXT: adds r2, r0, #4
; V8-NEXT: mov.w r12, #1
; V8-NEXT: b .LBB0_3
; V8-NEXT: .LBB0_1: @ %tailrecurse.switch
; V8-NEXT: @ in Loop: Header=BB0_3 Depth=1
; V8-NEXT: cmp r3, #1
; V8-NEXT: it ne
; V8-NEXT: bxne lr
; V8-NEXT: .LBB0_2: @ %sw.bb
; V8-NEXT: @ in Loop: Header=BB0_3 Depth=1
; V8-NEXT: orr.w r1, r3, r1, lsl #1
; V8-NEXT: adds r2, #4
; V8-NEXT: add.w r12, r12, #1
; V8-NEXT: .LBB0_3: @ %tailrecurse
; V8-NEXT: @ =>This Inner Loop Header: Depth=1
; V8-NEXT: ldr r3, [r2, #-4]
; V8-NEXT: ands r3, r3, #3
; V8-NEXT: beq .LBB0_2
; V8-NEXT: @ %bb.4: @ %tailrecurse.switch
; V8-NEXT: @ in Loop: Header=BB0_3 Depth=1
; V8-NEXT: cmp r3, #3
; V8-NEXT: itt eq
; V8-NEXT: moveq r0, r2
; V8-NEXT: bxeq lr
; V8-NEXT: .LBB0_5: @ %tailrecurse.switch
; V8-NEXT: @ in Loop: Header=BB0_3 Depth=1
; V8-NEXT: cmp r3, #2
; V8-NEXT: bne .LBB0_1
; V8-NEXT: @ %bb.6: @ %sw.bb8
; V8-NEXT: add r1, r12
; V8-NEXT: add.w r0, r0, r1, lsl #2
; V8-NEXT: bx lr
entry:
%scevgep = getelementptr %struct.Foo, %struct.Foo* %this, i32 1
br label %tailrecurse
@ -24,31 +171,15 @@ tailrecurse: ; preds = %sw.bb, %entry
%tmp2 = load i8*, i8** %scevgep5
%0 = ptrtoint i8* %tmp2 to i32
; ARM: ands {{r[0-9]+}}, {{r[0-9]+}}, #3
; ARM-NEXT: beq
; THUMB: movs r[[R0:[0-9]+]], #3
; THUMB-NEXT: ands r[[R0]], r
; THUMB-NEXT: beq
; T2: ands {{r[0-9]+}}, {{r[0-9]+}}, #3
; T2-NEXT: beq
%and = and i32 %0, 3
%tst = icmp eq i32 %and, 0
br i1 %tst, label %sw.bb, label %tailrecurse.switch
tailrecurse.switch: ; preds = %tailrecurse
; V8-LABEL: %tailrecurse.switch
; V8: cmp
; V8-NEXT: beq
; V8-NEXT: %tailrecurse.switch
; V8: cmp
; V8-NEXT: beq
; V8-NEXT: %tailrecurse.switch
; V8: cmp
; V8-NEXT: bne
; V8-NEXT: %sw.bb
switch i32 %and, label %sw.epilog [
i32 1, label %sw.bb
i32 3, label %sw.bb6
@ -85,39 +216,94 @@ sw.epilog: ; preds = %tailrecurse.switch
; T2-LABEL: bar:
; V8-LABEL: bar:
define internal zeroext i8 @bar(%struct.S* %x, %struct.S* nocapture %y) nounwind readonly {
; ARM: @ %bb.0: @ %entry
; ARM-NEXT: ldrb r2, [r0, #4]
; ARM-NEXT: ands r2, r2, #112
; ARM-NEXT: ldrbne r1, [r1, #4]
; ARM-NEXT: andsne r1, r1, #112
; ARM-NEXT: beq .LBB1_2
; ARM-NEXT: @ %bb.1: @ %bb2
; ARM-NEXT: cmp r2, #16
; ARM-NEXT: cmpne r1, #16
; ARM-NEXT: andeq r0, r0, #255
; ARM-NEXT: moveq pc, lr
; ARM-NEXT: .LBB1_2: @ %return
; ARM-NEXT: mov r0, #1
; ARM-NEXT: mov pc, lr
;
; THUMB: @ %bb.0: @ %entry
; THUMB-NEXT: ldrb r2, [r0, #4]
; THUMB-NEXT: movs r3, #112
; THUMB-NEXT: ands r2, r3
; THUMB-NEXT: beq .LBB1_4
; THUMB-NEXT: @ %bb.1: @ %bb
; THUMB-NEXT: ldrb r1, [r1, #4]
; THUMB-NEXT: ands r1, r3
; THUMB-NEXT: beq .LBB1_4
; THUMB-NEXT: @ %bb.2: @ %bb2
; THUMB-NEXT: cmp r2, #16
; THUMB-NEXT: beq .LBB1_5
; THUMB-NEXT: @ %bb.3: @ %bb2
; THUMB-NEXT: cmp r1, #16
; THUMB-NEXT: beq .LBB1_5
; THUMB-NEXT: .LBB1_4: @ %return
; THUMB-NEXT: movs r0, #1
; THUMB-NEXT: bx lr
; THUMB-NEXT: .LBB1_5: @ %bb4
; THUMB-NEXT: movs r1, #255
; THUMB-NEXT: ands r0, r1
; THUMB-NEXT: bx lr
;
; T2: @ %bb.0: @ %entry
; T2-NEXT: ldrb r2, [r0, #4]
; T2-NEXT: ands r2, r2, #112
; T2-NEXT: itt ne
; T2-NEXT: ldrbne r1, [r1, #4]
; T2-NEXT: andsne r1, r1, #112
; T2-NEXT: beq .LBB1_2
; T2-NEXT: @ %bb.1: @ %bb2
; T2-NEXT: cmp r2, #16
; T2-NEXT: itee ne
; T2-NEXT: cmpne r1, #16
; T2-NEXT: uxtbeq r0, r0
; T2-NEXT: bxeq lr
; T2-NEXT: .LBB1_2: @ %return
; T2-NEXT: movs r0, #1
; T2-NEXT: bx lr
;
; V8: @ %bb.0: @ %entry
; V8-NEXT: ldrb r2, [r0, #4]
; V8-NEXT: ands r2, r2, #112
; V8-NEXT: itt ne
; V8-NEXT: ldrbne r1, [r1, #4]
; V8-NEXT: andsne r1, r1, #112
; V8-NEXT: beq .LBB1_2
; V8-NEXT: @ %bb.1: @ %bb2
; V8-NEXT: cmp r2, #16
; V8-NEXT: itee ne
; V8-NEXT: cmpne r1, #16
; V8-NEXT: uxtbeq r0, r0
; V8-NEXT: bxeq lr
; V8-NEXT: .LBB1_2: @ %return
; V8-NEXT: movs r0, #1
; V8-NEXT: bx lr
entry:
%0 = getelementptr inbounds %struct.S, %struct.S* %x, i32 0, i32 1, i32 0
%1 = load i8, i8* %0, align 1
%2 = zext i8 %1 to i32
; ARM: ands
; THUMB: ands
; T2: ands
; V8: ands
; V8-NEXT: beq
%3 = and i32 %2, 112
%4 = icmp eq i32 %3, 0
br i1 %4, label %return, label %bb
bb: ; preds = %entry
; V8-NEXT: %bb
%5 = getelementptr inbounds %struct.S, %struct.S* %y, i32 0, i32 1, i32 0
%6 = load i8, i8* %5, align 1
%7 = zext i8 %6 to i32
; ARM: andsne
; THUMB: ands
; T2: andsne
; V8: ands
; V8-NEXT: beq
%8 = and i32 %7, 112
%9 = icmp eq i32 %8, 0
br i1 %9, label %return, label %bb2
bb2: ; preds = %bb
; V8-NEXT: %bb2
; V8-NEXT: cmp
; V8-NEXT: it ne
; V8-NEXT: cmpne
; V8-NEXT: bne
%10 = icmp eq i32 %3, 16
%11 = icmp eq i32 %8, 16
%or.cond = or i1 %10, %11
@ -168,11 +354,10 @@ define i32 @test_tst_assessment(i32 %a, i32 %b) {
;
; V8-LABEL: test_tst_assessment:
; V8: @ %bb.0:
; V8-NEXT: and r2, r0, #1
; V8-NEXT: subs r0, r2, #1
; V8-NEXT: and r0, r0, #1
; V8-NEXT: lsls r1, r1, #31
; V8-NEXT: it eq
; V8-NEXT: moveq r0, r2
; V8-NEXT: it ne
; V8-NEXT: subne r0, #1
; V8-NEXT: bx lr
%and1 = and i32 %a, 1
%sub = sub i32 %and1, 1

View File

@ -186,8 +186,8 @@ define bfloat @test_fncall_soft(bfloat %bf, bfloat (bfloat, bfloat)* %f) {
; BASE-THUMB-NEXT: mov r0, r5
; BASE-THUMB-NEXT: mov r1, r5
; BASE-THUMB-NEXT: blx r4
; BASE-THUMB-NEXT: uxth r1, r0
; BASE-THUMB-NEXT: strh.w r0, [sp, #6]
; BASE-THUMB-NEXT: uxth r1, r0
; BASE-THUMB-NEXT: mov r0, r5
; BASE-THUMB-NEXT: blx r4
; BASE-THUMB-NEXT: ldrh.w r0, [sp, #6]

View File

@ -1045,21 +1045,19 @@ define i8 @test_atomic_cmpxchg_i8(i8 zeroext %wanted, i8 zeroext %new) nounwind
; function there.
; CHECK-ARM-NEXT: cmp r[[OLD]], r0
; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]
; CHECK-NEXT: bne .LBB{{[0-9]+}}_4
; CHECK-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}
; CHECK-NEXT: %bb.2:
; As above, r1 is a reasonable guess.
; CHECK: strexb [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
; CHECK-NEXT: cmp [[STATUS]], #0
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
; CHECK-ARM-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}
; CHECK-THUMB-NEXT: it eq
; CHECK-THUMB-NEXT: bxeq lr
; CHECK-ARM: mov r0, r[[OLD]]
; CHECK-ARM: clrex
; CHECK: bx lr
; CHECK-NEXT: .LBB{{[0-9]+}}_4:
; CHECK-NEXT: clrex
; CHECK-NOT: dmb
; CHECK-NOT: mcr
; CHECK-ARM: mov r0, r[[OLD]]
; CHECK-ARM-NEXT: bx lr
ret i8 %old
}
@ -1079,16 +1077,18 @@ define i16 @test_atomic_cmpxchg_i16(i16 zeroext %wanted, i16 zeroext %new) nounw
; function there.
; CHECK-ARM-NEXT: cmp r[[OLD]], r0
; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]
; CHECK-NEXT: bne .LBB{{[0-9]+}}_4
; CHECK-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}
; CHECK-NEXT: %bb.2:
; As above, r1 is a reasonable guess.
; CHECK: stlexh [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
; CHECK-NEXT: cmp [[STATUS]], #0
; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
; CHECK-ARM-NEXT: bne .LBB{{[0-9]+}}_{{[0-9]}}
; CHECK-THUMB-NEXT: it eq
; CHECK-THUMB-NEXT: bxeq lr
; CHECK-ARM: mov r0, r[[OLD]]
; CHECK: bx lr
; CHECK-NEXT: .LBB{{[0-9]+}}_4:
; CHECK-NEXT: clrex
; CHECK-ARM-NEXT: .LBB{{[0-9]+}}_{{[0-9]}}
; CHECK-ARM-NEXT: clrex
; CHECK-NOT: dmb
; CHECK-NOT: mcr

View File

@ -192,11 +192,11 @@ body: |
; CHECK-V7: tTAILJMPdND @extfunc, 14 /* CC::al */, $noreg, implicit $sp, implicit $sp
; CHECK-V8-LABEL: name: test_nosize
; CHECK-V8: bb.0 (%ir-block.0):
; CHECK-V8: successors: %bb.1(0x50000000), %bb.6(0x30000000)
; CHECK-V8: successors: %bb.1(0x80000000)
; CHECK-V8: liveins: $lr, $r7
; CHECK-V8: renamable $r0 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK-V8: t2CMPri killed renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
; CHECK-V8: t2Bcc %bb.6, 1 /* CC::ne */, killed $cpsr
; CHECK-V8: tTAILJMPdND @extfunc, 1 /* CC::ne */, killed $cpsr, implicit $sp, implicit $sp
; CHECK-V8: bb.1.b1:
; CHECK-V8: successors: %bb.3(0x40000000), %bb.2(0x40000000)
; CHECK-V8: liveins: $r7, $lr
@ -216,15 +216,12 @@ body: |
; CHECK-V8: renamable $r0 = t2LDRi12 undef renamable $r0, 0, 14 /* CC::al */, $noreg :: (load (s32) from `i32* undef`)
; CHECK-V8: renamable $r0 = t2ANDri killed renamable $r0, 256, 14 /* CC::al */, $noreg, $noreg
; CHECK-V8: bb.4.b5:
; CHECK-V8: successors: %bb.5(0x30000000), %bb.6(0x50000000)
; CHECK-V8: successors: %bb.5(0x50000000)
; CHECK-V8: liveins: $r0
; CHECK-V8: t2CMPri killed renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
; CHECK-V8: $sp = t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r7, def $lr
; CHECK-V8: t2Bcc %bb.6, 1 /* CC::ne */, killed $cpsr
; CHECK-V8: bb.5.b8:
; CHECK-V8: liveins: $lr, $r7
; CHECK-V8: tBX_RET 14 /* CC::al */, $noreg
; CHECK-V8: bb.6.b7:
; CHECK-V8: tBX_RET 0 /* CC::eq */, killed $cpsr
; CHECK-V8: bb.5.b7:
; CHECK-V8: liveins: $lr, $r7
; CHECK-V8: tTAILJMPdND @extfunc, 14 /* CC::al */, $noreg, implicit $sp, implicit $sp
bb.0 (%ir-block.0):

View File

@ -1,5 +1,5 @@
; RUN: llc -O3 -mtriple=armv8a-none-eabi -mattr=+fullfp16 -o - %s | FileCheck %s
; RUN: llc -O3 -mtriple=thumbv8a-none-eabi -mattr=+fullfp16 -arm-no-restrict-it -o - %s | FileCheck %s
; RUN: llc -O3 -mtriple=armv8a-none-eabi -mattr=+fullfp16 -arm-restrict-it -o - %s | FileCheck %s
; RUN: llc -O3 -mtriple=thumbv8a-none-eabi -mattr=+fullfp16 -o - %s | FileCheck %s
; Require the vmul.f16 not to be predicated, because it's illegal to
; do so with fp16 instructions

View File

@ -3,8 +3,8 @@
; RUN: llc -mtriple=armv7 < %s | FileCheck %s --check-prefixes=ARM,ARM78
; RUN: llc -mtriple=armv8a < %s | FileCheck %s --check-prefixes=ARM,ARM78
; RUN: llc -mtriple=thumbv6 < %s | FileCheck %s --check-prefixes=THUMB,THUMB6
; RUN: llc -mtriple=thumbv7 < %s | FileCheck %s --check-prefixes=THUMB,THUMB78,THUMB7
; RUN: llc -mtriple=thumbv8-eabi < %s | FileCheck %s --check-prefixes=THUMB,THUMB78,THUMB8
; RUN: llc -mtriple=thumbv7 < %s | FileCheck %s --check-prefixes=THUMB,THUMB78
; RUN: llc -mtriple=thumbv8-eabi < %s | FileCheck %s --check-prefixes=THUMB,THUMB78
; We are looking for the following pattern here:
; (X & (C l>> Y)) ==/!= 0
@ -350,32 +350,18 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; THUMB6-NEXT: adcs r0, r2
; THUMB6-NEXT: pop {r7, pc}
;
; THUMB7-LABEL: scalar_i64_signbit_eq:
; THUMB7: @ %bb.0:
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: lsls r1, r2
; THUMB7-NEXT: subs r2, #32
; THUMB7-NEXT: lsr.w r3, r0, r3
; THUMB7-NEXT: orr.w r1, r1, r3
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lslpl.w r1, r0, r2
; THUMB7-NEXT: mvns r0, r1
; THUMB7-NEXT: lsrs r0, r0, #31
; THUMB7-NEXT: bx lr
;
; THUMB8-LABEL: scalar_i64_signbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsls r1, r2
; THUMB8-NEXT: lsr.w r3, r0, r3
; THUMB8-NEXT: orrs r1, r3
; THUMB8-NEXT: subs r2, #32
; THUMB8-NEXT: lsl.w r0, r0, r2
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r0, r1
; THUMB8-NEXT: mvns r0, r0
; THUMB8-NEXT: lsrs r0, r0, #31
; THUMB8-NEXT: bx lr
; THUMB78-LABEL: scalar_i64_signbit_eq:
; THUMB78: @ %bb.0:
; THUMB78-NEXT: rsb.w r3, r2, #32
; THUMB78-NEXT: lsls r1, r2
; THUMB78-NEXT: subs r2, #32
; THUMB78-NEXT: lsr.w r3, r0, r3
; THUMB78-NEXT: orr.w r1, r1, r3
; THUMB78-NEXT: it pl
; THUMB78-NEXT: lslpl.w r1, r0, r2
; THUMB78-NEXT: mvns r0, r1
; THUMB78-NEXT: lsrs r0, r0, #31
; THUMB78-NEXT: bx lr
%t0 = lshr i64 9223372036854775808, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
@ -471,40 +457,22 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB6-NEXT: .LCPI11_0:
; THUMB6-NEXT: .long 4294901760 @ 0xffff0000
;
; THUMB7-LABEL: scalar_i64_bitsinmiddle_eq:
; THUMB7: @ %bb.0:
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: lsls r1, r2
; THUMB7-NEXT: lsr.w r3, r0, r3
; THUMB7-NEXT: orrs r1, r3
; THUMB7-NEXT: subs.w r3, r2, #32
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lslpl.w r1, r0, r3
; THUMB7-NEXT: lsl.w r0, r0, r2
; THUMB7-NEXT: it pl
; THUMB7-NEXT: movpl r0, #0
; THUMB7-NEXT: pkhbt r0, r1, r0
; THUMB7-NEXT: clz r0, r0
; THUMB7-NEXT: lsrs r0, r0, #5
; THUMB7-NEXT: bx lr
;
; THUMB8-LABEL: scalar_i64_bitsinmiddle_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsls r1, r2
; THUMB8-NEXT: lsr.w r3, r0, r3
; THUMB8-NEXT: orrs r1, r3
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: lsl.w r3, r0, r3
; THUMB8-NEXT: lsl.w r0, r0, r2
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r3, r1
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r0, #0
; THUMB8-NEXT: pkhbt r0, r3, r0
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: bx lr
; THUMB78-LABEL: scalar_i64_bitsinmiddle_eq:
; THUMB78: @ %bb.0:
; THUMB78-NEXT: rsb.w r3, r2, #32
; THUMB78-NEXT: lsls r1, r2
; THUMB78-NEXT: lsr.w r3, r0, r3
; THUMB78-NEXT: orrs r1, r3
; THUMB78-NEXT: subs.w r3, r2, #32
; THUMB78-NEXT: it pl
; THUMB78-NEXT: lslpl.w r1, r0, r3
; THUMB78-NEXT: lsl.w r0, r0, r2
; THUMB78-NEXT: it pl
; THUMB78-NEXT: movpl r0, #0
; THUMB78-NEXT: pkhbt r0, r1, r0
; THUMB78-NEXT: clz r0, r0
; THUMB78-NEXT: lsrs r0, r0, #5
; THUMB78-NEXT: bx lr
%t0 = lshr i64 281474976645120, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0

View File

@ -49,8 +49,8 @@ define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
;
; THUMB8-LABEL: scalar_i8_signbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: uxtb r1, r1
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: movs r1, #1
; THUMB8-NEXT: eor.w r0, r1, r0, lsr #7
@ -92,8 +92,8 @@ define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
;
; THUMB8-LABEL: scalar_i8_lowestbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: uxtb r1, r1
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: movs r1, #1
; THUMB8-NEXT: bic.w r0, r1, r0
@ -138,8 +138,8 @@ define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
;
; THUMB8-LABEL: scalar_i8_bitsinmiddle_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: uxtb r1, r1
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: and r0, r0, #24
; THUMB8-NEXT: clz r0, r0
@ -186,8 +186,8 @@ define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
;
; THUMB8-LABEL: scalar_i16_signbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: uxth r1, r1
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: movs r1, #1
; THUMB8-NEXT: eor.w r0, r1, r0, lsr #15
@ -229,8 +229,8 @@ define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
;
; THUMB8-LABEL: scalar_i16_lowestbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: uxth r1, r1
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: movs r1, #1
; THUMB8-NEXT: bic.w r0, r1, r0
@ -276,8 +276,8 @@ define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
;
; THUMB8-LABEL: scalar_i16_bitsinmiddle_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: uxth r1, r1
; THUMB8-NEXT: uxth r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: and r0, r0, #4080
; THUMB8-NEXT: clz r0, r0
@ -481,14 +481,13 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; THUMB8: @ %bb.0:
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsrs r0, r2
; THUMB8-NEXT: lsl.w r3, r1, r3
; THUMB8-NEXT: orrs r0, r3
; THUMB8-NEXT: subs r2, #32
; THUMB8-NEXT: lsr.w r1, r1, r2
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r1, r0
; THUMB8-NEXT: movs r0, #1
; THUMB8-NEXT: bics r0, r1
; THUMB8-NEXT: lsl.w r3, r1, r3
; THUMB8-NEXT: orr.w r0, r0, r3
; THUMB8-NEXT: it pl
; THUMB8-NEXT: lsrpl.w r0, r1, r2
; THUMB8-NEXT: movs r1, #1
; THUMB8-NEXT: bic.w r0, r1, r0
; THUMB8-NEXT: bx lr
%t0 = shl i64 1, %y
%t1 = and i64 %t0, %x
@ -565,13 +564,12 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB8-NEXT: lsl.w r3, r1, r3
; THUMB8-NEXT: orrs r0, r3
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: lsr.w r3, r1, r3
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r3, r0
; THUMB8-NEXT: lsr.w r0, r1, r2
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r0, #0
; THUMB8-NEXT: pkhbt r0, r0, r3
; THUMB8-NEXT: lsrpl.w r0, r1, r3
; THUMB8-NEXT: lsr.w r1, r1, r2
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r1, #0
; THUMB8-NEXT: pkhbt r0, r1, r0
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: bx lr
@ -988,8 +986,8 @@ define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
;
; THUMB8-LABEL: scalar_i8_signbit_ne:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: uxtb r1, r1
; THUMB8-NEXT: uxtb r0, r0
; THUMB8-NEXT: lsrs r0, r1
; THUMB8-NEXT: lsrs r0, r0, #7
; THUMB8-NEXT: bx lr

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -mtriple=thumbv8 -stop-after=if-converter -arm-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8 -stop-after=if-converter -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
%struct.S = type { i8* (i8*)*, [1 x i8] }
define internal zeroext i8 @bar(%struct.S* %x, %struct.S* nocapture %y) nounwind readonly {
@ -18,7 +18,7 @@ bb:
%9 = icmp eq i32 %8, 0
br i1 %9, label %return, label %bb2
; CHECK: bb.2.bb2:
; CHECK: bb.1.bb:
; CHECK: successors: %bb.4(0x40000000), %bb.3(0x40000000)
bb2:

View File

@ -35,7 +35,7 @@ if.then: ; preds = %entry
; CHECK-LABEL: double_return:
; HARDEN: {{bx lr$}}
; NOHARDENARM: {{bxgt lr$}}
; NOHARDENTHUMB: {{bx lr$}}
; NOHARDENTHUMB: {{bxgt lr$}}
; ISBDSB-NEXT: dsb sy
; ISBDSB-NEXT: isb
; SB-NEXT: {{ sb$}}

View File

@ -19,9 +19,8 @@ while.cond38: ; preds = %if.end111, %entry
; CHECK: %cond.true77
; CHECK-NEXT: @ in Loop
; CHECK-NEXT: cmp.w {{r[0-9]+}}, #0
; CHECK-NEXT: it eq
; CHECK-NEXT: ite eq
; CHECK-NEXT: ldreq
; CHECK-NEXT: it ne
; N.b. 16-bit mov instruction in IT block does not set flags.
; CHECK-NEXT: movne
; CHECK-NEXT: mvns

View File

@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefixes=ALL,V01
; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s --check-prefixes=ALL,V01
; RUN: llc < %s -mtriple=thumbv8 -arm-no-restrict-it | FileCheck %s --check-prefixes=ALL,V23,V2
; RUN: llc < %s -mtriple=thumbv8 -arm-no-restrict-it -enable-tail-merge=0 | FileCheck %s --check-prefixes=ALL,V23,V3
; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s --check-prefixes=ALL,V23,V2
; RUN: llc < %s -mtriple=thumbv8 -enable-tail-merge=0 | FileCheck %s --check-prefixes=ALL,V23,V3
define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
; ALL-LABEL: t1:

View File

@ -1,6 +1,6 @@
; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-atomic-cfg-tidy=0 -arm-default-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8-apple-ios -arm-atomic-cfg-tidy=0 -arm-no-restrict-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s
define void @foo(i32 %X, i32 %Y) {
entry:

View File

@ -1,6 +1,6 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-atomic-cfg-tidy=0 -arm-default-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8-apple-darwin -arm-atomic-cfg-tidy=0 -arm-no-restrict-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8-apple-darwin -arm-atomic-cfg-tidy=0 | FileCheck %s
; There shouldn't be a unconditional branch at end of bb52.
; rdar://7184787

View File

@ -1,6 +1,6 @@
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv7 -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 -relocation-model=pic | FileCheck %s --check-prefix=CHECK-PIC
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 -arm-restrict-it -relocation-model=pic | FileCheck %s --check-prefix=CHECK-PIC
; RUN: llc < %s -mtriple=thumbv7 -arm-atomic-cfg-tidy=0 -arm-restrict-it -relocation-model=pic | FileCheck %s --check-prefix=CHECK-PIC
%struct.FF = type { i32 (i32*)*, i32 (i32*, i32*, i32, i32, i32, i32)*, i32 (i32, i32, i8*)*, void ()*, i32 (i32, i8*, i32*)*, i32 ()* }
@ -36,9 +36,9 @@ bb:
bb1:
; CHECK: %entry
; CHECK: it eq
; CHECK: it eq
; CHECK-NEXT: ldreq
; CHECK-NEXT: it eq
; CHECK-NEXT: it eq
; CHECK-NEXT: cmpeq
; CHECK: %bb1
%tmp5 = load i32, i32* %block_size, align 4

View File

@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard | FileCheck --check-prefixes=P01 %s
; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard -arm-restrict-it | FileCheck --check-prefixes=P01 %s
; RUN: llc < %s -mtriple=thumbv7-eabi -float-abi=hard -arm-restrict-it | FileCheck --check-prefixes=P01 %s
; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard -regalloc=basic | FileCheck --check-prefixes=P23 %s
; RUN: llc < %s -mtriple=thumbv8-eabi -float-abi=hard -regalloc=basic -arm-restrict-it | FileCheck --check-prefixes=P23 %s
; RUN: llc < %s -mtriple=thumbv7-eabi -float-abi=hard -regalloc=basic -arm-restrict-it | FileCheck --check-prefixes=P23 %s
%"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* }

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8 -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
; RUN: llc < %s -mtriple=thumbv7 -arm-atomic-cfg-tidy=0 -arm-restrict-it | FileCheck %s
; CHECK: it ne
; CHECK-NEXT: cmpne

View File

@ -1,32 +0,0 @@
; RUN: llc < %s -mtriple=thumbv7 -o - | llvm-mc -triple thumbv7 --show-encoding 2>&1 | FileCheck %s --check-prefix=V7
; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it -o - | llvm-mc -triple thumbv7 --show-encoding 2>&1 | FileCheck %s --check-prefix=V7_RESTRICT_IT
; RUN: llc < %s -mtriple=thumbv8 -o - | llvm-mc -triple thumbv8 --show-encoding 2>&1 | FileCheck %s --check-prefix=V8
; RUN: llc < %s -mtriple=thumbv8 -arm-no-restrict-it -o - | llvm-mc -triple thumbv8 --show-encoding 2>&1 | FileCheck %s --check-prefix=V8_NO_RESTRICT_IT
; V7-NOT: warning
; V7_RESTRICT_IT-NOT: warning
; V8-NOT: warning
; V8_NO_RESTRICT_IT: warning: deprecated instruction in IT block
; it ge @ encoding: [0xa8,0xbf]
; lslge.w r3, r12, lr @ encoding: [0x0c,0xfa,0x0e,0xf3] ; deprecated in ARMv8 thumb mode
define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) {
%t0 = shl i64 1, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
ret i1 %res
}
; V7-NOT: warning
; V7_RESTRICT_IT-NOT: warning
; V8-NOT: warning
; V8_NO_RESTRICT_IT: warning: deprecated instruction in IT block
; it ne @ encoding: [0x18,0xbf]
; movne.w r0, #-1 @ encoding: [0x4f,0xf0,0xff,0x30] ; deprecated in ARMv8 thumb mode
define i32 @icmp_eq_minus_one(i8* %ptr) {
%load = load i8, i8* %ptr, align 1
%conv = zext i8 %load to i32
%cmp = icmp eq i8 %load, -1
%ret = select i1 %cmp, i32 %conv, i32 -1
ret i32 %ret
}

View File

@ -33,28 +33,28 @@ mcr p15, #0, r5, c7, c10, #5
@ CHECK-NO-WARN-NOT: warning: deprecated since v7, use 'dmb'
it ge
movge r0, #4096
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV8-NOT: warning
@ CHECK-THUMBV7-NOT: warning
@ CHECK-NO-WARN-NOT: warning
ite ge
addge r0, r1
addlt r0, r2
@ CHECK-ARMV8: warning: applying IT instruction to more than one subsequent instruction is deprecated
@ CHECK-THUMBV8: warning: applying IT instruction to more than one subsequent instruction is deprecated
@ CHECK-ARMV8-NOT: warning
@ CHECK-THUMBV8-NOT: warning
@ CHECK-THUMBV7-NOT: warning
@ CHECK-NO-WARN-NOT: warning
it ge
movge r0, pc // invalid operand
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV8-NOT: warning
@ CHECK-THUMBV7-NOT: warning
@ CHECK-NO-WARN-NOT: warning
it ge
revge r0, r0 // invalid instruction
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV8-NOT: warning
@ CHECK-THUMBV7-NOT: warning
@ CHECK-NO-WARN-NOT: warning
it ge
clzge r0, r0 // only has 32-bit form
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV8-NOT: warning
@ CHECK-THUMBV7-NOT: warning
@ CHECK-NO-WARN-NOT: warning

File diff suppressed because it is too large Load Diff