brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · 666f1cb Raw
249 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; FIXME: Add tests for global-isel/fast-isel.3 4; RUN: llc < %s -mtriple=arm64-windows | FileCheck %s5 6; Returns <= 8 bytes should be in X0.7%struct.S1 = type { i32, i32 }8define dso_local i64 @"?f1"() {9entry:10; CHECK-LABEL: f111; CHECK-DAG: str xzr, [sp, #8]12; CHECK-DAG: mov x0, xzr13 14  %retval = alloca %struct.S1, align 415  store i32 0, ptr %retval, align 416  %b = getelementptr inbounds %struct.S1, ptr %retval, i32 0, i32 117  store i32 0, ptr %b, align 418  %0 = load i64, ptr %retval, align 419  ret i64 %020}21 22; Returns <= 16 bytes should be in X0/X1.23%struct.S2 = type { i32, i32, i32, i32 }24define dso_local [2 x i64] @"?f2"() {25entry:26; FIXME: Missed optimization, the entire SP push/pop could be removed27; CHECK-LABEL: f228; CHECK:         sub     sp, sp, #1629; CHECK-NEXT:    .seh_stackalloc 1630; CHECK-NEXT:    .seh_endprologue31; CHECK-DAG:     stp     xzr, xzr, [sp]32; CHECK-DAG:     mov     x0, xzr33; CHECK-DAG:     mov     x1, xzr34; CHECK:         .seh_startepilogue35; CHECK-NEXT:    add     sp, sp, #1636 37  %retval = alloca %struct.S2, align 438  store i32 0, ptr %retval, align 439  %b = getelementptr inbounds %struct.S2, ptr %retval, i32 0, i32 140  store i32 0, ptr %b, align 441  %c = getelementptr inbounds %struct.S2, ptr %retval, i32 0, i32 242  store i32 0, ptr %c, align 443  %d = getelementptr inbounds %struct.S2, ptr %retval, i32 0, i32 344  store i32 0, ptr %d, align 445  %0 = load [2 x i64], ptr %retval, align 446  ret [2 x i64] %047}48 49; Arguments > 16 bytes should be passed in X8.50%struct.S3 = type { i32, i32, i32, i32, i32 }51define dso_local void @"?f3"(ptr noalias sret(%struct.S3) %agg.result) {52entry:53; CHECK-LABEL: f354; CHECK: stp xzr, xzr, [x8]55; CHECK: str wzr, [x8, #16]56 57  store i32 0, ptr %agg.result, align 458  %b = getelementptr inbounds %struct.S3, ptr %agg.result, i32 0, i32 159  store i32 0, ptr %b, align 460  %c = getelementptr inbounds %struct.S3, ptr %agg.result, i32 0, i32 261  store i32 0, ptr %c, align 462  %d = getelementptr inbounds %struct.S3, ptr %agg.result, i32 0, i32 363  store i32 0, ptr %d, align 464  %e = getelementptr inbounds %struct.S3, ptr %agg.result, i32 0, i32 465  store i32 0, ptr %e, align 466  ret void67}68 69; InReg arguments to non-instance methods must be passed in X0 and returns in70; X0.71%class.B = type { i32 }72define dso_local void @"?f4"(ptr inreg noalias nocapture sret(%class.B) %agg.result) {73entry:74; CHECK-LABEL: f475; CHECK: mov w8, #176; CHECK: str w8, [x0]77  store i32 1, ptr %agg.result, align 478  ret void79}80 81; InReg arguments to instance methods must be passed in X1 and returns in X0.82%class.C = type { i8 }83%class.A = type { i8 }84 85define dso_local void @"?inst@C"(ptr %this, ptr inreg noalias sret(%class.A) %agg.result) {86entry:87; CHECK-LABEL: inst@C88; CHECK-DAG: mov x0, x189; CHECK-DAG: str x8, [sp, #8]90 91  %this.addr = alloca ptr, align 892  store ptr %this, ptr %this.addr, align 893  %this1 = load ptr, ptr %this.addr, align 894  ret void95}96 97; The following tests correspond to tests in98; clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp99 100; Pod is a trivial HFA101%struct.Pod = type { [2 x double] }102; Not an aggregate according to C++14 spec => not HFA according to MSVC103%struct.NotCXX14Aggregate  = type { %struct.Pod }104; NotPod is a C++14 aggregate. But not HFA, because it contains105; NotCXX14Aggregate (which itself is not HFA because it's not a C++14106; aggregate).107%struct.NotPod = type { %struct.NotCXX14Aggregate }108 109define dso_local %struct.Pod @copy_pod(ptr %x) {110; CHECK-LABEL: copy_pod:111; CHECK:       // %bb.0:112; CHECK-NEXT:    ldp d0, d1, [x0]113; CHECK-NEXT:    ret114  %x1 = load %struct.Pod, ptr %x, align 8115  ret %struct.Pod %x1116}117 118declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)119 120define dso_local void @copy_notcxx14aggregate(ptr inreg noalias sret(%struct.NotCXX14Aggregate) align 8 %agg.result, ptr %x) {121; CHECK-LABEL: copy_notcxx14aggregate:122; CHECK:       // %bb.0:123; CHECK-NEXT:    ldr q0, [x1]124; CHECK-NEXT:    str q0, [x0]125; CHECK-NEXT:    ret126  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.result, ptr align 8 %x, i64 16, i1 false)127  ret void128}129 130define dso_local [2 x i64] @copy_notpod(ptr %x) {131; CHECK-LABEL: copy_notpod:132; CHECK:       // %bb.0:133; CHECK-NEXT:    ldp x8, x1, [x0]134; CHECK-NEXT:    mov x0, x8135; CHECK-NEXT:    ret136  %x2 = load [2 x i64], ptr %x137  ret [2 x i64] %x2138}139 140@Pod = external global %struct.Pod141 142define void @call_copy_pod() {143; CHECK-LABEL: call_copy_pod:144; CHECK:       .seh_proc call_copy_pod145; CHECK-NEXT:  // %bb.0:146; CHECK-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill147; CHECK-NEXT:    .seh_save_reg_x x19, 16148; CHECK-NEXT:    str x30, [sp, #8] // 8-byte Spill149; CHECK-NEXT:    .seh_save_reg x30, 8150; CHECK-NEXT:    .seh_endprologue151; CHECK-NEXT:    adrp x19, Pod152; CHECK-NEXT:    add x19, x19, :lo12:Pod153; CHECK-NEXT:    mov x0, x19154; CHECK-NEXT:    bl copy_pod155; CHECK-NEXT:    stp d0, d1, [x19]156; CHECK-NEXT:    .seh_startepilogue157; CHECK-NEXT:    ldr x30, [sp, #8] // 8-byte Reload158; CHECK-NEXT:    .seh_save_reg x30, 8159; CHECK-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload160; CHECK-NEXT:    .seh_save_reg_x x19, 16161; CHECK-NEXT:    .seh_endepilogue162; CHECK-NEXT:    ret163; CHECK-NEXT:    .seh_endfunclet164; CHECK-NEXT:    .seh_endproc165  %x = call %struct.Pod @copy_pod(ptr @Pod)166  store %struct.Pod %x, ptr @Pod167  ret void168}169 170@NotCXX14Aggregate = external global %struct.NotCXX14Aggregate171 172define void @call_copy_notcxx14aggregate() {173; CHECK-LABEL: call_copy_notcxx14aggregate:174; CHECK:       .seh_proc call_copy_notcxx14aggregate175; CHECK-NEXT:  // %bb.0:176; CHECK-NEXT:    sub sp, sp, #32177; CHECK-NEXT:    .seh_stackalloc 32178; CHECK-NEXT:    str x19, [sp, #16] // 8-byte Spill179; CHECK-NEXT:    .seh_save_reg x19, 16180; CHECK-NEXT:    str x30, [sp, #24] // 8-byte Spill181; CHECK-NEXT:    .seh_save_reg x30, 24182; CHECK-NEXT:    .seh_endprologue183; CHECK-NEXT:    adrp x19, NotCXX14Aggregate184; CHECK-NEXT:    add x19, x19, :lo12:NotCXX14Aggregate185; CHECK-NEXT:    mov x0, sp186; CHECK-NEXT:    mov x1, x19187; CHECK-NEXT:    bl copy_notcxx14aggregate188; CHECK-NEXT:    ldp d0, d1, [sp]189; CHECK-NEXT:    stp d0, d1, [x19]190; CHECK-NEXT:    .seh_startepilogue191; CHECK-NEXT:    ldr x30, [sp, #24] // 8-byte Reload192; CHECK-NEXT:    .seh_save_reg x30, 24193; CHECK-NEXT:    ldr x19, [sp, #16] // 8-byte Reload194; CHECK-NEXT:    .seh_save_reg x19, 16195; CHECK-NEXT:    add sp, sp, #32196; CHECK-NEXT:    .seh_stackalloc 32197; CHECK-NEXT:    .seh_endepilogue198; CHECK-NEXT:    ret199; CHECK-NEXT:    .seh_endfunclet200; CHECK-NEXT:    .seh_endproc201  %x = alloca %struct.NotCXX14Aggregate202  call void @copy_notcxx14aggregate(ptr %x, ptr @NotCXX14Aggregate)203  %x1 = load %struct.NotCXX14Aggregate, ptr %x204  store %struct.NotCXX14Aggregate %x1, ptr @NotCXX14Aggregate205  ret void206}207 208@NotPod = external global %struct.NotPod209 210define void @call_copy_notpod() {211; CHECK-LABEL: call_copy_notpod:212; CHECK:       .seh_proc call_copy_notpod213; CHECK-NEXT:  // %bb.0:214; CHECK-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill215; CHECK-NEXT:    .seh_save_reg_x x19, 16216; CHECK-NEXT:    str x30, [sp, #8] // 8-byte Spill217; CHECK-NEXT:    .seh_save_reg x30, 8218; CHECK-NEXT:    .seh_endprologue219; CHECK-NEXT:    adrp x19, NotPod220; CHECK-NEXT:    add x19, x19, :lo12:NotPod221; CHECK-NEXT:    mov x0, x19222; CHECK-NEXT:    bl copy_notpod223; CHECK-NEXT:    stp x0, x1, [x19]224; CHECK-NEXT:    .seh_startepilogue225; CHECK-NEXT:    ldr x30, [sp, #8] // 8-byte Reload226; CHECK-NEXT:    .seh_save_reg x30, 8227; CHECK-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload228; CHECK-NEXT:    .seh_save_reg_x x19, 16229; CHECK-NEXT:    .seh_endepilogue230; CHECK-NEXT:    ret231; CHECK-NEXT:    .seh_endfunclet232; CHECK-NEXT:    .seh_endproc233  %x = call [2 x i64] @copy_notpod(ptr @NotPod)234  store [2 x i64] %x, ptr @NotPod235  ret void236}237 238; We shouldn't return the argument239; when it has only inreg attribute240define i64 @foobar(ptr inreg %0) {241; CHECK-LABEL: foobar:242; CHECK:       // %bb.0: // %entry243; CHECK-NEXT:    ldr x0, [x0]244; CHECK-NEXT:    ret245entry:246  %1 = load i64, ptr %0247  ret i64 %1248}249