114 lines · plain
1; RUN: llc < %s -mtriple=aarch64 -aarch64-neon-syntax=apple -aarch64-enable-stp-suppress=false -verify-machineinstrs -asm-verbose=false | FileCheck %s2 3; CHECK-LABEL: test_strd_sturd:4; CHECK-NEXT: stp d0, d1, [x0, #-8]5; CHECK-NEXT: ret6define void @test_strd_sturd(ptr %ptr, <2 x float> %v1, <2 x float> %v2) #0 {7 store <2 x float> %v2, ptr %ptr, align 168 %add.ptr = getelementptr inbounds float, ptr %ptr, i64 -29 store <2 x float> %v1, ptr %add.ptr, align 1610 ret void11}12 13; CHECK-LABEL: test_sturd_strd:14; CHECK-NEXT: stp d0, d1, [x0, #-8]15; CHECK-NEXT: ret16define void @test_sturd_strd(ptr %ptr, <2 x float> %v1, <2 x float> %v2) #0 {17 %add.ptr = getelementptr inbounds float, ptr %ptr, i64 -218 store <2 x float> %v1, ptr %add.ptr, align 1619 store <2 x float> %v2, ptr %ptr, align 1620 ret void21}22 23; CHECK-LABEL: test_strq_sturq:24; CHECK-NEXT: stp q0, q1, [x0, #-16]25; CHECK-NEXT: ret26define void @test_strq_sturq(ptr %ptr, <2 x double> %v1, <2 x double> %v2) #0 {27 store <2 x double> %v2, ptr %ptr, align 1628 %add.ptr = getelementptr inbounds double, ptr %ptr, i64 -229 store <2 x double> %v1, ptr %add.ptr, align 1630 ret void31}32 33; CHECK-LABEL: test_sturq_strq:34; CHECK-NEXT: stp q0, q1, [x0, #-16]35; CHECK-NEXT: ret36define void @test_sturq_strq(ptr %ptr, <2 x double> %v1, <2 x double> %v2) #0 {37 %add.ptr = getelementptr inbounds double, ptr %ptr, i64 -238 store <2 x double> %v1, ptr %add.ptr, align 1639 store <2 x double> %v2, ptr %ptr, align 1640 ret void41}42 43; CHECK-LABEL: test_ldrx_ldurx:44; CHECK-NEXT: ldp [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-8]45; CHECK-NEXT: add x0, [[V0]], [[V1]]46; CHECK-NEXT: ret47define i64 @test_ldrx_ldurx(ptr %p) #0 {48 %tmp = load i64, ptr %p, align 449 %add.ptr = getelementptr inbounds i64, ptr %p, i64 -150 %tmp1 = load i64, ptr %add.ptr, align 451 %add = add nsw i64 %tmp1, %tmp52 ret i64 %add53}54 55; CHECK-LABEL: test_ldurx_ldrx:56; CHECK-NEXT: ldp [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-8]57; CHECK-NEXT: add x0, [[V0]], [[V1]]58; CHECK-NEXT: ret59define i64 @test_ldurx_ldrx(ptr %p) #0 {60 %add.ptr = getelementptr inbounds i64, ptr %p, i64 -161 %tmp1 = load i64, ptr %add.ptr, align 462 %tmp = load i64, ptr %p, align 463 %add = add nsw i64 %tmp1, %tmp64 ret i64 %add65}66 67; CHECK-LABEL: test_ldrsw_ldursw:68; CHECK-NEXT: ldpsw [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-4]69; CHECK-NEXT: add x0, [[V0]], [[V1]]70; CHECK-NEXT: ret71define i64 @test_ldrsw_ldursw(ptr %p) #0 {72 %tmp = load i32, ptr %p, align 473 %add.ptr = getelementptr inbounds i32, ptr %p, i64 -174 %tmp1 = load i32, ptr %add.ptr, align 475 %sexttmp = sext i32 %tmp to i6476 %sexttmp1 = sext i32 %tmp1 to i6477 %add = add nsw i64 %sexttmp1, %sexttmp78 ret i64 %add79}80 81; Also make sure we only match valid offsets.82; CHECK-LABEL: test_ldrq_ldruq_invalidoffset:83; CHECK-NEXT: ldr q[[V0:[0-9]+]], [x0]84; CHECK-NEXT: ldur q[[V1:[0-9]+]], [x0, #24]85; CHECK-NEXT: add.2d v0, v[[V0]], v[[V1]]86; CHECK-NEXT: ret87define <2 x i64> @test_ldrq_ldruq_invalidoffset(ptr %p) #0 {88 %tmp1 = load <2 x i64>, ptr %p, align 889 %add.ptr2 = getelementptr inbounds i64, ptr %p, i64 390 %tmp2 = load <2 x i64>, ptr %add.ptr2, align 891 %add = add nsw <2 x i64> %tmp1, %tmp292 ret <2 x i64> %add93}94 95; Pair an unscaled store with a scaled store where the scaled store has a96; non-zero offset. This should not hit an assert.97; CHECK-LABEL: test_stur_str_no_assert98; CHECK: stp xzr, xzr, [sp, #16]99; CHECK: ret100define void @test_stur_str_no_assert() #0 {101entry:102 %a1 = alloca i64, align 4103 %a2 = alloca [12 x i8], align 4104 %C = getelementptr inbounds [12 x i8], ptr %a2, i64 0, i64 4105 store i64 0, ptr %C, align 4106 call void @llvm.memset.p0.i64(ptr align 8 %a1, i8 0, i64 8, i1 false)107 ret void108}109 110declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)111 112 113attributes #0 = { nounwind }114