1; RUN: opt < %s -mattr=+neon -interleaved-access -S | FileCheck %s 2 3target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64" 4target triple = "arm---eabi" 5 6define void @extract_user_basic(<8 x i32>* %ptr, i1 %c) { 7; CHECK-LABEL: @extract_user_basic( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i32>* %ptr to i8* 10; CHECK-NEXT: [[VLDN:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8(i8* [[TMP0]], i32 8) 11; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[VLDN]], 0 12; CHECK-NEXT: br i1 %c, label %if.then, label %if.merge 13; CHECK: if.then: 14; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[TMP1]], i64 1 15; CHECK-NEXT: br label %if.merge 16; CHECK: if.merge: 17; CHECK-NEXT: ret void 18; 19entry: 20 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 21 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 22 br i1 %c, label %if.then, label %if.merge 23 24if.then: 25 %e0 = extractelement <8 x i32> %interleaved.vec, i32 2 26 br label %if.merge 27 28if.merge: 29 ret void 30} 31 32define void @extract_user_multi(<8 x i32>* %ptr, i1 %c) { 33; CHECK-LABEL: @extract_user_multi( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i32>* %ptr to i8* 36; CHECK-NEXT: [[VLDN:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8(i8* [[TMP0]], i32 8) 37; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[VLDN]], 0 38; CHECK-NEXT: br i1 %c, label %if.then, label %if.merge 39; CHECK: if.then: 40; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[TMP1]], i64 0 41; CHECK-NEXT: br label %if.merge 42; CHECK: if.merge: 43; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[TMP1]], i64 1 44; CHECK-NEXT: ret void 45; 46entry: 47 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 48 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 49 br i1 %c, label %if.then, label %if.merge 50 51if.then: 52 %e0 = extractelement <8 x i32> %interleaved.vec, i32 0 53 br label %if.merge 54 55if.merge: 56 %e1 = extractelement <8 x i32> %interleaved.vec, i32 2 57 ret void 58} 59 60define void @extract_user_multi_no_dom(<8 x i32>* %ptr, i1 %c) { 61; CHECK-LABEL: @extract_user_multi_no_dom( 62; CHECK-NOT: @llvm.arm.neon 63; CHECK: ret void 64; 65entry: 66 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 67 %e0 = extractelement <8 x i32> %interleaved.vec, i32 0 68 br i1 %c, label %if.then, label %if.merge 69 70if.then: 71 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 72 %e1 = extractelement <8 x i32> %interleaved.vec, i32 2 73 br label %if.merge 74 75if.merge: 76 ret void 77} 78 79define void @extract_user_wrong_const_index(<8 x i32>* %ptr) { 80; CHECK-LABEL: @extract_user_wrong_const_index( 81; CHECK-NOT: @llvm.arm.neon 82; CHECK: ret void 83; 84entry: 85 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 86 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 87 %e0 = extractelement <8 x i32> %interleaved.vec, i32 1 88 ret void 89} 90 91define void @extract_user_undef_index(<8 x i32>* %ptr) { 92; CHECK-LABEL: @extract_user_undef_index( 93; CHECK-NOT: @llvm.arm.neon 94; CHECK: ret void 95; 96entry: 97 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 98 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 99 %e0 = extractelement <8 x i32> %interleaved.vec, i32 undef 100 ret void 101} 102 103define void @extract_user_var_index(<8 x i32>* %ptr, i32 %i) { 104; CHECK-LABEL: @extract_user_var_index( 105; CHECK-NOT: @llvm.arm.neon 106; CHECK: ret void 107; 108entry: 109 %interleaved.vec = load <8 x i32>, <8 x i32>* %ptr, align 8 110 %v0 = shufflevector <8 x i32> %interleaved.vec, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> 111 %e0 = extractelement <8 x i32> %interleaved.vec, i32 %i 112 ret void 113} 114