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