1 ; RUN: opt -loop-reduce -S < %s | FileCheck %s 2 3 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64" 4 target triple = "nvptx64-unknown-unknown" 5 6 ; LSR used not to be able to generate a float* induction variable in 7 ; these cases due to scalar evolution not propagating nsw from an 8 ; instruction to the SCEV, preventing distributing sext into the 9 ; corresponding addrec. 10 11 ; Test this pattern: 12 ; 13 ; for (int i = 0; i < numIterations; ++i) 14 ; sum += ptr[i + offset]; 15 ; 16 define float @testadd(float* %input, i32 %offset, i32 %numIterations) { 17 ; CHECK-LABEL: @testadd 18 ; CHECK: sext i32 %offset to i64 19 ; CHECK: loop: 20 ; CHECK-DAG: phi float* 21 ; CHECK-DAG: phi i32 22 ; CHECK-NOT: sext 23 24 entry: 25 br label %loop 26 27 loop: 28 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 29 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 30 %index32 = add nuw nsw i32 %i, %offset 31 %index64 = sext i32 %index32 to i64 32 %ptr = getelementptr inbounds float, float* %input, i64 %index64 33 %addend = load float, float* %ptr, align 4 34 %nextsum = fadd float %sum, %addend 35 %nexti = add nuw nsw i32 %i, 1 36 %exitcond = icmp eq i32 %nexti, %numIterations 37 br i1 %exitcond, label %exit, label %loop 38 39 exit: 40 ret float %nextsum 41 } 42 43 ; Test this pattern: 44 ; 45 ; for (int i = 0; i < numIterations; ++i) 46 ; sum += ptr[i - offset]; 47 ; 48 define float @testsub(float* %input, i32 %offset, i32 %numIterations) { 49 ; CHECK-LABEL: @testsub 50 ; CHECK: sub i32 0, %offset 51 ; CHECK: sext i32 52 ; CHECK: loop: 53 ; CHECK-DAG: phi float* 54 ; CHECK-DAG: phi i32 55 ; CHECK-NOT: sext 56 57 entry: 58 br label %loop 59 60 loop: 61 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 62 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 63 %index32 = sub nuw nsw i32 %i, %offset 64 %index64 = sext i32 %index32 to i64 65 %ptr = getelementptr inbounds float, float* %input, i64 %index64 66 %addend = load float, float* %ptr, align 4 67 %nextsum = fadd float %sum, %addend 68 %nexti = add nuw nsw i32 %i, 1 69 %exitcond = icmp eq i32 %nexti, %numIterations 70 br i1 %exitcond, label %exit, label %loop 71 72 exit: 73 ret float %nextsum 74 } 75 76 ; Test this pattern: 77 ; 78 ; for (int i = 0; i < numIterations; ++i) 79 ; sum += ptr[i * stride]; 80 ; 81 define float @testmul(float* %input, i32 %stride, i32 %numIterations) { 82 ; CHECK-LABEL: @testmul 83 ; CHECK: sext i32 %stride to i64 84 ; CHECK: loop: 85 ; CHECK-DAG: phi float* 86 ; CHECK-DAG: phi i32 87 ; CHECK-NOT: sext 88 89 entry: 90 br label %loop 91 92 loop: 93 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 94 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 95 %index32 = mul nuw nsw i32 %i, %stride 96 %index64 = sext i32 %index32 to i64 97 %ptr = getelementptr inbounds float, float* %input, i64 %index64 98 %addend = load float, float* %ptr, align 4 99 %nextsum = fadd float %sum, %addend 100 %nexti = add nuw nsw i32 %i, 1 101 %exitcond = icmp eq i32 %nexti, %numIterations 102 br i1 %exitcond, label %exit, label %loop 103 104 exit: 105 ret float %nextsum 106 } 107 108 ; Test this pattern: 109 ; 110 ; for (int i = 0; i < numIterations; ++i) 111 ; sum += ptr[3 * (i << 7)]; 112 ; 113 ; The multiplication by 3 is to make the address calculation expensive 114 ; enough to force the introduction of a pointer induction variable. 115 define float @testshl(float* %input, i32 %numIterations) { 116 ; CHECK-LABEL: @testshl 117 ; CHECK: loop: 118 ; CHECK-DAG: phi float* 119 ; CHECK-DAG: phi i32 120 ; CHECK-NOT: sext 121 122 entry: 123 br label %loop 124 125 loop: 126 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 127 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 128 %index32 = shl nuw nsw i32 %i, 7 129 %index32mul = mul nuw nsw i32 %index32, 3 130 %index64 = sext i32 %index32mul to i64 131 %ptr = getelementptr inbounds float, float* %input, i64 %index64 132 %addend = load float, float* %ptr, align 4 133 %nextsum = fadd float %sum, %addend 134 %nexti = add nuw nsw i32 %i, 1 135 %exitcond = icmp eq i32 %nexti, %numIterations 136 br i1 %exitcond, label %exit, label %loop 137 138 exit: 139 ret float %nextsum 140 } 141