1; RUN: opt -S -slp-vectorizer -slp-threshold=-18 -dce -instcombine -pass-remarks-output=%t < %s | FileCheck %s 2; RUN: cat %t | FileCheck -check-prefix=YAML %s 3; RUN: opt -S -passes='slp-vectorizer,dce,instcombine' -slp-threshold=-18 -pass-remarks-output=%t < %s | FileCheck %s 4; RUN: cat %t | FileCheck -check-prefix=YAML %s 5 6 7target datalayout = "e-m:e-i32:64-i128:128-n32:64-S128" 8target triple = "aarch64--linux-gnu" 9 10; These tests check that we remove from consideration pairs of seed 11; getelementptrs when they are known to have a constant difference. Such pairs 12; are likely not good candidates for vectorization since one can be computed 13; from the other. We use an unprofitable threshold to force vectorization. 14; 15; int getelementptr(int *g, int n, int w, int x, int y, int z) { 16; int sum = 0; 17; for (int i = 0; i < n ; ++i) { 18; sum += g[2*i + w]; sum += g[2*i + x]; 19; sum += g[2*i + y]; sum += g[2*i + z]; 20; } 21; return sum; 22; } 23; 24 25; CHECK-LABEL: @getelementptr_4x32 26; 27; CHECK: [[A:%[a-zA-Z0-9.]+]] = add nsw <4 x i32> 28; CHECK: [[X:%[a-zA-Z0-9.]+]] = extractelement <4 x i32> [[A]] 29; CHECK: sext i32 [[X]] to i64 30 31; YAML: --- !Passed 32; YAML-NEXT: Pass: slp-vectorizer 33; YAML-NEXT: Name: VectorizedList 34; YAML-NEXT: Function: getelementptr_4x32 35; YAML-NEXT: Args: 36; YAML-NEXT: - String: 'SLP vectorized with cost ' 37; YAML-NEXT: - Cost: '11' 38; YAML-NEXT: - String: ' and with tree size ' 39; YAML-NEXT: - TreeSize: '5' 40 41; YAML: --- !Passed 42; YAML-NEXT: Pass: slp-vectorizer 43; YAML-NEXT: Name: VectorizedList 44; YAML-NEXT: Function: getelementptr_4x32 45; YAML-NEXT: Args: 46; YAML-NEXT: - String: 'SLP vectorized with cost ' 47; YAML-NEXT: - Cost: '16' 48; YAML-NEXT: - String: ' and with tree size ' 49; YAML-NEXT: - TreeSize: '3' 50 51define i32 @getelementptr_4x32(i32* nocapture readonly %g, i32 %n, i32 %x, i32 %y, i32 %z) { 52entry: 53 %cmp31 = icmp sgt i32 %n, 0 54 br i1 %cmp31, label %for.body.preheader, label %for.cond.cleanup 55 56for.body.preheader: 57 br label %for.body 58 59for.cond.cleanup.loopexit: 60 br label %for.cond.cleanup 61 62for.cond.cleanup: 63 %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add16, %for.cond.cleanup.loopexit ] 64 ret i32 %sum.0.lcssa 65 66for.body: 67 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 68 %sum.032 = phi i32 [ 0, %for.body.preheader ], [ %add16, %for.body ] 69 %t4 = shl nsw i32 %indvars.iv, 1 70 %t5 = add nsw i32 %t4, 0 71 %arrayidx = getelementptr inbounds i32, i32* %g, i32 %t5 72 %t6 = load i32, i32* %arrayidx, align 4 73 %add1 = add nsw i32 %t6, %sum.032 74 %t7 = add nsw i32 %t4, %x 75 %arrayidx5 = getelementptr inbounds i32, i32* %g, i32 %t7 76 %t8 = load i32, i32* %arrayidx5, align 4 77 %add6 = add nsw i32 %add1, %t8 78 %t9 = add nsw i32 %t4, %y 79 %arrayidx10 = getelementptr inbounds i32, i32* %g, i32 %t9 80 %t10 = load i32, i32* %arrayidx10, align 4 81 %add11 = add nsw i32 %add6, %t10 82 %t11 = add nsw i32 %t4, %z 83 %arrayidx15 = getelementptr inbounds i32, i32* %g, i32 %t11 84 %t12 = load i32, i32* %arrayidx15, align 4 85 %add16 = add nsw i32 %add11, %t12 86 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1 87 %exitcond = icmp eq i32 %indvars.iv.next , %n 88 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body 89} 90 91; CHECK-LABEL: @getelementptr_2x32 92; 93; CHECK: [[A:%[a-zA-Z0-9.]+]] = add nsw <2 x i32> 94; CHECK: [[X:%[a-zA-Z0-9.]+]] = extractelement <2 x i32> [[A]] 95; CHECK: sext i32 [[X]] to i64 96 97; YAML: --- !Passed 98; YAML-NEXT: Pass: slp-vectorizer 99; YAML-NEXT: Name: VectorizedList 100; YAML-NEXT: Function: getelementptr_2x32 101; YAML-NEXT: Args: 102; YAML-NEXT: - String: 'SLP vectorized with cost ' 103; YAML-NEXT: - Cost: '11' 104; YAML-NEXT: - String: ' and with tree size ' 105; YAML-NEXT: - TreeSize: '5' 106 107; YAML: --- !Passed 108; YAML-NEXT: Pass: slp-vectorizer 109; YAML-NEXT: Name: VectorizedList 110; YAML-NEXT: Function: getelementptr_2x32 111; YAML-NEXT: Args: 112; YAML-NEXT: - String: 'SLP vectorized with cost ' 113; YAML-NEXT: - Cost: '6' 114; YAML-NEXT: - String: ' and with tree size ' 115; YAML-NEXT: - TreeSize: '3' 116 117define i32 @getelementptr_2x32(i32* nocapture readonly %g, i32 %n, i32 %x, i32 %y, i32 %z) { 118entry: 119 %cmp31 = icmp sgt i32 %n, 0 120 br i1 %cmp31, label %for.body.preheader, label %for.cond.cleanup 121 122for.body.preheader: 123 br label %for.body 124 125for.cond.cleanup.loopexit: 126 br label %for.cond.cleanup 127 128for.cond.cleanup: 129 %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add16, %for.cond.cleanup.loopexit ] 130 ret i32 %sum.0.lcssa 131 132for.body: 133 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 134 %sum.032 = phi i32 [ 0, %for.body.preheader ], [ %add16, %for.body ] 135 %t4 = shl nsw i32 %indvars.iv, 1 136 %t5 = add nsw i32 %t4, 0 137 %arrayidx = getelementptr inbounds i32, i32* %g, i32 %t5 138 %t6 = load i32, i32* %arrayidx, align 4 139 %add1 = add nsw i32 %t6, %sum.032 140 %t7 = add nsw i32 %t4, 1 141 %arrayidx5 = getelementptr inbounds i32, i32* %g, i32 %t7 142 %t8 = load i32, i32* %arrayidx5, align 4 143 %add6 = add nsw i32 %add1, %t8 144 %t9 = add nsw i32 %t4, %y 145 %arrayidx10 = getelementptr inbounds i32, i32* %g, i32 %t9 146 %t10 = load i32, i32* %arrayidx10, align 4 147 %add11 = add nsw i32 %add6, %t10 148 %t11 = add nsw i32 %t4, %z 149 %arrayidx15 = getelementptr inbounds i32, i32* %g, i32 %t11 150 %t12 = load i32, i32* %arrayidx15, align 4 151 %add16 = add nsw i32 %add11, %t12 152 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1 153 %exitcond = icmp eq i32 %indvars.iv.next , %n 154 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body 155} 156