After successfull horizontal reduction vectorization attempt for PHI node vectorizer tries to update root binary op by combining vectorized tree and the ReductionPHI node. But during vectorization this ReductionPHI can be vectorized itself and replaced by the `undef` value, while the instruction itself is marked for deletion. This 'marked for deletion' PHI node then can be used in new binary operation, causing "Use still stuck around after Def is destroyed" crash upon PHI node deletion. Also the test is fixed to make it perform actual testing. Differential Revision: https://reviews.llvm.org/D25671 llvm-svn: 285286
513 lines
18 KiB
LLVM
513 lines
18 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -slp-vectorizer -S < %s -mtriple=x86_64-apple-macosx -mcpu=corei7-avx | FileCheck %s
|
|
|
|
; #include <stdint.h>
|
|
;
|
|
; int foo(float *A, int n) {
|
|
; float sum = 0;
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; sum += 7*A[i*4 ] +
|
|
; 7*A[i*4+1] +
|
|
; 7*A[i*4+2] +
|
|
; 7*A[i*4+3];
|
|
; }
|
|
; return sum;
|
|
; }
|
|
|
|
; CHECK-LABEL: add_red
|
|
; CHECK: fmul <4 x float>
|
|
; CHECK: shufflevector <4 x float>
|
|
|
|
define i32 @add_red(float* %A, i32 %n) {
|
|
entry:
|
|
%cmp31 = icmp sgt i32 %n, 0
|
|
br i1 %cmp31, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%0 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.033 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%sum.032 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add17, %for.body ]
|
|
%mul = shl nsw i64 %i.033, 2
|
|
%arrayidx = getelementptr inbounds float, float* %A, i64 %mul
|
|
%1 = load float, float* %arrayidx, align 4
|
|
%mul2 = fmul float %1, 7.000000e+00
|
|
%add28 = or i64 %mul, 1
|
|
%arrayidx4 = getelementptr inbounds float, float* %A, i64 %add28
|
|
%2 = load float, float* %arrayidx4, align 4
|
|
%mul5 = fmul float %2, 7.000000e+00
|
|
%add6 = fadd fast float %mul2, %mul5
|
|
%add829 = or i64 %mul, 2
|
|
%arrayidx9 = getelementptr inbounds float, float* %A, i64 %add829
|
|
%3 = load float, float* %arrayidx9, align 4
|
|
%mul10 = fmul float %3, 7.000000e+00
|
|
%add11 = fadd fast float %add6, %mul10
|
|
%add1330 = or i64 %mul, 3
|
|
%arrayidx14 = getelementptr inbounds float, float* %A, i64 %add1330
|
|
%4 = load float, float* %arrayidx14, align 4
|
|
%mul15 = fmul float %4, 7.000000e+00
|
|
%add16 = fadd fast float %add11, %mul15
|
|
%add17 = fadd fast float %sum.032, %add16
|
|
%inc = add nsw i64 %i.033, 1
|
|
%exitcond = icmp eq i64 %inc, %0
|
|
br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body
|
|
|
|
for.cond.for.end_crit_edge:
|
|
%phitmp = fptosi float %add17 to i32
|
|
br label %for.end
|
|
|
|
for.end:
|
|
%sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]
|
|
ret i32 %sum.0.lcssa
|
|
}
|
|
|
|
; int foo(float * restrict A, float * restrict B, int n) {
|
|
; float sum = 0;
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; sum *= B[0]*A[i*4 ] +
|
|
; B[1]*A[i*4+1] +
|
|
; B[2]*A[i*4+2] +
|
|
; B[3]*A[i*4+3];
|
|
; }
|
|
; return sum;
|
|
; }
|
|
|
|
; CHECK-LABEL: mul_red
|
|
; CHECK: fmul <4 x float>
|
|
; CHECK: shufflevector <4 x float>
|
|
|
|
define i32 @mul_red(float* noalias %A, float* noalias %B, i32 %n) {
|
|
entry:
|
|
%cmp38 = icmp sgt i32 %n, 0
|
|
br i1 %cmp38, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%0 = load float, float* %B, align 4
|
|
%arrayidx4 = getelementptr inbounds float, float* %B, i64 1
|
|
%1 = load float, float* %arrayidx4, align 4
|
|
%arrayidx9 = getelementptr inbounds float, float* %B, i64 2
|
|
%2 = load float, float* %arrayidx9, align 4
|
|
%arrayidx15 = getelementptr inbounds float, float* %B, i64 3
|
|
%3 = load float, float* %arrayidx15, align 4
|
|
%4 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.040 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%sum.039 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %mul21, %for.body ]
|
|
%mul = shl nsw i64 %i.040, 2
|
|
%arrayidx2 = getelementptr inbounds float, float* %A, i64 %mul
|
|
%5 = load float, float* %arrayidx2, align 4
|
|
%mul3 = fmul float %0, %5
|
|
%add35 = or i64 %mul, 1
|
|
%arrayidx6 = getelementptr inbounds float, float* %A, i64 %add35
|
|
%6 = load float, float* %arrayidx6, align 4
|
|
%mul7 = fmul float %1, %6
|
|
%add8 = fadd fast float %mul3, %mul7
|
|
%add1136 = or i64 %mul, 2
|
|
%arrayidx12 = getelementptr inbounds float, float* %A, i64 %add1136
|
|
%7 = load float, float* %arrayidx12, align 4
|
|
%mul13 = fmul float %2, %7
|
|
%add14 = fadd fast float %add8, %mul13
|
|
%add1737 = or i64 %mul, 3
|
|
%arrayidx18 = getelementptr inbounds float, float* %A, i64 %add1737
|
|
%8 = load float, float* %arrayidx18, align 4
|
|
%mul19 = fmul float %3, %8
|
|
%add20 = fadd fast float %add14, %mul19
|
|
%mul21 = fmul float %sum.039, %add20
|
|
%inc = add nsw i64 %i.040, 1
|
|
%exitcond = icmp eq i64 %inc, %4
|
|
br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body
|
|
|
|
for.cond.for.end_crit_edge:
|
|
%phitmp = fptosi float %mul21 to i32
|
|
br label %for.end
|
|
|
|
for.end:
|
|
%sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]
|
|
ret i32 %sum.0.lcssa
|
|
}
|
|
|
|
; int foo(float * restrict A, float * restrict B, int n) {
|
|
; float sum = 0;
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; sum += B[0]*A[i*6 ] +
|
|
; B[1]*A[i*6+1] +
|
|
; B[2]*A[i*6+2] +
|
|
; B[3]*A[i*6+3] +
|
|
; B[4]*A[i*6+4] +
|
|
; B[5]*A[i*6+5] +
|
|
; B[6]*A[i*6+6] +
|
|
; B[7]*A[i*6+7] +
|
|
; B[8]*A[i*6+8];
|
|
; }
|
|
; return sum;
|
|
; }
|
|
|
|
; CHECK-LABEL: long_red
|
|
; CHECK: fmul fast <8 x float>
|
|
; CHECK: shufflevector <8 x float>
|
|
|
|
define i32 @long_red(float* noalias %A, float* noalias %B, i32 %n) {
|
|
entry:
|
|
%cmp81 = icmp sgt i32 %n, 0
|
|
br i1 %cmp81, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%0 = load float, float* %B, align 4
|
|
%arrayidx4 = getelementptr inbounds float, float* %B, i64 1
|
|
%1 = load float, float* %arrayidx4, align 4
|
|
%arrayidx9 = getelementptr inbounds float, float* %B, i64 2
|
|
%2 = load float, float* %arrayidx9, align 4
|
|
%arrayidx15 = getelementptr inbounds float, float* %B, i64 3
|
|
%3 = load float, float* %arrayidx15, align 4
|
|
%arrayidx21 = getelementptr inbounds float, float* %B, i64 4
|
|
%4 = load float, float* %arrayidx21, align 4
|
|
%arrayidx27 = getelementptr inbounds float, float* %B, i64 5
|
|
%5 = load float, float* %arrayidx27, align 4
|
|
%arrayidx33 = getelementptr inbounds float, float* %B, i64 6
|
|
%6 = load float, float* %arrayidx33, align 4
|
|
%arrayidx39 = getelementptr inbounds float, float* %B, i64 7
|
|
%7 = load float, float* %arrayidx39, align 4
|
|
%arrayidx45 = getelementptr inbounds float, float* %B, i64 8
|
|
%8 = load float, float* %arrayidx45, align 4
|
|
%9 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.083 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%sum.082 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add51, %for.body ]
|
|
%mul = mul nsw i64 %i.083, 6
|
|
%arrayidx2 = getelementptr inbounds float, float* %A, i64 %mul
|
|
%10 = load float, float* %arrayidx2, align 4
|
|
%mul3 = fmul fast float %0, %10
|
|
%add80 = or i64 %mul, 1
|
|
%arrayidx6 = getelementptr inbounds float, float* %A, i64 %add80
|
|
%11 = load float, float* %arrayidx6, align 4
|
|
%mul7 = fmul fast float %1, %11
|
|
%add8 = fadd fast float %mul3, %mul7
|
|
%add11 = add nsw i64 %mul, 2
|
|
%arrayidx12 = getelementptr inbounds float, float* %A, i64 %add11
|
|
%12 = load float, float* %arrayidx12, align 4
|
|
%mul13 = fmul fast float %2, %12
|
|
%add14 = fadd fast float %add8, %mul13
|
|
%add17 = add nsw i64 %mul, 3
|
|
%arrayidx18 = getelementptr inbounds float, float* %A, i64 %add17
|
|
%13 = load float, float* %arrayidx18, align 4
|
|
%mul19 = fmul fast float %3, %13
|
|
%add20 = fadd fast float %add14, %mul19
|
|
%add23 = add nsw i64 %mul, 4
|
|
%arrayidx24 = getelementptr inbounds float, float* %A, i64 %add23
|
|
%14 = load float, float* %arrayidx24, align 4
|
|
%mul25 = fmul fast float %4, %14
|
|
%add26 = fadd fast float %add20, %mul25
|
|
%add29 = add nsw i64 %mul, 5
|
|
%arrayidx30 = getelementptr inbounds float, float* %A, i64 %add29
|
|
%15 = load float, float* %arrayidx30, align 4
|
|
%mul31 = fmul fast float %5, %15
|
|
%add32 = fadd fast float %add26, %mul31
|
|
%add35 = add nsw i64 %mul, 6
|
|
%arrayidx36 = getelementptr inbounds float, float* %A, i64 %add35
|
|
%16 = load float, float* %arrayidx36, align 4
|
|
%mul37 = fmul fast float %6, %16
|
|
%add38 = fadd fast float %add32, %mul37
|
|
%add41 = add nsw i64 %mul, 7
|
|
%arrayidx42 = getelementptr inbounds float, float* %A, i64 %add41
|
|
%17 = load float, float* %arrayidx42, align 4
|
|
%mul43 = fmul fast float %7, %17
|
|
%add44 = fadd fast float %add38, %mul43
|
|
%add47 = add nsw i64 %mul, 8
|
|
%arrayidx48 = getelementptr inbounds float, float* %A, i64 %add47
|
|
%18 = load float, float* %arrayidx48, align 4
|
|
%mul49 = fmul fast float %8, %18
|
|
%add50 = fadd fast float %add44, %mul49
|
|
%add51 = fadd fast float %sum.082, %add50
|
|
%inc = add nsw i64 %i.083, 1
|
|
%exitcond = icmp eq i64 %inc, %9
|
|
br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body
|
|
|
|
for.cond.for.end_crit_edge:
|
|
%phitmp = fptosi float %add51 to i32
|
|
br label %for.end
|
|
|
|
for.end:
|
|
%sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]
|
|
ret i32 %sum.0.lcssa
|
|
}
|
|
|
|
; int foo(float * restrict A, float * restrict B, int n) {
|
|
; float sum = 0;
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; sum += B[0]*A[i*4 ];
|
|
; sum += B[1]*A[i*4+1];
|
|
; sum += B[2]*A[i*4+2];
|
|
; sum += B[3]*A[i*4+3];
|
|
; }
|
|
; return sum;
|
|
; }
|
|
|
|
; CHECK-LABEL: chain_red
|
|
; CHECK: fmul fast <4 x float>
|
|
; CHECK: shufflevector <4 x float>
|
|
|
|
define i32 @chain_red(float* noalias %A, float* noalias %B, i32 %n) {
|
|
entry:
|
|
%cmp41 = icmp sgt i32 %n, 0
|
|
br i1 %cmp41, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%0 = load float, float* %B, align 4
|
|
%arrayidx4 = getelementptr inbounds float, float* %B, i64 1
|
|
%1 = load float, float* %arrayidx4, align 4
|
|
%arrayidx10 = getelementptr inbounds float, float* %B, i64 2
|
|
%2 = load float, float* %arrayidx10, align 4
|
|
%arrayidx16 = getelementptr inbounds float, float* %B, i64 3
|
|
%3 = load float, float* %arrayidx16, align 4
|
|
%4 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.043 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%sum.042 = phi float [ 0.000000e+00, %for.body.lr.ph ], [ %add21, %for.body ]
|
|
%mul = shl nsw i64 %i.043, 2
|
|
%arrayidx2 = getelementptr inbounds float, float* %A, i64 %mul
|
|
%5 = load float, float* %arrayidx2, align 4
|
|
%mul3 = fmul fast float %0, %5
|
|
%add = fadd fast float %sum.042, %mul3
|
|
%add638 = or i64 %mul, 1
|
|
%arrayidx7 = getelementptr inbounds float, float* %A, i64 %add638
|
|
%6 = load float, float* %arrayidx7, align 4
|
|
%mul8 = fmul fast float %1, %6
|
|
%add9 = fadd fast float %add, %mul8
|
|
%add1239 = or i64 %mul, 2
|
|
%arrayidx13 = getelementptr inbounds float, float* %A, i64 %add1239
|
|
%7 = load float, float* %arrayidx13, align 4
|
|
%mul14 = fmul fast float %2, %7
|
|
%add15 = fadd fast float %add9, %mul14
|
|
%add1840 = or i64 %mul, 3
|
|
%arrayidx19 = getelementptr inbounds float, float* %A, i64 %add1840
|
|
%8 = load float, float* %arrayidx19, align 4
|
|
%mul20 = fmul fast float %3, %8
|
|
%add21 = fadd fast float %add15, %mul20
|
|
%inc = add nsw i64 %i.043, 1
|
|
%exitcond = icmp eq i64 %inc, %4
|
|
br i1 %exitcond, label %for.cond.for.end_crit_edge, label %for.body
|
|
|
|
for.cond.for.end_crit_edge:
|
|
%phitmp = fptosi float %add21 to i32
|
|
br label %for.end
|
|
|
|
for.end:
|
|
%sum.0.lcssa = phi i32 [ %phitmp, %for.cond.for.end_crit_edge ], [ 0, %entry ]
|
|
ret i32 %sum.0.lcssa
|
|
}
|
|
|
|
; void foo(const float *arg_A, unsigned arg_B, float *array) {
|
|
; for (uint32_t i = 0; i < 6; ++i) {
|
|
; const float *ptr = arg_A + i;
|
|
; float w0 = array[i * 4 + 0];
|
|
; float w1 = array[i * 4 + 1];
|
|
; float w2 = array[i * 4 + 2];
|
|
; float w3 = array[i * 4 + 3];
|
|
;
|
|
; for (unsigned j = 0; j < arg_B; ++j) {
|
|
; const float x1 = *ptr - (-1.1f * w0) - (1.2f * w1);
|
|
; const float x2 = (2.1f * x1) + (-2.2f * w0) + (2.3f * w1);
|
|
; const float x3 = x2 - (-3.1f * w2) - (3.2f * w3);
|
|
; const float x4 = x3 + (-4.0f * w2) + w3;
|
|
; w1 = w0;
|
|
; w0 = x1;
|
|
; w3 = w2;
|
|
; w2 = x3;
|
|
; }
|
|
;
|
|
; array[i * 4 + 0] = w0;
|
|
; array[i * 4 + 1] = w1;
|
|
; array[i * 4 + 2] = w2;
|
|
; array[i * 4 + 3] = w3;
|
|
; }
|
|
; }
|
|
|
|
define void @foo(float* nocapture readonly %arg_A, i32 %arg_B, float* nocapture %array) {
|
|
; CHECK-LABEL: @foo(
|
|
; CHECK: fmul fast <4 x float>
|
|
; CHECK: shufflevector <4 x float>
|
|
;
|
|
entry:
|
|
%cmp1495 = icmp eq i32 %arg_B, 0
|
|
br label %for.body
|
|
|
|
for.cond.cleanup: ; preds = %for.cond.cleanup15
|
|
ret void
|
|
|
|
for.body: ; preds = %for.cond.cleanup15, %entry
|
|
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.cond.cleanup15 ]
|
|
%0 = shl i64 %indvars.iv, 2
|
|
%arrayidx = getelementptr inbounds float, float* %array, i64 %0
|
|
%1 = load float, float* %arrayidx, align 4
|
|
%2 = or i64 %0, 1
|
|
%arrayidx4 = getelementptr inbounds float, float* %array, i64 %2
|
|
%3 = load float, float* %arrayidx4, align 4
|
|
%4 = or i64 %0, 2
|
|
%arrayidx8 = getelementptr inbounds float, float* %array, i64 %4
|
|
%5 = load float, float* %arrayidx8, align 4
|
|
%6 = or i64 %0, 3
|
|
%arrayidx12 = getelementptr inbounds float, float* %array, i64 %6
|
|
%7 = load float, float* %arrayidx12, align 4
|
|
br i1 %cmp1495, label %for.cond.cleanup15, label %for.body16.lr.ph
|
|
|
|
for.body16.lr.ph: ; preds = %for.body
|
|
%add.ptr = getelementptr inbounds float, float* %arg_A, i64 %indvars.iv
|
|
%8 = load float, float* %add.ptr, align 4
|
|
br label %for.body16
|
|
|
|
for.cond.cleanup15: ; preds = %for.body16, %for.body
|
|
%w2.0.lcssa = phi float [ %5, %for.body ], [ %sub28, %for.body16 ]
|
|
%w3.0.lcssa = phi float [ %7, %for.body ], [ %w2.096, %for.body16 ]
|
|
%w1.0.lcssa = phi float [ %3, %for.body ], [ %w0.0100, %for.body16 ]
|
|
%w0.0.lcssa = phi float [ %1, %for.body ], [ %sub19, %for.body16 ]
|
|
store float %w0.0.lcssa, float* %arrayidx, align 4
|
|
store float %w1.0.lcssa, float* %arrayidx4, align 4
|
|
store float %w2.0.lcssa, float* %arrayidx8, align 4
|
|
store float %w3.0.lcssa, float* %arrayidx12, align 4
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond109 = icmp eq i64 %indvars.iv.next, 6
|
|
br i1 %exitcond109, label %for.cond.cleanup, label %for.body
|
|
|
|
for.body16: ; preds = %for.body16, %for.body16.lr.ph
|
|
%w0.0100 = phi float [ %1, %for.body16.lr.ph ], [ %sub19, %for.body16 ]
|
|
%w1.099 = phi float [ %3, %for.body16.lr.ph ], [ %w0.0100, %for.body16 ]
|
|
%j.098 = phi i32 [ 0, %for.body16.lr.ph ], [ %inc, %for.body16 ]
|
|
%w3.097 = phi float [ %7, %for.body16.lr.ph ], [ %w2.096, %for.body16 ]
|
|
%w2.096 = phi float [ %5, %for.body16.lr.ph ], [ %sub28, %for.body16 ]
|
|
%mul17 = fmul fast float %w0.0100, 0x3FF19999A0000000
|
|
%mul18.neg = fmul fast float %w1.099, 0xBFF3333340000000
|
|
%sub92 = fadd fast float %mul17, %mul18.neg
|
|
%sub19 = fadd fast float %sub92, %8
|
|
%mul20 = fmul fast float %sub19, 0x4000CCCCC0000000
|
|
%mul21.neg = fmul fast float %w0.0100, 0xC0019999A0000000
|
|
%mul23 = fmul fast float %w1.099, 0x4002666660000000
|
|
%mul25 = fmul fast float %w2.096, 0x4008CCCCC0000000
|
|
%mul27.neg = fmul fast float %w3.097, 0xC0099999A0000000
|
|
%add2293 = fadd fast float %mul27.neg, %mul25
|
|
%add24 = fadd fast float %add2293, %mul23
|
|
%sub2694 = fadd fast float %add24, %mul21.neg
|
|
%sub28 = fadd fast float %sub2694, %mul20
|
|
%inc = add nuw i32 %j.098, 1
|
|
%exitcond = icmp eq i32 %inc, %arg_B
|
|
br i1 %exitcond, label %for.cond.cleanup15, label %for.body16
|
|
}
|
|
|
|
; RUN: opt -slp-vectorizer -slp-vectorize-hor -slp-vectorize-hor-store -S < %s -mtriple=x86_64-apple-macosx -mcpu=corei7-avx | FileCheck %s --check-prefix=STORE
|
|
|
|
; void foo(double * restrict A, double * restrict B, double * restrict C,
|
|
; int n) {
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; C[i] = B[0] *A[i*4 ] + B[1] *A[i*4+1];
|
|
; }
|
|
; }
|
|
|
|
; STORE-LABEL: store_red_double
|
|
; STORE: fmul fast <2 x double>
|
|
; STORE: extractelement <2 x double>
|
|
; STORE: extractelement <2 x double>
|
|
|
|
define void @store_red_double(double* noalias %A, double* noalias %B, double* noalias %C, i32 %n) {
|
|
entry:
|
|
%cmp17 = icmp sgt i32 %n, 0
|
|
br i1 %cmp17, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%0 = load double, double* %B, align 8
|
|
%arrayidx4 = getelementptr inbounds double, double* %B, i64 1
|
|
%1 = load double, double* %arrayidx4, align 8
|
|
%2 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.018 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%mul = shl nsw i64 %i.018, 2
|
|
%arrayidx2 = getelementptr inbounds double, double* %A, i64 %mul
|
|
%3 = load double, double* %arrayidx2, align 8
|
|
%mul3 = fmul fast double %0, %3
|
|
%add16 = or i64 %mul, 1
|
|
%arrayidx6 = getelementptr inbounds double, double* %A, i64 %add16
|
|
%4 = load double, double* %arrayidx6, align 8
|
|
%mul7 = fmul fast double %1, %4
|
|
%add8 = fadd fast double %mul3, %mul7
|
|
%arrayidx9 = getelementptr inbounds double, double* %C, i64 %i.018
|
|
store double %add8, double* %arrayidx9, align 8
|
|
%inc = add nsw i64 %i.018, 1
|
|
%exitcond = icmp eq i64 %inc, %2
|
|
br i1 %exitcond, label %for.end, label %for.body
|
|
|
|
for.end:
|
|
ret void
|
|
}
|
|
|
|
; int foo(float * restrict A, float * restrict B, float * restrict C, int n) {
|
|
; float sum = 0;
|
|
; for (intptr_t i=0; i < n; ++i) {
|
|
; C[i] = B[0] *A[i*4 ] +
|
|
; B[1] *A[i*4+1] +
|
|
; B[2] *A[i*4+2] +
|
|
; B[3] *A[i*4+3];
|
|
; }
|
|
; return sum;
|
|
; }
|
|
|
|
; STORE-LABEL: store_red
|
|
; STORE: fmul fast <4 x float>
|
|
; STORE: shufflevector <4 x float>
|
|
|
|
define i32 @store_red(float* noalias %A, float* noalias %B, float* noalias %C, i32 %n) {
|
|
entry:
|
|
%cmp37 = icmp sgt i32 %n, 0
|
|
br i1 %cmp37, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph:
|
|
%arrayidx4 = getelementptr inbounds float, float* %B, i64 1
|
|
%arrayidx9 = getelementptr inbounds float, float* %B, i64 2
|
|
%arrayidx15 = getelementptr inbounds float, float* %B, i64 3
|
|
%0 = sext i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i.039 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
|
%C.addr.038 = phi float* [ %C, %for.body.lr.ph ], [ %incdec.ptr, %for.body ]
|
|
%1 = load float, float* %B, align 4
|
|
%mul = shl nsw i64 %i.039, 2
|
|
%arrayidx2 = getelementptr inbounds float, float* %A, i64 %mul
|
|
%2 = load float, float* %arrayidx2, align 4
|
|
%mul3 = fmul fast float %1, %2
|
|
%3 = load float, float* %arrayidx4, align 4
|
|
%add34 = or i64 %mul, 1
|
|
%arrayidx6 = getelementptr inbounds float, float* %A, i64 %add34
|
|
%4 = load float, float* %arrayidx6, align 4
|
|
%mul7 = fmul fast float %3, %4
|
|
%add8 = fadd fast float %mul3, %mul7
|
|
%5 = load float, float* %arrayidx9, align 4
|
|
%add1135 = or i64 %mul, 2
|
|
%arrayidx12 = getelementptr inbounds float, float* %A, i64 %add1135
|
|
%6 = load float, float* %arrayidx12, align 4
|
|
%mul13 = fmul fast float %5, %6
|
|
%add14 = fadd fast float %add8, %mul13
|
|
%7 = load float, float* %arrayidx15, align 4
|
|
%add1736 = or i64 %mul, 3
|
|
%arrayidx18 = getelementptr inbounds float, float* %A, i64 %add1736
|
|
%8 = load float, float* %arrayidx18, align 4
|
|
%mul19 = fmul fast float %7, %8
|
|
%add20 = fadd fast float %add14, %mul19
|
|
store float %add20, float* %C.addr.038, align 4
|
|
%incdec.ptr = getelementptr inbounds float, float* %C.addr.038, i64 1
|
|
%inc = add nsw i64 %i.039, 1
|
|
%exitcond = icmp eq i64 %inc, %0
|
|
br i1 %exitcond, label %for.end, label %for.body
|
|
|
|
for.end:
|
|
ret i32 0
|
|
}
|
|
|