1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=arm-eabi -mattr=+neon %s -o - | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev64D8(<8 x i8>* %A) nounwind { 4*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D8: 5*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8 6*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i8>, <8 x i8>* %A 7*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 8*9880d681SAndroid Build Coastguard Worker ret <8 x i8> %tmp2 9*9880d681SAndroid Build Coastguard Worker} 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test_vrev64D16(<4 x i16>* %A) nounwind { 12*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D16: 13*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.16 14*9880d681SAndroid Build Coastguard Worker %tmp1 = load <4 x i16>, <4 x i16>* %A 15*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 16*9880d681SAndroid Build Coastguard Worker ret <4 x i16> %tmp2 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test_vrev64D32(<2 x i32>* %A) nounwind { 20*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D32: 21*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32 22*9880d681SAndroid Build Coastguard Worker %tmp1 = load <2 x i32>, <2 x i32>* %A 23*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> <i32 1, i32 0> 24*9880d681SAndroid Build Coastguard Worker ret <2 x i32> %tmp2 25*9880d681SAndroid Build Coastguard Worker} 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @test_vrev64Df(<2 x float>* %A) nounwind { 28*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Df: 29*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32 30*9880d681SAndroid Build Coastguard Worker %tmp1 = load <2 x float>, <2 x float>* %A 31*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> <i32 1, i32 0> 32*9880d681SAndroid Build Coastguard Worker ret <2 x float> %tmp2 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev64Q8(<16 x i8>* %A) nounwind { 36*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q8: 37*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8 38*9880d681SAndroid Build Coastguard Worker %tmp1 = load <16 x i8>, <16 x i8>* %A 39*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8> 40*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %tmp2 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev64Q16(<8 x i16>* %A) nounwind { 44*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q16: 45*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.16 46*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i16>, <8 x i16>* %A 47*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4> 48*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %tmp2 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_vrev64Q32(<4 x i32>* %A) nounwind { 52*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q32: 53*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32 54*9880d681SAndroid Build Coastguard Worker %tmp1 = load <4 x i32>, <4 x i32>* %A 55*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 56*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %tmp2 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @test_vrev64Qf(<4 x float>* %A) nounwind { 60*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Qf: 61*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32 62*9880d681SAndroid Build Coastguard Worker %tmp1 = load <4 x float>, <4 x float>* %A 63*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 64*9880d681SAndroid Build Coastguard Worker ret <4 x float> %tmp2 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev32D8(<8 x i8>* %A) nounwind { 68*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32D8: 69*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.8 70*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i8>, <8 x i8>* %A 71*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4> 72*9880d681SAndroid Build Coastguard Worker ret <8 x i8> %tmp2 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test_vrev32D16(<4 x i16>* %A) nounwind { 76*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32D16: 77*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16 78*9880d681SAndroid Build Coastguard Worker %tmp1 = load <4 x i16>, <4 x i16>* %A 79*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 80*9880d681SAndroid Build Coastguard Worker ret <4 x i16> %tmp2 81*9880d681SAndroid Build Coastguard Worker} 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev32Q8(<16 x i8>* %A) nounwind { 84*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q8: 85*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.8 86*9880d681SAndroid Build Coastguard Worker %tmp1 = load <16 x i8>, <16 x i8>* %A 87*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12> 88*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %tmp2 89*9880d681SAndroid Build Coastguard Worker} 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev32Q16(<8 x i16>* %A) nounwind { 92*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q16: 93*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16 94*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i16>, <8 x i16>* %A 95*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6> 96*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %tmp2 97*9880d681SAndroid Build Coastguard Worker} 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev16D8(<8 x i8>* %A) nounwind { 100*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev16D8: 101*9880d681SAndroid Build Coastguard Worker;CHECK: vrev16.8 102*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i8>, <8 x i8>* %A 103*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6> 104*9880d681SAndroid Build Coastguard Worker ret <8 x i8> %tmp2 105*9880d681SAndroid Build Coastguard Worker} 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev16Q8(<16 x i8>* %A) nounwind { 108*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev16Q8: 109*9880d681SAndroid Build Coastguard Worker;CHECK: vrev16.8 110*9880d681SAndroid Build Coastguard Worker %tmp1 = load <16 x i8>, <16 x i8>* %A 111*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14> 112*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %tmp2 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; Undef shuffle indices should not prevent matching to VREV: 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev64D8_undef(<8 x i8>* %A) nounwind { 118*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D8_undef: 119*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8 120*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i8>, <8 x i8>* %A 121*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 7, i32 undef, i32 undef, i32 4, i32 3, i32 2, i32 1, i32 0> 122*9880d681SAndroid Build Coastguard Worker ret <8 x i8> %tmp2 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev32Q16_undef(<8 x i16>* %A) nounwind { 126*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q16_undef: 127*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16 128*9880d681SAndroid Build Coastguard Worker %tmp1 = load <8 x i16>, <8 x i16>* %A 129*9880d681SAndroid Build Coastguard Worker %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 undef, i32 0, i32 undef, i32 2, i32 5, i32 4, i32 7, i32 undef> 130*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %tmp2 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; A vcombine feeding a VREV should not obscure things. Radar 8597007. 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Workerdefine void @test_with_vcombine(<4 x float>* %v) nounwind { 136*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_with_vcombine: 137*9880d681SAndroid Build Coastguard Worker;CHECK-NOT: vext 138*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32 139*9880d681SAndroid Build Coastguard Worker %tmp1 = load <4 x float>, <4 x float>* %v, align 16 140*9880d681SAndroid Build Coastguard Worker %tmp2 = bitcast <4 x float> %tmp1 to <2 x double> 141*9880d681SAndroid Build Coastguard Worker %tmp3 = extractelement <2 x double> %tmp2, i32 0 142*9880d681SAndroid Build Coastguard Worker %tmp4 = bitcast double %tmp3 to <2 x float> 143*9880d681SAndroid Build Coastguard Worker %tmp5 = extractelement <2 x double> %tmp2, i32 1 144*9880d681SAndroid Build Coastguard Worker %tmp6 = bitcast double %tmp5 to <2 x float> 145*9880d681SAndroid Build Coastguard Worker %tmp7 = fadd <2 x float> %tmp6, %tmp6 146*9880d681SAndroid Build Coastguard Worker %tmp8 = shufflevector <2 x float> %tmp4, <2 x float> %tmp7, <4 x i32> <i32 1, i32 0, i32 3, i32 2> 147*9880d681SAndroid Build Coastguard Worker store <4 x float> %tmp8, <4 x float>* %v, align 16 148*9880d681SAndroid Build Coastguard Worker ret void 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker; The type <2 x i16> is legalized to <2 x i32> and need to be trunc-stored 152*9880d681SAndroid Build Coastguard Worker; to <2 x i16> when stored to memory. 153*9880d681SAndroid Build Coastguard Workerdefine void @test_vrev64(<4 x i16>* nocapture %source, <2 x i16>* nocapture %dst) nounwind ssp { 154*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_vrev64: 155*9880d681SAndroid Build Coastguard Worker; CHECK: vst1.32 156*9880d681SAndroid Build Coastguard Workerentry: 157*9880d681SAndroid Build Coastguard Worker %0 = bitcast <4 x i16>* %source to <8 x i16>* 158*9880d681SAndroid Build Coastguard Worker %tmp2 = load <8 x i16>, <8 x i16>* %0, align 4 159*9880d681SAndroid Build Coastguard Worker %tmp3 = extractelement <8 x i16> %tmp2, i32 6 160*9880d681SAndroid Build Coastguard Worker %tmp5 = insertelement <2 x i16> undef, i16 %tmp3, i32 0 161*9880d681SAndroid Build Coastguard Worker %tmp9 = extractelement <8 x i16> %tmp2, i32 5 162*9880d681SAndroid Build Coastguard Worker %tmp11 = insertelement <2 x i16> %tmp5, i16 %tmp9, i32 1 163*9880d681SAndroid Build Coastguard Worker store <2 x i16> %tmp11, <2 x i16>* %dst, align 4 164*9880d681SAndroid Build Coastguard Worker ret void 165*9880d681SAndroid Build Coastguard Worker} 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker; Test vrev of float4 168*9880d681SAndroid Build Coastguard Workerdefine void @float_vrev64(float* nocapture %source, <4 x float>* nocapture %dest) nounwind noinline ssp { 169*9880d681SAndroid Build Coastguard Worker; CHECK: float_vrev64 170*9880d681SAndroid Build Coastguard Worker; CHECK: vext.32 171*9880d681SAndroid Build Coastguard Worker; CHECK: vrev64.32 172*9880d681SAndroid Build Coastguard Workerentry: 173*9880d681SAndroid Build Coastguard Worker %0 = bitcast float* %source to <4 x float>* 174*9880d681SAndroid Build Coastguard Worker %tmp2 = load <4 x float>, <4 x float>* %0, align 4 175*9880d681SAndroid Build Coastguard Worker %tmp5 = shufflevector <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <4 x float> %tmp2, <4 x i32> <i32 0, i32 7, i32 0, i32 0> 176*9880d681SAndroid Build Coastguard Worker %arrayidx8 = getelementptr inbounds <4 x float>, <4 x float>* %dest, i32 11 177*9880d681SAndroid Build Coastguard Worker store <4 x float> %tmp5, <4 x float>* %arrayidx8, align 4 178*9880d681SAndroid Build Coastguard Worker ret void 179*9880d681SAndroid Build Coastguard Worker} 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_vrev32_bswap(<4 x i32> %source) nounwind { 182*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_vrev32_bswap: 183*9880d681SAndroid Build Coastguard Worker; CHECK: vrev32.8 184*9880d681SAndroid Build Coastguard Worker %bswap = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %source) 185*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %bswap 186*9880d681SAndroid Build Coastguard Worker} 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Workerdeclare <4 x i32> @llvm.bswap.v4i32(<4 x i32>) nounwind readnone 189