1 ; RUN: llc -mtriple arm64-apple-ios -O3 -o - < %s | FileCheck %s 2 ; <rdar://problem/14477220> 3 4 %class.Complex = type { float, float } 5 %class.Complex_int = type { i32, i32 } 6 %class.Complex_long = type { i64, i64 } 7 8 ; CHECK-LABEL: @test 9 ; CHECK: add [[BASE:x[0-9]+]], x0, x1, lsl #3 10 ; CHECK: ldp [[CPLX1_I:s[0-9]+]], [[CPLX1_R:s[0-9]+]], {{\[}}[[BASE]]] 11 ; CHECK: ldp [[CPLX2_I:s[0-9]+]], [[CPLX2_R:s[0-9]+]], {{\[}}[[BASE]], #64] 12 ; CHECK: fadd {{s[0-9]+}}, [[CPLX2_I]], [[CPLX1_I]] 13 ; CHECK: fadd {{s[0-9]+}}, [[CPLX2_R]], [[CPLX1_R]] 14 ; CHECK: ret 15 define void @test(%class.Complex* nocapture %out, i64 %out_start) { 16 entry: 17 %arrayidx = getelementptr inbounds %class.Complex, %class.Complex* %out, i64 %out_start 18 %0 = bitcast %class.Complex* %arrayidx to i64* 19 %1 = load i64, i64* %0, align 4 20 %t0.sroa.0.0.extract.trunc = trunc i64 %1 to i32 21 %2 = bitcast i32 %t0.sroa.0.0.extract.trunc to float 22 %t0.sroa.2.0.extract.shift = lshr i64 %1, 32 23 %t0.sroa.2.0.extract.trunc = trunc i64 %t0.sroa.2.0.extract.shift to i32 24 %3 = bitcast i32 %t0.sroa.2.0.extract.trunc to float 25 %add = add i64 %out_start, 8 26 %arrayidx2 = getelementptr inbounds %class.Complex, %class.Complex* %out, i64 %add 27 %i.i = getelementptr inbounds %class.Complex, %class.Complex* %arrayidx2, i64 0, i32 0 28 %4 = load float, float* %i.i, align 4 29 %add.i = fadd float %4, %2 30 %retval.sroa.0.0.vec.insert.i = insertelement <2 x float> undef, float %add.i, i32 0 31 %r.i = getelementptr inbounds %class.Complex, %class.Complex* %arrayidx2, i64 0, i32 1 32 %5 = load float, float* %r.i, align 4 33 %add5.i = fadd float %5, %3 34 %retval.sroa.0.4.vec.insert.i = insertelement <2 x float> %retval.sroa.0.0.vec.insert.i, float %add5.i, i32 1 35 %ref.tmp.sroa.0.0.cast = bitcast %class.Complex* %arrayidx to <2 x float>* 36 store <2 x float> %retval.sroa.0.4.vec.insert.i, <2 x float>* %ref.tmp.sroa.0.0.cast, align 4 37 ret void 38 } 39 40 ; CHECK-LABEL: @test_int 41 ; CHECK: add [[BASE:x[0-9]+]], x0, x1, lsl #3 42 ; CHECK: ldp [[CPLX1_I:w[0-9]+]], [[CPLX1_R:w[0-9]+]], {{\[}}[[BASE]]] 43 ; CHECK: ldp [[CPLX2_I:w[0-9]+]], [[CPLX2_R:w[0-9]+]], {{\[}}[[BASE]], #64] 44 ; CHECK: add {{w[0-9]+}}, [[CPLX2_I]], [[CPLX1_I]] 45 ; CHECK: add {{w[0-9]+}}, [[CPLX2_R]], [[CPLX1_R]] 46 ; CHECK: ret 47 define void @test_int(%class.Complex_int* nocapture %out, i64 %out_start) { 48 entry: 49 %arrayidx = getelementptr inbounds %class.Complex_int, %class.Complex_int* %out, i64 %out_start 50 %0 = bitcast %class.Complex_int* %arrayidx to i64* 51 %1 = load i64, i64* %0, align 4 52 %t0.sroa.0.0.extract.trunc = trunc i64 %1 to i32 53 %2 = bitcast i32 %t0.sroa.0.0.extract.trunc to i32 54 %t0.sroa.2.0.extract.shift = lshr i64 %1, 32 55 %t0.sroa.2.0.extract.trunc = trunc i64 %t0.sroa.2.0.extract.shift to i32 56 %3 = bitcast i32 %t0.sroa.2.0.extract.trunc to i32 57 %add = add i64 %out_start, 8 58 %arrayidx2 = getelementptr inbounds %class.Complex_int, %class.Complex_int* %out, i64 %add 59 %i.i = getelementptr inbounds %class.Complex_int, %class.Complex_int* %arrayidx2, i64 0, i32 0 60 %4 = load i32, i32* %i.i, align 4 61 %add.i = add i32 %4, %2 62 %retval.sroa.0.0.vec.insert.i = insertelement <2 x i32> undef, i32 %add.i, i32 0 63 %r.i = getelementptr inbounds %class.Complex_int, %class.Complex_int* %arrayidx2, i64 0, i32 1 64 %5 = load i32, i32* %r.i, align 4 65 %add5.i = add i32 %5, %3 66 %retval.sroa.0.4.vec.insert.i = insertelement <2 x i32> %retval.sroa.0.0.vec.insert.i, i32 %add5.i, i32 1 67 %ref.tmp.sroa.0.0.cast = bitcast %class.Complex_int* %arrayidx to <2 x i32>* 68 store <2 x i32> %retval.sroa.0.4.vec.insert.i, <2 x i32>* %ref.tmp.sroa.0.0.cast, align 4 69 ret void 70 } 71 72 ; CHECK-LABEL: @test_long 73 ; CHECK: add [[BASE:x[0-9]+]], x0, x1, lsl #4 74 ; CHECK: ldp [[CPLX1_I:x[0-9]+]], [[CPLX1_R:x[0-9]+]], {{\[}}[[BASE]]] 75 ; CHECK: ldp [[CPLX2_I:x[0-9]+]], [[CPLX2_R:x[0-9]+]], {{\[}}[[BASE]], #128] 76 ; CHECK: add {{x[0-9]+}}, [[CPLX2_I]], [[CPLX1_I]] 77 ; CHECK: add {{x[0-9]+}}, [[CPLX2_R]], [[CPLX1_R]] 78 ; CHECK: ret 79 define void @test_long(%class.Complex_long* nocapture %out, i64 %out_start) { 80 entry: 81 %arrayidx = getelementptr inbounds %class.Complex_long, %class.Complex_long* %out, i64 %out_start 82 %0 = bitcast %class.Complex_long* %arrayidx to i128* 83 %1 = load i128, i128* %0, align 4 84 %t0.sroa.0.0.extract.trunc = trunc i128 %1 to i64 85 %2 = bitcast i64 %t0.sroa.0.0.extract.trunc to i64 86 %t0.sroa.2.0.extract.shift = lshr i128 %1, 64 87 %t0.sroa.2.0.extract.trunc = trunc i128 %t0.sroa.2.0.extract.shift to i64 88 %3 = bitcast i64 %t0.sroa.2.0.extract.trunc to i64 89 %add = add i64 %out_start, 8 90 %arrayidx2 = getelementptr inbounds %class.Complex_long, %class.Complex_long* %out, i64 %add 91 %i.i = getelementptr inbounds %class.Complex_long, %class.Complex_long* %arrayidx2, i32 0, i32 0 92 %4 = load i64, i64* %i.i, align 4 93 %add.i = add i64 %4, %2 94 %retval.sroa.0.0.vec.insert.i = insertelement <2 x i64> undef, i64 %add.i, i32 0 95 %r.i = getelementptr inbounds %class.Complex_long, %class.Complex_long* %arrayidx2, i32 0, i32 1 96 %5 = load i64, i64* %r.i, align 4 97 %add5.i = add i64 %5, %3 98 %retval.sroa.0.4.vec.insert.i = insertelement <2 x i64> %retval.sroa.0.0.vec.insert.i, i64 %add5.i, i32 1 99 %ref.tmp.sroa.0.0.cast = bitcast %class.Complex_long* %arrayidx to <2 x i64>* 100 store <2 x i64> %retval.sroa.0.4.vec.insert.i, <2 x i64>* %ref.tmp.sroa.0.0.cast, align 4 101 ret void 102 } 103