1; RUN: opt -mtriple=x86-linux -load-store-vectorizer -S -o - %s | FileCheck %s 2 3target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" 4 5%struct.buffer_t = type { i64, i8* } 6%struct.nested.buffer = type { %struct.buffer_t, %struct.buffer_t } 7 8; Check an i64 and i8* get vectorized, and that the two accesses 9; (load into buff.val and store to buff.p) preserve their order. 10; Vectorized loads should be inserted at the position of the first load, 11; and instructions which were between the first and last load should be 12; reordered preserving their relative order inasmuch as possible. 13 14; CHECK-LABEL: @preserve_order_64( 15; CHECK: load <2 x i64> 16; CHECK: %buff.val = load i8 17; CHECK: store i8 0 18define void @preserve_order_64(%struct.buffer_t* noalias %buff) #0 { 19entry: 20 %tmp1 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %buff, i64 0, i32 1 21 %buff.p = load i8*, i8** %tmp1, align 8 22 %buff.val = load i8, i8* %buff.p, align 8 23 store i8 0, i8* %buff.p, align 8 24 %tmp0 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %buff, i64 0, i32 0 25 %buff.int = load i64, i64* %tmp0, align 8 26 ret void 27} 28 29; Check reordering recurses correctly. 30 31; CHECK-LABEL: @transitive_reorder( 32; CHECK: load <2 x i64> 33; CHECK: %buff.val = load i8 34; CHECK: store i8 0 35define void @transitive_reorder(%struct.buffer_t* noalias %buff, %struct.nested.buffer* noalias %nest) #0 { 36entry: 37 %nest0_0 = getelementptr inbounds %struct.nested.buffer, %struct.nested.buffer* %nest, i64 0, i32 0 38 %tmp1 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %nest0_0, i64 0, i32 1 39 %buff.p = load i8*, i8** %tmp1, align 8 40 %buff.val = load i8, i8* %buff.p, align 8 41 store i8 0, i8* %buff.p, align 8 42 %nest1_0 = getelementptr inbounds %struct.nested.buffer, %struct.nested.buffer* %nest, i64 0, i32 0 43 %tmp0 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %nest1_0, i64 0, i32 0 44 %buff.int = load i64, i64* %tmp0, align 8 45 ret void 46} 47 48; Check for no vectorization over phi node 49 50; CHECK-LABEL: @no_vect_phi( 51; CHECK: load i8* 52; CHECK: load i8 53; CHECK: store i8 0 54; CHECK: load i64 55define void @no_vect_phi(i32* noalias %ptr, %struct.buffer_t* noalias %buff) { 56entry: 57 %tmp1 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %buff, i64 0, i32 1 58 %buff.p = load i8*, i8** %tmp1, align 8 59 %buff.val = load i8, i8* %buff.p, align 8 60 store i8 0, i8* %buff.p, align 8 61 br label %"for something" 62 63"for something": 64 %index = phi i64 [ 0, %entry ], [ %index.next, %"for something" ] 65 66 %tmp0 = getelementptr inbounds %struct.buffer_t, %struct.buffer_t* %buff, i64 0, i32 0 67 %buff.int = load i64, i64* %tmp0, align 8 68 69 %index.next = add i64 %index, 8 70 %cmp_res = icmp eq i64 %index.next, 8 71 br i1 %cmp_res, label %ending, label %"for something" 72 73ending: 74 ret void 75} 76 77attributes #0 = { nounwind } 78