1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; PR7158 4*9880d681SAndroid Build Coastguard Workerdefine i32 @test_pr7158() nounwind { 5*9880d681SAndroid Build Coastguard Workerbb.nph55.bb.nph55.split_crit_edge: 6*9880d681SAndroid Build Coastguard Worker br label %bb3 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerbb3: ; preds = %bb3, %bb.nph55.bb.nph55.split_crit_edge 9*9880d681SAndroid Build Coastguard Worker br i1 undef, label %bb.i19, label %bb3 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerbb.i19: ; preds = %bb.i19, %bb3 12*9880d681SAndroid Build Coastguard Worker %0 = insertelement <4 x float> undef, float undef, i32 3 ; <<4 x float>> [#uses=3] 13*9880d681SAndroid Build Coastguard Worker %1 = fmul <4 x float> %0, %0 ; <<4 x float>> [#uses=1] 14*9880d681SAndroid Build Coastguard Worker %2 = bitcast <4 x float> %1 to <2 x double> ; <<2 x double>> [#uses=0] 15*9880d681SAndroid Build Coastguard Worker %3 = fmul <4 x float> %0, undef ; <<4 x float>> [#uses=0] 16*9880d681SAndroid Build Coastguard Worker br label %bb.i19 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker; Check that the DAG combiner does not arbitrarily modify BUILD_VECTORs 20*9880d681SAndroid Build Coastguard Worker; after legalization. 21*9880d681SAndroid Build Coastguard Workerdefine void @test_illegal_build_vector() nounwind { 22*9880d681SAndroid Build Coastguard Workerentry: 23*9880d681SAndroid Build Coastguard Worker store <2 x i64> undef, <2 x i64>* undef, align 16 24*9880d681SAndroid Build Coastguard Worker %0 = load <16 x i8>, <16 x i8>* undef, align 16 ; <<16 x i8>> [#uses=1] 25*9880d681SAndroid Build Coastguard Worker %1 = or <16 x i8> zeroinitializer, %0 ; <<16 x i8>> [#uses=1] 26*9880d681SAndroid Build Coastguard Worker store <16 x i8> %1, <16 x i8>* undef, align 16 27*9880d681SAndroid Build Coastguard Worker ret void 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker; PR22678 31*9880d681SAndroid Build Coastguard Worker; Check CONCAT_VECTORS DAG combiner pass doesn't introduce illegal types. 32*9880d681SAndroid Build Coastguard Workerdefine void @test_pr22678() { 33*9880d681SAndroid Build Coastguard Worker %1 = fptoui <16 x float> undef to <16 x i8> 34*9880d681SAndroid Build Coastguard Worker store <16 x i8> %1, <16 x i8>* undef 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Radar 8407927: Make sure that VMOVRRD gets optimized away when the result is 39*9880d681SAndroid Build Coastguard Worker; converted back to be used as a vector type. 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_vmovrrd_combine: 41*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_vmovrrd_combine() nounwind { 42*9880d681SAndroid Build Coastguard Workerentry: 43*9880d681SAndroid Build Coastguard Worker br i1 undef, label %bb1, label %bb2 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerbb1: 46*9880d681SAndroid Build Coastguard Worker %0 = bitcast <2 x i64> zeroinitializer to <2 x double> 47*9880d681SAndroid Build Coastguard Worker %1 = extractelement <2 x double> %0, i32 0 48*9880d681SAndroid Build Coastguard Worker %2 = bitcast double %1 to i64 49*9880d681SAndroid Build Coastguard Worker %3 = insertelement <1 x i64> undef, i64 %2, i32 0 50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: vmov s 51*9880d681SAndroid Build Coastguard Worker; CHECK: vext.8 52*9880d681SAndroid Build Coastguard Worker %4 = shufflevector <1 x i64> %3, <1 x i64> undef, <2 x i32> <i32 0, i32 1> 53*9880d681SAndroid Build Coastguard Worker %tmp2006.3 = bitcast <2 x i64> %4 to <16 x i8> 54*9880d681SAndroid Build Coastguard Worker %5 = shufflevector <16 x i8> %tmp2006.3, <16 x i8> undef, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19> 55*9880d681SAndroid Build Coastguard Worker %tmp2004.3 = bitcast <16 x i8> %5 to <4 x i32> 56*9880d681SAndroid Build Coastguard Worker br i1 undef, label %bb2, label %bb1 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerbb2: 59*9880d681SAndroid Build Coastguard Worker %result = phi <4 x i32> [ undef, %entry ], [ %tmp2004.3, %bb1 ] 60*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %result 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; Test trying to do a ShiftCombine on illegal types. 64*9880d681SAndroid Build Coastguard Worker; The vector should be split first. 65*9880d681SAndroid Build Coastguard Workerdefine void @lshrIllegalType(<8 x i32>* %A) nounwind { 66*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i32>, <8 x i32>* %A 67*9880d681SAndroid Build Coastguard Worker %tmp2 = lshr <8 x i32> %tmp1, < i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> 68*9880d681SAndroid Build Coastguard Worker store <8 x i32> %tmp2, <8 x i32>* %A 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; Test folding a binary vector operation with constant BUILD_VECTOR 73*9880d681SAndroid Build Coastguard Worker; operands with i16 elements. 74*9880d681SAndroid Build Coastguard Workerdefine void @test_i16_constant_fold() nounwind optsize { 75*9880d681SAndroid Build Coastguard Workerentry: 76*9880d681SAndroid Build Coastguard Worker %0 = sext <4 x i1> zeroinitializer to <4 x i16> 77*9880d681SAndroid Build Coastguard Worker %1 = add <4 x i16> %0, zeroinitializer 78*9880d681SAndroid Build Coastguard Worker %2 = shufflevector <4 x i16> %1, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 79*9880d681SAndroid Build Coastguard Worker %3 = add <8 x i16> %2, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> 80*9880d681SAndroid Build Coastguard Worker %4 = trunc <8 x i16> %3 to <8 x i8> 81*9880d681SAndroid Build Coastguard Worker tail call void @llvm.arm.neon.vst1.p0i8.v8i8(i8* undef, <8 x i8> %4, i32 1) 82*9880d681SAndroid Build Coastguard Worker unreachable 83*9880d681SAndroid Build Coastguard Worker} 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.arm.neon.vst1.p0i8.v8i8(i8*, <8 x i8>, i32) nounwind 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker; Test that loads and stores of i64 vector elements are handled as f64 values 88*9880d681SAndroid Build Coastguard Worker; so they are not split up into i32 values. Radar 8755338. 89*9880d681SAndroid Build Coastguard Workerdefine void @i64_buildvector(i64* %ptr, <2 x i64>* %vp) nounwind { 90*9880d681SAndroid Build Coastguard Worker; CHECK: i64_buildvector 91*9880d681SAndroid Build Coastguard Worker; CHECK: vldr 92*9880d681SAndroid Build Coastguard Worker %t0 = load i64, i64* %ptr, align 4 93*9880d681SAndroid Build Coastguard Worker %t1 = insertelement <2 x i64> undef, i64 %t0, i32 0 94*9880d681SAndroid Build Coastguard Worker store <2 x i64> %t1, <2 x i64>* %vp 95*9880d681SAndroid Build Coastguard Worker ret void 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerdefine void @i64_insertelement(i64* %ptr, <2 x i64>* %vp) nounwind { 99*9880d681SAndroid Build Coastguard Worker; CHECK: i64_insertelement 100*9880d681SAndroid Build Coastguard Worker; CHECK: vldr 101*9880d681SAndroid Build Coastguard Worker %t0 = load i64, i64* %ptr, align 4 102*9880d681SAndroid Build Coastguard Worker %vec = load <2 x i64>, <2 x i64>* %vp 103*9880d681SAndroid Build Coastguard Worker %t1 = insertelement <2 x i64> %vec, i64 %t0, i32 0 104*9880d681SAndroid Build Coastguard Worker store <2 x i64> %t1, <2 x i64>* %vp 105*9880d681SAndroid Build Coastguard Worker ret void 106*9880d681SAndroid Build Coastguard Worker} 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerdefine void @i64_extractelement(i64* %ptr, <2 x i64>* %vp) nounwind { 109*9880d681SAndroid Build Coastguard Worker; CHECK: i64_extractelement 110*9880d681SAndroid Build Coastguard Worker; CHECK: vstr 111*9880d681SAndroid Build Coastguard Worker %vec = load <2 x i64>, <2 x i64>* %vp 112*9880d681SAndroid Build Coastguard Worker %t1 = extractelement <2 x i64> %vec, i32 0 113*9880d681SAndroid Build Coastguard Worker store i64 %t1, i64* %ptr 114*9880d681SAndroid Build Coastguard Worker ret void 115*9880d681SAndroid Build Coastguard Worker} 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker; Test trying to do a AND Combine on illegal types. 118*9880d681SAndroid Build Coastguard Workerdefine void @andVec(<3 x i8>* %A) nounwind { 119*9880d681SAndroid Build Coastguard Worker %tmp = load <3 x i8>, <3 x i8>* %A, align 4 120*9880d681SAndroid Build Coastguard Worker %and = and <3 x i8> %tmp, <i8 7, i8 7, i8 7> 121*9880d681SAndroid Build Coastguard Worker store <3 x i8> %and, <3 x i8>* %A 122*9880d681SAndroid Build Coastguard Worker ret void 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; Test trying to do an OR Combine on illegal types. 127*9880d681SAndroid Build Coastguard Workerdefine void @orVec(<3 x i8>* %A) nounwind { 128*9880d681SAndroid Build Coastguard Worker %tmp = load <3 x i8>, <3 x i8>* %A, align 4 129*9880d681SAndroid Build Coastguard Worker %or = or <3 x i8> %tmp, <i8 7, i8 7, i8 7> 130*9880d681SAndroid Build Coastguard Worker store <3 x i8> %or, <3 x i8>* %A 131*9880d681SAndroid Build Coastguard Worker ret void 132*9880d681SAndroid Build Coastguard Worker} 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker; The following test was hitting an assertion in the DAG combiner when 135*9880d681SAndroid Build Coastguard Worker; constant folding the multiply because the "sext undef" was translated to 136*9880d681SAndroid Build Coastguard Worker; a BUILD_VECTOR with i32 0 operands, which did not match the i16 operands 137*9880d681SAndroid Build Coastguard Worker; of the other BUILD_VECTOR. 138*9880d681SAndroid Build Coastguard Workerdefine i16 @foldBuildVectors() { 139*9880d681SAndroid Build Coastguard Worker %1 = sext <8 x i8> undef to <8 x i16> 140*9880d681SAndroid Build Coastguard Worker %2 = mul <8 x i16> %1, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255> 141*9880d681SAndroid Build Coastguard Worker %3 = extractelement <8 x i16> %2, i32 0 142*9880d681SAndroid Build Coastguard Worker ret i16 %3 143*9880d681SAndroid Build Coastguard Worker} 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker; Test that we are generating vrev and vext for reverse shuffles of v8i16 146*9880d681SAndroid Build Coastguard Worker; shuffles. 147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reverse_v8i16: 148*9880d681SAndroid Build Coastguard Workerdefine void @reverse_v8i16(<8 x i16>* %loadaddr, <8 x i16>* %storeaddr) { 149*9880d681SAndroid Build Coastguard Worker %v0 = load <8 x i16>, <8 x i16>* %loadaddr 150*9880d681SAndroid Build Coastguard Worker ; CHECK: vrev64.16 151*9880d681SAndroid Build Coastguard Worker ; CHECK: vext.16 152*9880d681SAndroid Build Coastguard Worker %v1 = shufflevector <8 x i16> %v0, <8 x i16> undef, 153*9880d681SAndroid Build Coastguard Worker <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 154*9880d681SAndroid Build Coastguard Worker store <8 x i16> %v1, <8 x i16>* %storeaddr 155*9880d681SAndroid Build Coastguard Worker ret void 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; Test that we are generating vrev and vext for reverse shuffles of v16i8 159*9880d681SAndroid Build Coastguard Worker; shuffles. 160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reverse_v16i8: 161*9880d681SAndroid Build Coastguard Workerdefine void @reverse_v16i8(<16 x i8>* %loadaddr, <16 x i8>* %storeaddr) { 162*9880d681SAndroid Build Coastguard Worker %v0 = load <16 x i8>, <16 x i8>* %loadaddr 163*9880d681SAndroid Build Coastguard Worker ; CHECK: vrev64.8 164*9880d681SAndroid Build Coastguard Worker ; CHECK: vext.8 165*9880d681SAndroid Build Coastguard Worker %v1 = shufflevector <16 x i8> %v0, <16 x i8> undef, 166*9880d681SAndroid Build Coastguard Worker <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, 167*9880d681SAndroid Build Coastguard Worker i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 168*9880d681SAndroid Build Coastguard Worker store <16 x i8> %v1, <16 x i8>* %storeaddr 169*9880d681SAndroid Build Coastguard Worker ret void 170*9880d681SAndroid Build Coastguard Worker} 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker; <rdar://problem/14170854>. 173*9880d681SAndroid Build Coastguard Worker; vldr cannot handle unaligned loads. 174*9880d681SAndroid Build Coastguard Worker; Fall back to vld1.32, which can, instead of using the general purpose loads 175*9880d681SAndroid Build Coastguard Worker; followed by a costly sequence of instructions to build the vector register. 176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t3: 177*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {[[REG:d[0-9]+]][0]} 178*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {[[REG]][1]} 179*9880d681SAndroid Build Coastguard Worker; CHECK: vmull.u8 q{{[0-9]+}}, [[REG]], [[REG]] 180*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @t3(i8 zeroext %xf, i8* nocapture %sp0, i8* nocapture %sp1, i32* nocapture %outp) { 181*9880d681SAndroid Build Coastguard Workerentry: 182*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.cast = bitcast i8* %sp0 to i32* 183*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.copyload = load i32, i32* %pix_sp0.0.cast, align 1 184*9880d681SAndroid Build Coastguard Worker %pix_sp1.0.cast = bitcast i8* %sp1 to i32* 185*9880d681SAndroid Build Coastguard Worker %pix_sp1.0.copyload = load i32, i32* %pix_sp1.0.cast, align 1 186*9880d681SAndroid Build Coastguard Worker %vecinit = insertelement <2 x i32> undef, i32 %pix_sp0.0.copyload, i32 0 187*9880d681SAndroid Build Coastguard Worker %vecinit1 = insertelement <2 x i32> %vecinit, i32 %pix_sp1.0.copyload, i32 1 188*9880d681SAndroid Build Coastguard Worker %0 = bitcast <2 x i32> %vecinit1 to <8 x i8> 189*9880d681SAndroid Build Coastguard Worker %vmull.i = tail call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %0, <8 x i8> %0) 190*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %vmull.i 191*9880d681SAndroid Build Coastguard Worker} 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readnone 194*9880d681SAndroid Build Coastguard Workerdeclare <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8>, <8 x i8>) 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker; Check that (insert_vector_elt (load)) => (vector_load). 197*9880d681SAndroid Build Coastguard Worker; Thus, check that scalar_to_vector do not interfer with that. 198*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @t4(i8* nocapture %sp0) { 199*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t4: 200*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {{{d[0-9]+}}[0]}, [r0] 201*9880d681SAndroid Build Coastguard Workerentry: 202*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.cast = bitcast i8* %sp0 to i32* 203*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.copyload = load i32, i32* %pix_sp0.0.cast, align 1 204*9880d681SAndroid Build Coastguard Worker %vec = insertelement <2 x i32> undef, i32 %pix_sp0.0.copyload, i32 0 205*9880d681SAndroid Build Coastguard Worker %0 = bitcast <2 x i32> %vec to <8 x i8> 206*9880d681SAndroid Build Coastguard Worker %vmull.i = tail call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %0, <8 x i8> %0) 207*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %vmull.i 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker; Make sure vector load is used for all three loads. 211*9880d681SAndroid Build Coastguard Worker; Lowering to build vector was breaking the single use property of the load of 212*9880d681SAndroid Build Coastguard Worker; %pix_sp0.0.copyload. 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: t5: 214*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {[[REG1:d[0-9]+]][1]}, [r0] 215*9880d681SAndroid Build Coastguard Worker; CHECK: vorr [[REG2:d[0-9]+]], [[REG1]], [[REG1]] 216*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {[[REG1]][0]}, [r1] 217*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.32 {[[REG2]][0]}, [r2] 218*9880d681SAndroid Build Coastguard Worker; CHECK: vmull.u8 q{{[0-9]+}}, [[REG1]], [[REG2]] 219*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @t5(i8* nocapture %sp0, i8* nocapture %sp1, i8* nocapture %sp2) { 220*9880d681SAndroid Build Coastguard Workerentry: 221*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.cast = bitcast i8* %sp0 to i32* 222*9880d681SAndroid Build Coastguard Worker %pix_sp0.0.copyload = load i32, i32* %pix_sp0.0.cast, align 1 223*9880d681SAndroid Build Coastguard Worker %pix_sp1.0.cast = bitcast i8* %sp1 to i32* 224*9880d681SAndroid Build Coastguard Worker %pix_sp1.0.copyload = load i32, i32* %pix_sp1.0.cast, align 1 225*9880d681SAndroid Build Coastguard Worker %pix_sp2.0.cast = bitcast i8* %sp2 to i32* 226*9880d681SAndroid Build Coastguard Worker %pix_sp2.0.copyload = load i32, i32* %pix_sp2.0.cast, align 1 227*9880d681SAndroid Build Coastguard Worker %vec = insertelement <2 x i32> undef, i32 %pix_sp0.0.copyload, i32 1 228*9880d681SAndroid Build Coastguard Worker %vecinit1 = insertelement <2 x i32> %vec, i32 %pix_sp1.0.copyload, i32 0 229*9880d681SAndroid Build Coastguard Worker %vecinit2 = insertelement <2 x i32> %vec, i32 %pix_sp2.0.copyload, i32 0 230*9880d681SAndroid Build Coastguard Worker %0 = bitcast <2 x i32> %vecinit1 to <8 x i8> 231*9880d681SAndroid Build Coastguard Worker %1 = bitcast <2 x i32> %vecinit2 to <8 x i8> 232*9880d681SAndroid Build Coastguard Worker %vmull.i = tail call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %0, <8 x i8> %1) 233*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %vmull.i 234*9880d681SAndroid Build Coastguard Worker} 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker; <rdar://problem/14989896> Make sure we manage to truncate a vector from an 237*9880d681SAndroid Build Coastguard Worker; illegal type to a legal type. 238*9880d681SAndroid Build Coastguard Workerdefine <2 x i8> @test_truncate(<2 x i128> %in) { 239*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_truncate: 240*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[BASE:r[0-9]+]], sp 241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vld1.32 {[[REG1:d[0-9]+]][0]}, {{\[}}[[BASE]]:32] 242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[BASE2:r[0-9]+]], [[BASE]], #4 243*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vld1.32 {[[REG1]][1]}, {{\[}}[[BASE2]]:32] 244*9880d681SAndroid Build Coastguard Worker; REG2 Should map on the same Q register as REG1, i.e., REG2 = REG1 - 1, but we 245*9880d681SAndroid Build Coastguard Worker; cannot express that. 246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vmov.32 [[REG2:d[0-9]+]][0], r0 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vmov.32 [[REG2]][1], r1 248*9880d681SAndroid Build Coastguard Worker; The Q register used here should match floor(REG1/2), but we cannot express that. 249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vmovn.i64 [[RES:d[0-9]+]], q{{[0-9]+}} 250*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vmov r0, r1, [[RES]] 251*9880d681SAndroid Build Coastguard Workerentry: 252*9880d681SAndroid Build Coastguard Worker %res = trunc <2 x i128> %in to <2 x i8> 253*9880d681SAndroid Build Coastguard Worker ret <2 x i8> %res 254*9880d681SAndroid Build Coastguard Worker} 255