brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · c4ee318 Raw
142 lines · plain
1; RUN: llc -mtriple=thumbv8m.base-eabi -mattr=+execute-only %s -o - | FileCheck --check-prefixes=CHECK,CHECK-MOVW %s2; RUN: llc -mtriple=thumbv6m-eabi -mattr=+execute-only %s -o - | FileCheck --check-prefixes=CHECK,CHECK-NOMOVW %s3 4; Largest offset that fits into sp-relative ldr5; CHECK-LABEL: ldr_range_end:6; CHECK: ldr {{r[0-9]+}}, [sp, #1020]7define i32 @ldr_range_end() {8entry:9  %var = alloca i32, align 410  %arr = alloca [1020 x i8], align 411  %0 = load i32, ptr %var, align 412  ret i32 %013}14 15; Smallest offset that fits into add+ldr16; CHECK-LABEL: add_ldr_range_start:17; CHECK:      add [[REG:r[0-9]+]], sp, #90018; CHECK-NEXT: ldr {{r[0-9]+}}, [[[REG]], #124]19define i32 @add_ldr_range_start() {20entry:21  %var = alloca i32, align 422  %arr = alloca [1024 x i8], align 423  %0 = load i32, ptr %var, align 424  ret i32 %025}26 27; Largest offset that fits into add+ldr28; CHECK-LABEL: add_ldr_range_end:29; CHECK:      add [[REG:r[0-9]+]], sp, #102030; CHECK-NEXT: ldr {{r[0-9]+}}, [[[REG]], #124]31define i32 @add_ldr_range_end() {32entry:33  %var = alloca i32, align 434  %arr = alloca [1144 x i8], align 435  %0 = load i32, ptr %var, align 436  ret i32 %037}38 39; Smallest offset where we start using mov32. If we don't have movw then using40; an ldr offset means we save an add.41; CHECK-LABEL: mov32_range_start:42; CHECK-MOVW:        movw [[REG:r[0-9]+]], #114843; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #444; CHECK-NOMOVW-NEXT: lsls [[REG]], [[REG]], #845; CHECK-NEXT:        add [[REG]], sp46; CHECK-MOVW-NEXT:   ldr {{r[0-9]+}}, [[[REG]]]47; CHECK-NOMOVW-NEXT: ldr {{r[0-9]+}}, [[[REG]], #124]48define i32 @mov32_range_start() {49entry:50  %var = alloca i32, align 451  %arr = alloca [1148 x i8], align 452  %0 = load i32, ptr %var, align 453  ret i32 %054}55 56; Here using an ldr offset doesn't save an add so we shouldn't do it.57; CHECK-LABEL: mov32_range_next:58; CHECK-MOVW:        movw [[REG:r[0-9]+]], #115259; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #460; CHECK-NOMOVW-NEXT: lsls [[REG]], [[REG]], #861; CHECK-NOMOVW-NEXT: adds [[REG]], #12862; CHECK-NEXT:        add [[REG]], sp63; CHECK-NEXT:        ldr {{r[0-9]+}}, [[[REG]]]64define i32 @mov32_range_next() {65entry:66  %var = alloca i32, align 467  %arr = alloca [1152 x i8], align 468  %0 = load i32, ptr %var, align 469  ret i32 %070}71 72; Smallest offset where using an ldr offset prevents needing a movt or lsl+add73; CHECK-LABEL: can_clear_top_byte_start:74; CHECK:             add sp, {{r[0-9]+}}75; CHECK-MOVW:        movw [[REG:r[0-9]+]], #6541276; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #25577; CHECK-NOMOVW-NEXT: lsls [[REG:r[0-9]+]], [[REG:r[0-9]+]], #878; CHECK-NOMOVW-NEXT: adds [[REG:r[0-9]+]], #13279; CHECK-NEXT:        add [[REG]], sp80; CHECK-NEXT:        ldr {{r[0-9]+}}, [[[REG]], #124]81define i32 @can_clear_top_byte_start() {82entry:83  %var = alloca i32, align 484  %arr = alloca [65536 x i8], align 485  %0 = load i32, ptr %var, align 486  ret i32 %087}88 89; Largest offset where using an ldr offset prevents needing a movt or lsl+add90; CHECK-LABEL: can_clear_top_byte_end:91; CHECK:             add sp, {{r[0-9]+}}92; CHECK-MOVW:        movw [[REG:r[0-9]+]], #6553293; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #25594; CHECK-NOMOVW-NEXT: lsls [[REG:r[0-9]+]], [[REG:r[0-9]+]], #895; CHECK-NOMOVW-NEXT: adds [[REG:r[0-9]+]], #25296; CHECK-NEXT:        add [[REG]], sp97; CHECK-NEXT:        ldr {{r[0-9]+}}, [[[REG]], #124]98define i32 @can_clear_top_byte_end() {99entry:100  %var = alloca i32, align 4101  %arr = alloca [65656 x i8], align 4102  %0 = load i32, ptr %var, align 4103  ret i32 %0104}105 106; Smallest offset where using an ldr offset doesn't clear the top byte, though107; we can use an ldr offset if not using movt to save an add of the low byte.108; CHECK-LABEL: cant_clear_top_byte_start:109; CHECK:             add sp, {{r[0-9]+}}110; CHECK-MOVW:        movw [[REG:r[0-9]+]], #124111; CHECK-MOVW-NEXT:   movt [[REG:r[0-9]+]], #1112; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #1113; CHECK-NOMOVW-NEXT: lsls [[REG:r[0-9]+]], [[REG:r[0-9]+]], #16114; CHECK-NEXT:        add [[REG]], sp115; CHECK-MOVW-NEXT:   ldr {{r[0-9]+}}, [[[REG]]]116; CHECK-NOMOVW-NEXT: ldr {{r[0-9]+}}, [[[REG]], #124]117define i32 @cant_clear_top_byte_start() {118entry:119  %var = alloca i32, align 4120  %arr = alloca [65660 x i8], align 4121  %0 = load i32, ptr %var, align 4122  ret i32 %0123}124 125; An ldr offset doesn't help for anything, so we shouldn't do it.126; CHECK-LABEL: cant_clear_top_byte_next:127; CHECK:             add sp, {{r[0-9]+}}128; CHECK-MOVW:        movw [[REG:r[0-9]+]], #128129; CHECK-MOVW:        movt [[REG:r[0-9]+]], #1130; CHECK-NOMOVW:      movs [[REG:r[0-9]+]], #1131; CHECK-NOMOVW-NEXT: lsls [[REG:r[0-9]+]], [[REG:r[0-9]+]], #16132; CHECK-NOMOVW-NEXT: adds [[REG:r[0-9]+]], #128133; CHECK-NEXT:        add [[REG]], sp134; CHECK-NEXT:        ldr {{r[0-9]+}}, [[[REG]]]135define i32 @cant_clear_top_byte_next() {136entry:137  %var = alloca i32, align 4138  %arr = alloca [65664 x i8], align 4139  %0 = load i32, ptr %var, align 4140  ret i32 %0141}142