1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=aarch64 -aarch64-neon-syntax=apple -aarch64-stp-suppress=false -verify-machineinstrs -asm-verbose=false | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_strd_sturd: 4*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp d0, d1, [x0, #-8] 5*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 6*9880d681SAndroid Build Coastguard Workerdefine void @test_strd_sturd(float* %ptr, <2 x float> %v1, <2 x float> %v2) #0 { 7*9880d681SAndroid Build Coastguard Worker %tmp1 = bitcast float* %ptr to <2 x float>* 8*9880d681SAndroid Build Coastguard Worker store <2 x float> %v2, <2 x float>* %tmp1, align 16 9*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds float, float* %ptr, i64 -2 10*9880d681SAndroid Build Coastguard Worker %tmp = bitcast float* %add.ptr to <2 x float>* 11*9880d681SAndroid Build Coastguard Worker store <2 x float> %v1, <2 x float>* %tmp, align 16 12*9880d681SAndroid Build Coastguard Worker ret void 13*9880d681SAndroid Build Coastguard Worker} 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sturd_strd: 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp d0, d1, [x0, #-8] 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 18*9880d681SAndroid Build Coastguard Workerdefine void @test_sturd_strd(float* %ptr, <2 x float> %v1, <2 x float> %v2) #0 { 19*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds float, float* %ptr, i64 -2 20*9880d681SAndroid Build Coastguard Worker %tmp = bitcast float* %add.ptr to <2 x float>* 21*9880d681SAndroid Build Coastguard Worker store <2 x float> %v1, <2 x float>* %tmp, align 16 22*9880d681SAndroid Build Coastguard Worker %tmp1 = bitcast float* %ptr to <2 x float>* 23*9880d681SAndroid Build Coastguard Worker store <2 x float> %v2, <2 x float>* %tmp1, align 16 24*9880d681SAndroid Build Coastguard Worker ret void 25*9880d681SAndroid Build Coastguard Worker} 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_strq_sturq: 28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp q0, q1, [x0, #-16] 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 30*9880d681SAndroid Build Coastguard Workerdefine void @test_strq_sturq(double* %ptr, <2 x double> %v1, <2 x double> %v2) #0 { 31*9880d681SAndroid Build Coastguard Worker %tmp1 = bitcast double* %ptr to <2 x double>* 32*9880d681SAndroid Build Coastguard Worker store <2 x double> %v2, <2 x double>* %tmp1, align 16 33*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds double, double* %ptr, i64 -2 34*9880d681SAndroid Build Coastguard Worker %tmp = bitcast double* %add.ptr to <2 x double>* 35*9880d681SAndroid Build Coastguard Worker store <2 x double> %v1, <2 x double>* %tmp, align 16 36*9880d681SAndroid Build Coastguard Worker ret void 37*9880d681SAndroid Build Coastguard Worker} 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_sturq_strq: 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp q0, q1, [x0, #-16] 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 42*9880d681SAndroid Build Coastguard Workerdefine void @test_sturq_strq(double* %ptr, <2 x double> %v1, <2 x double> %v2) #0 { 43*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds double, double* %ptr, i64 -2 44*9880d681SAndroid Build Coastguard Worker %tmp = bitcast double* %add.ptr to <2 x double>* 45*9880d681SAndroid Build Coastguard Worker store <2 x double> %v1, <2 x double>* %tmp, align 16 46*9880d681SAndroid Build Coastguard Worker %tmp1 = bitcast double* %ptr to <2 x double>* 47*9880d681SAndroid Build Coastguard Worker store <2 x double> %v2, <2 x double>* %tmp1, align 16 48*9880d681SAndroid Build Coastguard Worker ret void 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ldrx_ldurx: 52*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-8] 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add x0, [[V0]], [[V1]] 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 55*9880d681SAndroid Build Coastguard Workerdefine i64 @test_ldrx_ldurx(i64* %p) #0 { 56*9880d681SAndroid Build Coastguard Worker %tmp = load i64, i64* %p, align 4 57*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds i64, i64* %p, i64 -1 58*9880d681SAndroid Build Coastguard Worker %tmp1 = load i64, i64* %add.ptr, align 4 59*9880d681SAndroid Build Coastguard Worker %add = add nsw i64 %tmp1, %tmp 60*9880d681SAndroid Build Coastguard Worker ret i64 %add 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ldurx_ldrx: 64*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-8] 65*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add x0, [[V0]], [[V1]] 66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 67*9880d681SAndroid Build Coastguard Workerdefine i64 @test_ldurx_ldrx(i64* %p) #0 { 68*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds i64, i64* %p, i64 -1 69*9880d681SAndroid Build Coastguard Worker %tmp1 = load i64, i64* %add.ptr, align 4 70*9880d681SAndroid Build Coastguard Worker %tmp = load i64, i64* %p, align 4 71*9880d681SAndroid Build Coastguard Worker %add = add nsw i64 %tmp1, %tmp 72*9880d681SAndroid Build Coastguard Worker ret i64 %add 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ldrsw_ldursw: 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldpsw [[V0:x[0-9]+]], [[V1:x[0-9]+]], [x0, #-4] 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add x0, [[V0]], [[V1]] 78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 79*9880d681SAndroid Build Coastguard Workerdefine i64 @test_ldrsw_ldursw(i32* %p) #0 { 80*9880d681SAndroid Build Coastguard Worker %tmp = load i32, i32* %p, align 4 81*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds i32, i32* %p, i64 -1 82*9880d681SAndroid Build Coastguard Worker %tmp1 = load i32, i32* %add.ptr, align 4 83*9880d681SAndroid Build Coastguard Worker %sexttmp = sext i32 %tmp to i64 84*9880d681SAndroid Build Coastguard Worker %sexttmp1 = sext i32 %tmp1 to i64 85*9880d681SAndroid Build Coastguard Worker %add = add nsw i64 %sexttmp1, %sexttmp 86*9880d681SAndroid Build Coastguard Worker ret i64 %add 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; Also make sure we only match valid offsets. 90*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ldrq_ldruq_invalidoffset: 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr q[[V0:[0-9]+]], [x0] 92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldur q[[V1:[0-9]+]], [x0, #24] 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add.2d v0, v[[V0]], v[[V1]] 94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 95*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test_ldrq_ldruq_invalidoffset(i64* %p) #0 { 96*9880d681SAndroid Build Coastguard Worker %a1 = bitcast i64* %p to <2 x i64>* 97*9880d681SAndroid Build Coastguard Worker %tmp1 = load <2 x i64>, < 2 x i64>* %a1, align 8 98*9880d681SAndroid Build Coastguard Worker %add.ptr2 = getelementptr inbounds i64, i64* %p, i64 3 99*9880d681SAndroid Build Coastguard Worker %a2 = bitcast i64* %add.ptr2 to <2 x i64>* 100*9880d681SAndroid Build Coastguard Worker %tmp2 = load <2 x i64>, <2 x i64>* %a2, align 8 101*9880d681SAndroid Build Coastguard Worker %add = add nsw <2 x i64> %tmp1, %tmp2 102*9880d681SAndroid Build Coastguard Worker ret <2 x i64> %add 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; Pair an unscaled store with a scaled store where the scaled store has a 106*9880d681SAndroid Build Coastguard Worker; non-zero offset. This should not hit an assert. 107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_stur_str_no_assert 108*9880d681SAndroid Build Coastguard Worker; CHECK: stp xzr, xzr, [sp, #16] 109*9880d681SAndroid Build Coastguard Worker; CHECK: ret 110*9880d681SAndroid Build Coastguard Workerdefine void @test_stur_str_no_assert() #0 { 111*9880d681SAndroid Build Coastguard Workerentry: 112*9880d681SAndroid Build Coastguard Worker %a1 = alloca i64, align 4 113*9880d681SAndroid Build Coastguard Worker %a2 = alloca [12 x i8], align 4 114*9880d681SAndroid Build Coastguard Worker %0 = bitcast i64* %a1 to i8* 115*9880d681SAndroid Build Coastguard Worker %C = getelementptr inbounds [12 x i8], [12 x i8]* %a2, i64 0, i64 4 116*9880d681SAndroid Build Coastguard Worker %1 = bitcast i8* %C to i64* 117*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %1, align 4 118*9880d681SAndroid Build Coastguard Worker call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 8, i32 8, i1 false) 119*9880d681SAndroid Build Coastguard Worker ret void 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind } 126