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