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: sext i32 %offset to i64 51 ; CHECK: loop: 52 ; CHECK-DAG: phi float* 53 ; CHECK-DAG: phi i32 54 ; CHECK-NOT: sext 55 56 entry: 57 br label %loop 58 59 loop: 60 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 61 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 62 %index32 = sub nuw nsw i32 %i, %offset 63 %index64 = sext i32 %index32 to i64 64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 65 %addend = load float, float* %ptr, align 4 66 %nextsum = fadd float %sum, %addend 67 %nexti = add nuw nsw i32 %i, 1 68 %exitcond = icmp eq i32 %nexti, %numIterations 69 br i1 %exitcond, label %exit, label %loop 70 71 exit: 72 ret float %nextsum 73 } 74 75 ; Test this pattern: 76 ; 77 ; for (int i = 0; i < numIterations; ++i) 78 ; sum += ptr[i * stride]; 79 ; 80 define float @testmul(float* %input, i32 %stride, i32 %numIterations) { 81 ; CHECK-LABEL: @testmul 82 ; CHECK: sext i32 %stride to i64 83 ; CHECK: loop: 84 ; CHECK-DAG: phi float* 85 ; CHECK-DAG: phi i32 86 ; CHECK-NOT: sext 87 88 entry: 89 br label %loop 90 91 loop: 92 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 93 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 94 %index32 = mul nuw nsw i32 %i, %stride 95 %index64 = sext i32 %index32 to i64 96 %ptr = getelementptr inbounds float, float* %input, i64 %index64 97 %addend = load float, float* %ptr, align 4 98 %nextsum = fadd float %sum, %addend 99 %nexti = add nuw nsw i32 %i, 1 100 %exitcond = icmp eq i32 %nexti, %numIterations 101 br i1 %exitcond, label %exit, label %loop 102 103 exit: 104 ret float %nextsum 105 } 106 107 ; Test this pattern: 108 ; 109 ; for (int i = 0; i < numIterations; ++i) 110 ; sum += ptr[3 * (i << 7)]; 111 ; 112 ; The multiplication by 3 is to make the address calculation expensive 113 ; enough to force the introduction of a pointer induction variable. 114 define float @testshl(float* %input, i32 %numIterations) { 115 ; CHECK-LABEL: @testshl 116 ; CHECK: loop: 117 ; CHECK-DAG: phi float* 118 ; CHECK-DAG: phi i32 119 ; CHECK-NOT: sext 120 121 entry: 122 br label %loop 123 124 loop: 125 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 126 %sum = phi float [ %nextsum, %loop ], [ 0.000000e+00, %entry ] 127 %index32 = shl nuw nsw i32 %i, 7 128 %index32mul = mul nuw nsw i32 %index32, 3 129 %index64 = sext i32 %index32mul to i64 130 %ptr = getelementptr inbounds float, float* %input, i64 %index64 131 %addend = load float, float* %ptr, align 4 132 %nextsum = fadd float %sum, %addend 133 %nexti = add nuw nsw i32 %i, 1 134 %exitcond = icmp eq i32 %nexti, %numIterations 135 br i1 %exitcond, label %exit, label %loop 136 137 exit: 138 ret float %nextsum 139 } 140