1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s 3 4; InferAlignment should be able to prove vector alignment in the 5; presence of a few mild address computation tricks. 6 7; ------------------------------------------------------------------------------ 8; alloca 9; ------------------------------------------------------------------------------ 10 11define void @alloca(<2 x i64> %y) { 12; CHECK-LABEL: define void @alloca 13; CHECK-SAME: (<2 x i64> [[Y:%.*]]) { 14; CHECK-NEXT: [[ALLOCA:%.*]] = alloca <2 x i64>, align 16 15; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i64>, ptr [[ALLOCA]], align 16 16; CHECK-NEXT: store <2 x i64> [[Y]], ptr [[ALLOCA]], align 16 17; CHECK-NEXT: ret void 18; 19 %alloca = alloca <2 x i64> 20 %load = load <2 x i64>, ptr %alloca, align 1 21 store <2 x i64> %y, ptr %alloca, align 1 22 ret void 23} 24 25; ------------------------------------------------------------------------------ 26; global 27; ------------------------------------------------------------------------------ 28 29@x.vector = external global <2 x i64>, align 16 30 31define void @global(<2 x i64> %y) { 32; CHECK-LABEL: define void @global 33; CHECK-SAME: (<2 x i64> [[Y:%.*]]) { 34; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i64>, ptr @x.vector, align 16 35; CHECK-NEXT: store <2 x i64> [[Y]], ptr @x.vector, align 16 36; CHECK-NEXT: ret void 37; 38 %load = load <2 x i64>, ptr @x.vector, align 1 39 store <2 x i64> %y, ptr @x.vector, align 1 40 ret void 41} 42 43; ------------------------------------------------------------------------------ 44; getelementptr 45; ------------------------------------------------------------------------------ 46 47@vector = external global <2 x i64>, align 16 48@vector.arr = external global [13 x <2 x i64>], align 16 49 50; ------------------------------------------------------------------------------ 51; 1d access 52; ------------------------------------------------------------------------------ 53 54define void @vector_singular(i32 %i, <2 x i64> %y) { 55; CHECK-LABEL: define void @vector_singular 56; CHECK-SAME: (i32 [[I:%.*]], <2 x i64> [[Y:%.*]]) { 57; CHECK-NEXT: [[GEP:%.*]] = getelementptr <2 x i64>, ptr @vector, i32 [[I]] 58; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i64>, ptr [[GEP]], align 16 59; CHECK-NEXT: store <2 x i64> [[Y]], ptr [[GEP]], align 16 60; CHECK-NEXT: ret void 61; 62 %gep = getelementptr <2 x i64>, ptr @vector, i32 %i 63 %load = load <2 x i64>, ptr %gep, align 1 64 store <2 x i64> %y, ptr %gep, align 1 65 ret void 66} 67 68; ------------------------------------------------------------------------------ 69; 2d access 70; ------------------------------------------------------------------------------ 71 72define void @vector_array(i32 %i, i32 %j, <2 x i64> %y) { 73; CHECK-LABEL: define void @vector_array 74; CHECK-SAME: (i32 [[I:%.*]], i32 [[J:%.*]], <2 x i64> [[Y:%.*]]) { 75; CHECK-NEXT: [[GEP:%.*]] = getelementptr [13 x <2 x i64>], ptr @vector.arr, i32 [[I]], i32 [[J]] 76; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i64>, ptr [[GEP]], align 16 77; CHECK-NEXT: store <2 x i64> [[Y]], ptr [[GEP]], align 16 78; CHECK-NEXT: ret void 79; 80 %gep = getelementptr [13 x <2 x i64>], ptr @vector.arr, i32 %i, i32 %j 81 %load = load <2 x i64>, ptr %gep, align 1 82 store <2 x i64> %y, ptr %gep, align 1 83 ret void 84} 85 86; ------------------------------------------------------------------------------ 87; non-vector array type 88; ------------------------------------------------------------------------------ 89 90; When we see a unaligned load or store from an insufficiently aligned global or 91; alloca, increase the alignment, turning it into an aligned load or store. 92@x.array = internal global [4 x i32] zeroinitializer 93 94define void @nonvector_array() { 95; CHECK-LABEL: define void @nonvector_array() { 96; CHECK-NEXT: [[LOAD_0:%.*]] = load <16 x i8>, ptr @x.array, align 16 97; CHECK-NEXT: store <16 x i8> zeroinitializer, ptr @x.array, align 16 98; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i32], ptr @x.array, i16 0, i16 2 99; CHECK-NEXT: [[LOAD_1:%.*]] = load <16 x i8>, ptr [[GEP]], align 8 100; CHECK-NEXT: store <16 x i8> zeroinitializer, ptr [[GEP]], align 8 101; CHECK-NEXT: ret void 102; 103 %load.0 = load <16 x i8>, ptr @x.array, align 1 104 store <16 x i8> zeroinitializer, ptr @x.array, align 1 105 106 %gep = getelementptr [4 x i32], ptr @x.array, i16 0, i16 2 107 %load.1 = load <16 x i8>, ptr %gep, align 1 108 store <16 x i8> zeroinitializer, ptr %gep, align 1 109 110 ret void 111} 112