diff options
| author | Diogo Sampaio <diogo.sampaio@arm.com> | 2020-01-13 11:36:02 +0000 |
|---|---|---|
| committer | Diogo Sampaio <diogo.sampaio@arm.com> | 2020-01-14 11:47:19 +0000 |
| commit | d94d079a6a5b12156e4b818c8ba46eb143f335b9 (patch) | |
| tree | 7524c45ac0f99e736d45f891263e872ede29d1ac /llvm/test | |
| parent | fd42a4ac7a69adb92f87c7fa927509f177dcc6ca (diff) | |
| download | bcm5719-llvm-d94d079a6a5b12156e4b818c8ba46eb143f335b9.tar.gz bcm5719-llvm-d94d079a6a5b12156e4b818c8ba46eb143f335b9.zip | |
[ARM][Thumb2] Fix ADD/SUB invalid writes to SP
Summary:
This patch fixes pr23772 [ARM] r226200 can emit illegal thumb2 instruction: "sub sp, r12, #80".
The violation was that SUB and ADD (reg, immediate) instructions can only write to SP if the source register is also SP. So the above instructions was unpredictable.
To enforce that the instruction t2(ADD|SUB)ri does not write to SP we now enforce the destination register to be rGPR (That exclude PC and SP).
Different than the ARM specification, that defines one instruction that can read from SP, and one that can't, here we inserted one that can't write to SP, and other that can only write to SP as to reuse most of the hard-coded size optimizations.
When performing this change, it uncovered that emitting Thumb2 Reg plus Immediate could not emit all variants of ADD SP, SP #imm instructions before so it was refactored to be able to. (see test/CodeGen/Thumb2/mve-stacksplot.mir where we use a subw sp, sp, Imm12 variant )
It also uncovered a disassembly issue of adr.w instructions, that were only written as SUBW instructions (see llvm/test/MC/Disassembler/ARM/thumb2.txt).
Reviewers: eli.friedman, dmgreen, carwil, olista01, efriedma, andreadb
Reviewed By: efriedma
Subscribers: gbedwell, john.brawn, efriedma, ostannard, kristof.beyls, hiraditya, dmgreen, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70680
Diffstat (limited to 'llvm/test')
19 files changed, 398 insertions, 62 deletions
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-arithmetic-ops.mir b/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-arithmetic-ops.mir index f760af5e0c7..f738724bff9 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-arithmetic-ops.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-arithmetic-ops.mir @@ -64,7 +64,7 @@ body: | %1(s32) = G_CONSTANT i32 786444 ; 0x000c000c %2(s32) = G_ADD %0, %1 - ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2ADDri [[VREGX]], 786444, 14, $noreg, $noreg + ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2ADDri [[VREGX]], 786444, 14, $noreg, $noreg $r0 = COPY %2(s32) ; CHECK: $r0 = COPY [[VREGRES]] @@ -92,7 +92,7 @@ body: | %1(s32) = G_CONSTANT i32 4093 %2(s32) = G_ADD %0, %1 - ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2ADDri12 [[VREGX]], 4093, 14, $noreg + ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2ADDri12 [[VREGX]], 4093, 14, $noreg $r0 = COPY %2(s32) ; CHECK: $r0 = COPY [[VREGRES]] @@ -178,7 +178,7 @@ body: | %1(s32) = G_CONSTANT i32 786444 ; 0x000c000c %2(s32) = G_SUB %0, %1 - ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2SUBri [[VREGX]], 786444, 14, $noreg, $noreg + ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2SUBri [[VREGX]], 786444, 14, $noreg, $noreg $r0 = COPY %2(s32) ; CHECK: $r0 = COPY [[VREGRES]] diff --git a/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir b/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir index ae7fdedd6f7..8f8e2a266a1 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/thumb-select-load-store.mir @@ -168,7 +168,7 @@ body: | liveins: $r0, $r1, $r2, $r3 %0(p0) = G_FRAME_INDEX %fixed-stack.2 - ; CHECK: [[FI32VREG:%[0-9]+]]:gprnopc = t2ADDri %fixed-stack.[[FI32]], 0, 14, $noreg, $noreg + ; CHECK: [[FI32VREG:%[0-9]+]]:rgpr = t2ADDri %fixed-stack.[[FI32]], 0, 14, $noreg, $noreg %1(s32) = G_LOAD %0(p0) :: (load 4) ; CHECK: [[LD32VREG:%[0-9]+]]:gpr = t2LDRi12 [[FI32VREG]], 0, 14, $noreg @@ -177,7 +177,7 @@ body: | ; CHECK: $r0 = COPY [[LD32VREG]] %2(p0) = G_FRAME_INDEX %fixed-stack.0 - ; CHECK: [[FI1VREG:%[0-9]+]]:gprnopc = t2ADDri %fixed-stack.[[FI1]], 0, 14, $noreg, $noreg + ; CHECK: [[FI1VREG:%[0-9]+]]:rgpr = t2ADDri %fixed-stack.[[FI1]], 0, 14, $noreg, $noreg %3(s1) = G_LOAD %2(p0) :: (load 1) ; CHECK: [[LD1VREG:%[0-9]+]]:gprnopc = t2LDRBi12 [[FI1VREG]], 0, 14, $noreg diff --git a/llvm/test/CodeGen/MIR/ARM/thumb2-sub-sp-t3.mir b/llvm/test/CodeGen/MIR/ARM/thumb2-sub-sp-t3.mir index d793bfc21f4..bafb3c46e47 100644 --- a/llvm/test/CodeGen/MIR/ARM/thumb2-sub-sp-t3.mir +++ b/llvm/test/CodeGen/MIR/ARM/thumb2-sub-sp-t3.mir @@ -1,7 +1,7 @@ --- | ; RUN: llc --run-pass=prologepilog -o - %s | FileCheck %s ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_register $r7 - ; CHECK-NEXT: $sp = frame-setup t2SUBri12 killed $sp, 4008, 14, $noreg + ; CHECK-NEXT: $sp = frame-setup t2SUBspImm12 killed $sp, 4008, 14, $noreg target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv7-none-none-eabi" diff --git a/llvm/test/CodeGen/Thumb2/bug-subw.ll b/llvm/test/CodeGen/Thumb2/bug-subw.ll new file mode 100644 index 00000000000..a9ca37e753b --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/bug-subw.ll @@ -0,0 +1,74 @@ +; pr23772 - [ARM] r226200 can emit illegal thumb2 instruction: "sub sp, r12, #80" +; RUN: llc -march=thumb -mcpu=cortex-m3 -O3 -filetype=asm -o - %s | FileCheck %s +; CHECK-NOT: sub{{.*}} sp, r{{.*}}, # +; CHECK: .fnend +; TODO: Missed optimization. The three instructions generated to subtract SP can be converged to a single one +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32" +target triple = "thumbv7m-unknown-unknown" +%B = type {%B*} +%R = type {i32} +%U = type {%U*, i8, i8} +%E = type {%B*, %U*} +%X = type {i32, i8, i8} +declare external [0 x i8]* @memalloc(i32, i32, i32) +declare external void @memfree([0 x i8]*, i32, i32) +define void @foo(%B* %pb$, %R* %pr$) nounwind { +L.0: + %pb = alloca %B* + %pr = alloca %R* + store %B* %pb$, %B** %pb + store %R* %pr$, %R** %pr + %pe = alloca %E* + %0 = load %B*, %B** %pb + %1 = bitcast %B* %0 to %E* + store %E* %1, %E** %pe + %2 = load %R*, %R** %pr + %3 = getelementptr %R, %R* %2, i32 0, i32 0 + %4 = load i32, i32* %3 + switch i32 %4, label %L.1 [ + i32 1, label %L.3 + ] +L.3: + %px = alloca %X* + %5 = load %R*, %R** %pr + %6 = bitcast %R* %5 to %X* + store %X* %6, %X** %px + %7 = load %X*, %X** %px + %8 = getelementptr %X, %X* %7, i32 0, i32 0 + %9 = load i32, i32* %8 + %10 = icmp ne i32 %9, 0 + br i1 %10, label %L.5, label %L.4 +L.5: + %pu = alloca %U* + %11 = call [0 x i8]* @memalloc(i32 8, i32 4, i32 0) + %12 = bitcast [0 x i8]* %11 to %U* + store %U* %12, %U** %pu + %13 = load %X*, %X** %px + %14 = getelementptr %X, %X* %13, i32 0, i32 1 + %15 = load i8, i8* %14 + %16 = load %U*, %U** %pu + %17 = getelementptr %U, %U* %16, i32 0, i32 1 + store i8 %15, i8* %17 + %18 = load %E*, %E** %pe + %19 = getelementptr %E, %E* %18, i32 0, i32 1 + %20 = load %U*, %U** %19 + %21 = load %U*, %U** %pu + %22 = getelementptr %U, %U* %21, i32 0, i32 0 + store %U* %20, %U** %22 + %23 = load %U*, %U** %pu + %24 = load %E*, %E** %pe + %25 = getelementptr %E, %E* %24, i32 0, i32 1 + store %U* %23, %U** %25 + br label %L.4 +L.4: + %26 = load %X*, %X** %px + %27 = bitcast %X* %26 to [0 x i8]* + call void @memfree([0 x i8]* %27, i32 8, i32 0) + br label %L.2 +L.1: + br label %L.2 +L.2: + br label %return +return: + ret void +} diff --git a/llvm/test/CodeGen/Thumb2/fp16-stacksplot.mir b/llvm/test/CodeGen/Thumb2/fp16-stacksplot.mir index 856f307488c..997a8aebed5 100644 --- a/llvm/test/CodeGen/Thumb2/fp16-stacksplot.mir +++ b/llvm/test/CodeGen/Thumb2/fp16-stacksplot.mir @@ -27,7 +27,7 @@ body: | ; CHECK: frame-setup CFI_INSTRUCTION offset $r6, -28 ; CHECK: frame-setup CFI_INSTRUCTION offset $r5, -32 ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -36 - ; CHECK: $sp = frame-setup t2SUBri killed $sp, 1208, 14, $noreg, $noreg + ; CHECK: $sp = frame-setup t2SUBspImm killed $sp, 1208, 14, $noreg, $noreg ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 1244 ; CHECK: $r0 = IMPLICIT_DEF ; CHECK: $r1 = IMPLICIT_DEF diff --git a/llvm/test/CodeGen/Thumb2/mve-stacksplot.mir b/llvm/test/CodeGen/Thumb2/mve-stacksplot.mir index ff1229d93ed..2e10c7240e9 100644 --- a/llvm/test/CodeGen/Thumb2/mve-stacksplot.mir +++ b/llvm/test/CodeGen/Thumb2/mve-stacksplot.mir @@ -118,7 +118,7 @@ body: | ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -28 ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -32 ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -36 - ; CHECK-NEXT: $sp = frame-setup t2SUBri12 killed $sp, 1220, 14, $noreg + ; CHECK-NEXT: $sp = frame-setup t2SUBspImm12 killed $sp, 1220, 14, $noreg ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 1256 ; CHECK-NEXT: $r0 = IMPLICIT_DEF ; CHECK-NEXT: $r1 = IMPLICIT_DEF diff --git a/llvm/test/CodeGen/Thumb2/peephole-addsub.mir b/llvm/test/CodeGen/Thumb2/peephole-addsub.mir index f9d7a838c6a..7c769109190 100644 --- a/llvm/test/CodeGen/Thumb2/peephole-addsub.mir +++ b/llvm/test/CodeGen/Thumb2/peephole-addsub.mir @@ -22,7 +22,7 @@ body: | %0:rgpr = COPY $r0 %2:rgpr = t2MOVi 1, 14, $noreg, $noreg %3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg - %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def dead $cpsr + %4:rgpr = t2SUBri %3, 0, 14, $noreg, def dead $cpsr t2CMPri killed %3, 0, 14, $noreg, implicit-def $cpsr %5:rgpr = t2MOVCCi %2, 0, 7, $cpsr $r0 = COPY %5 @@ -30,6 +30,6 @@ body: | # CHECK-LABEL: name: test # CHECK: %3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg -# CHECK-NEXT: %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def $cpsr +# CHECK-NEXT: %4:rgpr = t2SUBri %3, 0, 14, $noreg, def $cpsr # CHECK-NEXT: %5:rgpr = t2MOVCCi %2, 0, 7, $cpsr ... diff --git a/llvm/test/CodeGen/Thumb2/peephole-cmp.mir b/llvm/test/CodeGen/Thumb2/peephole-cmp.mir index 9a03c9cf997..b7c173fd635 100644 --- a/llvm/test/CodeGen/Thumb2/peephole-cmp.mir +++ b/llvm/test/CodeGen/Thumb2/peephole-cmp.mir @@ -23,7 +23,7 @@ body: | liveins: $r0 %0:rgpr = COPY $r0 - %1:gprnopc = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg + %1:rgpr = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg t2CMPrr %1, %0, 14, $noreg, implicit-def $cpsr t2Bcc %bb.2, 3, $cpsr t2B %bb.1, 14, $noreg @@ -37,7 +37,7 @@ body: | tBX_RET 14, $noreg # CHECK-LABEL: name: test_addir_frameindex -# CHECK: %1:gprnopc = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg +# CHECK: %1:rgpr = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg # CHECK-NEXT: t2CMPrr %1, %0, 14, $noreg, implicit-def $cpsr # CHECK-NEXT: t2Bcc %bb.2, 3, $cpsr ... diff --git a/llvm/test/CodeGen/Thumb2/t2peephole-t2ADDrr-to-t2ADDri.ll b/llvm/test/CodeGen/Thumb2/t2peephole-t2ADDrr-to-t2ADDri.ll new file mode 100644 index 00000000000..817eac5665e --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/t2peephole-t2ADDrr-to-t2ADDri.ll @@ -0,0 +1,10 @@ +; RUN: llc -mtriple=thumb-eabi --stop-after=peephole-opt -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s +define i32 @t2_const_var2_1_ok_2(i32 %lhs) { +; CHECK: [[R0:%0|%[1-9][0-9]*]]:gprnopc = COPY $r0 +; CHECK-NEXT: [[R1:%0|%[1-9][0-9]*]]:rgpr = t2ADDri [[R0]], 11206656 +; CHECK-NEXT: [[R2:%0|%[1-9][0-9]*]]:rgpr = t2ADDri killed [[R1]], 187 +; CHECK-NEXT: $r0 = COPY [[R2]] + %ret = add i32 %lhs, 11206843 ; 0x00ab00bb + ret i32 %ret +} + diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s index 59f64afb2dd..f490538011a 100644 --- a/llvm/test/MC/ARM/basic-thumb2-instructions.s +++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s @@ -79,7 +79,6 @@ _func: adds r2, r2, #56 adds r2, #56 add r1, r7, #0xcbcbcbcb - add sp, sp, #0x1fe0000 adds.w r2, #-16 adds.w r2, r2, #-16 @@ -103,7 +102,6 @@ _func: @ CHECK: adds r2, #56 @ encoding: [0x38,0x32] @ CHECK: adds r2, #56 @ encoding: [0x38,0x32] @ CHECK: add.w r1, r7, #3419130827 @ encoding: [0x07,0xf1,0xcb,0x31] -@ CHECK: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d] @ CHECK: subs.w r2, r2, #16 @ encoding: [0xb2,0xf1,0x10,0x02] @ CHECK: subs.w r2, r2, #16 @ encoding: [0xb2,0xf1,0x10,0x02] @@ -182,7 +180,102 @@ _func: @ CHECK: addw r6, sp, #1020 @ encoding: [0x0d,0xf2,0xfc,0x36] add r6, sp, #1019 // T4 @ CHECK: addw r6, sp, #1019 @ encoding: [0x0d,0xf2,0xfb,0x36] - + addw r0, r0, #4095 + addw r0, #4095 + add r0, r0, #4095 + add r0, #4095 +@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70] +@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70] +@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70] +@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70] +add.w r0, r0, #-4096 +add r0, r0, #-4096 +add.w r0, #-4096 +add r0, #-4096 +@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50] +@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50] +@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50] +@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50] +adds.w r0, r0, #-4096 +adds r0, r0, #-4096 +adds.w r0, #-4096 +adds r0, #-4096 +@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50] +@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50] +@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50] +@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50] +@------------------------------------------------------------------------------ +@ ADD (SP plus immediate, writing to SP) +@------------------------------------------------------------------------------ + add.w sp, sp, #0x1fe0000 //T3 + add.w sp, #0x1fe0000 + add sp, sp, #0x1fe0000 + add sp, #0x1fe0000 +@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d] +@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d] +@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d] +@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d] + adds.w sp, sp, #0x1fe0000 //T3 + adds.w sp, #0x1fe0000 + adds sp, sp, #0x1fe0000 + adds sp, #0x1fe0000 +@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d] +@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d] +@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d] +@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d] + addw sp, sp, #4095 //T4 + add sp, sp, #4095 + addw sp, #4095 + add sp, #4095 +@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d] +@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d] +@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d] +@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d] + add sp, sp, #128 //T2 + add sp, #128 +@ CHECK-NEXT: add sp, #128 @ encoding: [0x20,0xb0] +@ CHECK-NEXT: add sp, #128 @ encoding: [0x20,0xb0] + adds sp, sp, #128 //T3 + adds sp, #128 +@ CHECK-NEXT: adds.w sp, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x0d] +@ CHECK-NEXT: adds.w sp, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x0d] + add r0, sp, #128 //T1 +@ CHECK-NEXT: add r0, sp, #128 @ encoding: [0x20,0xa8] + adds r0, sp, #128 //T3 +@ CHECK-NEXT: adds.w r0, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x00] + addw r0, sp, #128 +@ CHECK-NEXT: addw r0, sp, #128 @ encoding: [0x0d,0xf2,0x80,0x00] +@------------------------------------------------------------------------------ +@ ADD (SP plus negative immediate, writing to SP) +@------------------------------------------------------------------------------ +add sp, sp, #-508 +add sp, #-508 +@ CHECK-NEXT: sub sp, #508 @ encoding: [0xff,0xb0] +@ CHECK-NEXT: sub sp, #508 @ encoding: [0xff,0xb0] +addw sp, sp, #-4095 +add sp, sp, #-4095 +addw sp, #-4095 +add sp, #-4095 +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +add.w sp, sp, #-4096 +add sp, sp, #-4096 +add.w sp, #-4096 +add sp, #-4096 +@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d] +@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d] +@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d] +@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d] +adds.w sp, sp, #-4096 +adds sp, sp, #-4096 +adds.w sp, #-4096 +adds sp, #-4096 +@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d] +@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d] +@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d] +@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d] @------------------------------------------------------------------------------ @ ADD (SP plus register) A8.8.10 @------------------------------------------------------------------------------ @@ -206,8 +299,22 @@ _func: @ CHECK: it eq @ encoding: [0x08,0xbf] addeq r2, sp, ip // T3 @ CHECK: addeq.w r2, sp, r12 @ encoding: [0x0d,0xeb,0x0c,0x02] - - + add.w r0, sp, r0, ror #2 + add r0, sp, r0, ror #2 + add sp, r1, lsl #15 + adds.w r0, sp, r0, ror #2 + adds r0, sp, r0, ror #2 + adds.w sp, sp, r0, ror #31 + adds sp, sp, r0, ror #31 + adds sp, r0, ror #31 +@ CHECK-NEXT: add.w r0, sp, r0, ror #2 @ encoding: [0x0d,0xeb,0xb0,0x00] +@ CHECK-NEXT: add.w r0, sp, r0, ror #2 @ encoding: [0x0d,0xeb,0xb0,0x00] +@ CHECK-NEXT: add.w sp, sp, r1, lsl #15 @ encoding: [0x0d,0xeb,0xc1,0x3d] +@ CHECK-NEXT: adds.w r0, sp, r0, ror #2 @ encoding: [0x1d,0xeb,0xb0,0x00] +@ CHECK-NEXT: adds.w r0, sp, r0, ror #2 @ encoding: [0x1d,0xeb,0xb0,0x00] +@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d] +@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d] +@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d] @------------------------------------------------------------------------------ @ FIXME: ADR @------------------------------------------------------------------------------ @@ -3083,7 +3190,10 @@ _func: sub r0, r0, #32 subs r2, r2, #56 subs r2, #56 - + subw r0, r0, #4095 + subw r0, #4095 + sub r0, r0, #4095 + sub r0, #4095 @ CHECK: itet eq @ encoding: [0x0a,0xbf] @ CHECK: subeq r1, r2, #4 @ encoding: [0x11,0x1f] @ CHECK: subwne r5, r3, #1023 @ encoding: [0xa3,0xf2,0xff,0x35] @@ -3099,8 +3209,47 @@ _func: @ CHECK: sub.w r0, r0, #32 @ encoding: [0xa0,0xf1,0x20,0x00] @ CHECK: subs r2, #56 @ encoding: [0x38,0x3a] @ CHECK: subs r2, #56 @ encoding: [0x38,0x3a] - - +@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70] +@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70] +@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70] +@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70] +@------------------------------------------------------------------------------ +@ SUB (immediate, writting to SP) +@------------------------------------------------------------------------------ + sub.w sp, sp, #0x1fe0000 //T2 + sub sp, sp, #0x1fe0000 + sub.w sp, #0x1fe0000 + sub sp, #0x1fe0000 +@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d] +@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d] +@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d] +@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d] + subs.w sp, sp, #0x1fe0000 //T2 + subs sp, sp, #0x1fe0000 + subs.w sp, #0x1fe0000 + subs sp, #0x1fe0000 +@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d] +@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d] +@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d] +@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d] + subw sp, sp, #4095 //T3 + sub sp, sp, #4095 + subw sp, #4095 + sub sp, #4095 +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] +@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d] + sub sp, #128 //T1 +@ CHECK-NEXT: sub sp, #128 @ encoding: [0xa0,0xb0] + subs.w sp, #128 //T2 + subs sp, #128 //T2 +@ CHECK-NEXT: subs.w sp, sp, #128 @ encoding: [0xbd,0xf1,0x80,0x0d] +@ CHECK-NEXT: subs.w sp, sp, #128 @ encoding: [0xbd,0xf1,0x80,0x0d] + sub.w sp, #128 //T2 +@ CHECK-NEXT: sub.w sp, sp, #128 @ encoding: [0xad,0xf1,0x80,0x0d] + subw sp, #128 //T4 +@ CHECK-NEXT: subw sp, sp, #128 @ encoding: [0xad,0xf2,0x80,0x0d] @------------------------------------------------------------------------------ @ SUB (register) @------------------------------------------------------------------------------ diff --git a/llvm/test/MC/ARM/invalid-addsub.s b/llvm/test/MC/ARM/invalid-addsub.s index 07c1a800425..51a618a5a71 100644 --- a/llvm/test/MC/ARM/invalid-addsub.s +++ b/llvm/test/MC/ARM/invalid-addsub.s @@ -1,20 +1,68 @@ -@ RUN: not llvm-mc -triple thumbv7-apple-ios %s -o - 2>&1 | FileCheck %s - -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp +@ RUN: not llvm-mc -triple thumbv7-apple-ios %s -o /dev/null 2>&1 | FileCheck %s add sp, r5, #1 addw sp, r7, #4 add sp, r3, r2 add sp, r3, r5, lsl #3 - - -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp -@ CHECK: error: source register must be sp if destination is sp sub sp, r5, #1 subw sp, r7, #4 sub sp, r3, r2 sub sp, r3, r5, lsl #3 +@CHECK: error: invalid instruction, any one of the following would fix this: +@CHECK-NEXT: add sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: invalid operand for instruction +@CHECK-NEXT: add sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: add sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: add sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register sp +@CHECK-NEXT: add sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: invalid instruction, any one of the following would fix this: +@CHECK-NEXT: addw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: addw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register sp +@CHECK-NEXT: addw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: source register must be sp if destination is sp +@CHECK-NEXT: add sp, r3, r2 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: source register must be sp if destination is sp +@CHECK-NEXT: add sp, r3, r5, lsl #3 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: invalid instruction, any one of the following would fix this: +@CHECK-NEXT: sub sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: invalid operand for instruction +@CHECK-NEXT: sub sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: sub sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: sub sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register sp +@CHECK-NEXT: sub sp, r5, #1 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: invalid instruction, any one of the following would fix this: +@CHECK-NEXT: subw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14 +@CHECK-NEXT: subw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: note: operand must be a register sp +@CHECK-NEXT: subw sp, r7, #4 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: source register must be sp if destination is sp +@CHECK-NEXT: sub sp, r3, r2 +@CHECK-NEXT: ^ +@CHECK-NEXT: error: source register must be sp if destination is sp +@CHECK-NEXT: sub sp, r3, r5, lsl #3 diff --git a/llvm/test/MC/ARM/negative-immediates.s b/llvm/test/MC/ARM/negative-immediates.s index 38a6f64452b..d6a2a8fb939 100644 --- a/llvm/test/MC/ARM/negative-immediates.s +++ b/llvm/test/MC/ARM/negative-immediates.s @@ -51,7 +51,7 @@ .thumb ADD r0, r1, #0xFFFFFF00 -# CHECK: subw r0, r1, #256 +# CHECK: sub.w r0, r1, #256 # CHECK-DISABLED: note: instruction requires: NegativeImmediates # CHECK-DISABLED: ADD ADDS r0, r1, #0xFFFFFF00 @@ -175,7 +175,7 @@ # CHECK-DISABLED: note: instruction requires: NegativeImmediates # CHECK-DISABLED: SUB.W SUB r0, r1, #0xFFFFFF00 -# CHECK: addw r0, r1, #256 +# CHECK: add.w r0, r1, #256 # CHECK-DISABLED: note: instruction requires: NegativeImmediates # CHECK-DISABLED: SUB SUBS r0, r1, #0xFFFFFF00 @@ -188,6 +188,6 @@ # CHECK-DISABLED: SUBS.W ADD r0, r1, #-13 -# CHECK: subw r0, r1, #13 +# CHECK: sub.w r0, r1, #13 # CHECK-DISABLED: note: instruction requires: NegativeImmediates # CHECK-DISABLED: ADD diff --git a/llvm/test/MC/ARM/register-token-source-loc.s b/llvm/test/MC/ARM/register-token-source-loc.s index bfd6097adf0..afb6ba0c61a 100644 --- a/llvm/test/MC/ARM/register-token-source-loc.s +++ b/llvm/test/MC/ARM/register-token-source-loc.s @@ -1,12 +1,11 @@ // RUN: not llvm-mc -triple armv6m--none-eabi < %s 2>&1 | FileCheck %s - -// Some of these CHECK lines need to uses regexes to that the amount of -// whitespace between the start of the line and the caret is significant. - add sp, r0, #4 -// CHECK: error: invalid instruction, any one of the following would fix this: -// CHECK: note: instruction requires: thumb2 -// CHECK: note: operand must be a register sp -// CHECK-NEXT: {{^ add sp, r0, #4}} -// CHECK-NEXT: {{^ \^}} -// CHECK: note: too many operands for instruction +// CHECK: error: invalid instruction, any one of the following would fix this: +// CHECK-NEXT: add sp, r0, #4 +// CHECK-NEXT: ^ +// CHECK-NEXT: note: operand must be a register sp +// CHECK-NEXT: add sp, r0, #4 +// CHECK-NEXT: ^ +// CHECK-NEXT: note: too many operands for instruction +// CHECK-NEXT: add sp, r0, #4 +// CHECK-NEXT: ^ diff --git a/llvm/test/MC/ARM/thumb-diagnostics.s b/llvm/test/MC/ARM/thumb-diagnostics.s index 304e9966da1..7179bd89e07 100644 --- a/llvm/test/MC/ARM/thumb-diagnostics.s +++ b/llvm/test/MC/ARM/thumb-diagnostics.s @@ -244,24 +244,44 @@ add sp, sp, #512 add r2, sp, #1024 @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this: -@ CHECK-ERRORS: add sp, #-1 -@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: add sp, #-1 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: operand must be a register in range [r0, r15] +@ CHECK-ERRORS: add sp, #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: note: invalid operand for instruction +@ CHECK-ERRORS: add sp, #-1 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: instruction requires: thumb2 +@ CHECK-ERRORS: add sp, #-1 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this: -@ CHECK-ERRORS: add sp, #3 -@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: add sp, #3 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: operand must be a register in range [r0, r15] +@ CHECK-ERRORS: add sp, #3 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: note: invalid operand for instruction +@ CHECK-ERRORS: add sp, #3 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: instruction requires: thumb2 +@ CHECK-ERRORS: add sp, #3 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this: -@ CHECK-ERRORS: add sp, sp, #512 -@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: add sp, sp, #512 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: operand must be a register in range [r0, r15] +@ CHECK-ERRORS: add sp, sp, #512 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: note: invalid operand for instruction +@ CHECK-ERRORS: add sp, sp, #512 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: note: instruction requires: thumb2 +@ CHECK-ERRORS: add sp, sp, #512 +@ CHECK-ERRORS: ^ @ CHECK-ERRORS: error: instruction requires: thumb2 -@ CHECK-ERRORS: add r2, sp, #1024 -@ CHECK-ERRORS: ^ - +@ CHECK-ERRORS: add r2, sp, #1024 +@ CHECK-ERRORS: ^ add r2, sp, ip @ CHECK-ERRORS: error: source register must be the same as destination @ CHECK-ERRORS: add r2, sp, ip diff --git a/llvm/test/MC/Disassembler/ARM/invalid-thumbv7.txt b/llvm/test/MC/Disassembler/ARM/invalid-thumbv7.txt index 48b5b8be7cd..5bbb7127155 100644 --- a/llvm/test/MC/Disassembler/ARM/invalid-thumbv7.txt +++ b/llvm/test/MC/Disassembler/ARM/invalid-thumbv7.txt @@ -425,3 +425,8 @@ # CHECK-V7-NEXT: [0xa3,0xeb,0x02,0x0d] # CHECK-V7: warning: potentially undefined instruction encoding # CHECK-V7-NEXT: [0xa3,0xeb,0xc5,0x0d] +# CHECK-V7-NEXT: ^ +[0x0f,0xf2,0x00,0x4d] +# CHECK-V7-NEXT: warning: potentially undefined instruction encoding +# CHECK-V7-NEXT: [0x0f,0xf2,0x00,0x4d] +# CHECK-V7-NEXT: ^ diff --git a/llvm/test/MC/Disassembler/ARM/thumb-tests.txt b/llvm/test/MC/Disassembler/ARM/thumb-tests.txt index dcb6e3f6721..09ffe5368f4 100644 --- a/llvm/test/MC/Disassembler/ARM/thumb-tests.txt +++ b/llvm/test/MC/Disassembler/ARM/thumb-tests.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu=cortex-a9 | FileCheck %s +# RUN: llvm-mc --disassemble --show-encoding %s -triple=thumbv7-apple-darwin9 -mcpu=cortex-a9 | FileCheck %s # CHECK: add r5, sp, #68 0x11 0xad @@ -84,9 +84,12 @@ # CHECK: sub sp, #60 0x8f 0xb0 -# CHECK: subw r0, pc, #1 +# CHECK: adr.w r0, #-1 0xaf 0xf2 0x01 0x00 +# CHECK: subw r0, pc, #0 +0xaf 0xf2 0x00 0x00 + # CHECK: subw r0, sp, #835 0xad 0xf2 0x43 0x30 @@ -155,7 +158,7 @@ # CHECK: ldm r5!, {r0, r1, r2, r3, r4} 0x1f 0xcd -# CHECK: addw r0, pc, #1050 +# CHECK: adr.w r0, #1050 0x0f 0xf2 0x1a 0x40 # CHECK: ldrd r3, r8, [r11, #-60] diff --git a/llvm/test/MC/Disassembler/ARM/thumb2-v8.txt b/llvm/test/MC/Disassembler/ARM/thumb2-v8.txt index 1b2f09562e2..9a4d0d946d1 100644 --- a/llvm/test/MC/Disassembler/ARM/thumb2-v8.txt +++ b/llvm/test/MC/Disassembler/ARM/thumb2-v8.txt @@ -38,3 +38,5 @@ 0x90 0xec 0x00 0x0e # CHECK: ldc p14 +[0x0f,0xf2,0x00,0x4d] +# CHECK: adr.w sp, #1024 diff --git a/llvm/test/MC/Disassembler/ARM/thumb2.txt b/llvm/test/MC/Disassembler/ARM/thumb2.txt index 986dbd52c2e..b4eca877490 100644 --- a/llvm/test/MC/Disassembler/ARM/thumb2.txt +++ b/llvm/test/MC/Disassembler/ARM/thumb2.txt @@ -90,14 +90,14 @@ #------------------------------------------------------------------------------ # ADR #------------------------------------------------------------------------------ -# CHECK: subw r11, pc, #3270 -# CHECK: subw r11, pc, #826 -# CHECK: subw r1, pc, #0 - +# CHECK: adr.w r11, #-3270 +# CHECK-NEXT: adr.w r11, #-826 +# CHECK-NEXT: subw r1, pc, #0 +# CHECK-NEXT: adr.w r0, #1024 0xaf 0xf6 0xc6 0x4b 0xaf 0xf2 0x3a 0x3b 0xaf 0xf2 0x00 0x01 - +0x0f,0xf2,0x00,0x40 #------------------------------------------------------------------------------ # AND (immediate) #------------------------------------------------------------------------------ diff --git a/llvm/test/tools/llvm-mca/ARM/simple-cortex-m33.s b/llvm/test/tools/llvm-mca/ARM/simple-cortex-m33.s new file mode 100644 index 00000000000..fa3bbc061b8 --- /dev/null +++ b/llvm/test/tools/llvm-mca/ARM/simple-cortex-m33.s @@ -0,0 +1,26 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -mtriple=thumbv7 --mcpu=cortex-m33 -instruction-tables -o - %s | FileCheck %s + +sub sp, #4 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 1 1.00 U sub sp, #4 + +# CHECK: Resources: +# CHECK-NEXT: [0] - M4Unit + +# CHECK: Resource pressure per iteration: +# CHECK-NEXT: [0] +# CHECK-NEXT: 1.00 + +# CHECK: Resource pressure by instruction: +# CHECK-NEXT: [0] Instructions: +# CHECK-NEXT: 1.00 sub sp, #4 |

