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