160 lines · plain
1; RUN: opt %loadNPMPolly -polly-stmt-granularity=bb '-passes=polly-custom<optree>' -polly-print-optree -disable-output < %s | FileCheck %s -match-full-lines2;3; %val1 is used three times: Twice by its own operand tree of %val2 and once4; more by the store in %bodyB.5; Verify that we can handle multiple uses by the same instruction and uses6; in multiple statements as well.7; The result processing may depend on the order in which the values are used,8; hence we check both orderings.9;10; for (int j = 0; j < n; j += 1) {11; bodyA:12; double val1 = A[j];13; double val2 = val1 + val1;14;15; bodyB:16; B[j] = val1;17; C[j] = val2;18; }19;20define void @func1(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B, ptr noalias nonnull %C) {21entry:22 br label %for23 24for:25 %j = phi i32 [0, %entry], [%j.inc, %inc]26 %j.cmp = icmp slt i32 %j, %n27 br i1 %j.cmp, label %bodyA, label %exit28 29 bodyA:30 %A_idx = getelementptr inbounds double, ptr %A, i32 %j31 %val1 = load double, ptr %A_idx32 %val2 = fadd double %val1, %val133 br label %bodyB34 35 bodyB:36 %B_idx = getelementptr inbounds double, ptr %B, i32 %j37 store double %val1, ptr %B_idx38 %C_idx = getelementptr inbounds double, ptr %C, i32 %j39 store double %val2, ptr %C_idx40 br label %inc41 42inc:43 %j.inc = add nuw nsw i32 %j, 144 br label %for45 46exit:47 br label %return48 49return:50 ret void51}52 53 54; CHECK: Statistics {55; CHECK: Instructions copied: 156; CHECK: Known loads forwarded: 257; CHECK: Operand trees forwarded: 258; CHECK: Statements with forwarded operand trees: 159; CHECK: }60 61; CHECK: After statements {62; CHECK-NEXT: Stmt_bodyA63; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]64; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };65; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]66; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };67; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]68; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };69; CHECK-NEXT: Instructions {70; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 871; CHECK-NEXT: %val2 = fadd double %val1, %val172; CHECK-NEXT: }73; CHECK-NEXT: Stmt_bodyB74; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]75; CHECK-NEXT: ;76; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };77; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]78; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };79; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]80; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };81; CHECK-NEXT: Instructions {82; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 883; CHECK-NEXT: %val2 = fadd double %val1, %val184; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 885; CHECK-NEXT: store double %val1, ptr %B_idx, align 886; CHECK-NEXT: store double %val2, ptr %C_idx, align 887; CHECK-NEXT: }88; CHECK-NEXT: }89 90 91define void @func2(i32 %n, ptr noalias nonnull %A, ptr noalias nonnull %B, ptr noalias nonnull %C) {92entry:93 br label %for94 95for:96 %j = phi i32 [0, %entry], [%j.inc, %inc]97 %j.cmp = icmp slt i32 %j, %n98 br i1 %j.cmp, label %bodyA, label %exit99 100 bodyA:101 %A_idx = getelementptr inbounds double, ptr %A, i32 %j102 %val1 = load double, ptr %A_idx103 %val2 = fadd double %val1, %val1104 br label %bodyB105 106 bodyB:107 %B_idx = getelementptr inbounds double, ptr %B, i32 %j108 store double %val2, ptr %B_idx109 %C_idx = getelementptr inbounds double, ptr %C, i32 %j110 store double %val1, ptr %C_idx111 br label %inc112 113inc:114 %j.inc = add nuw nsw i32 %j, 1115 br label %for116 117exit:118 br label %return119 120return:121 ret void122}123 124 125; CHECK: Statistics {126; CHECK: Instructions copied: 1127; CHECK: Known loads forwarded: 2128; CHECK: Operand trees forwarded: 2129; CHECK: Statements with forwarded operand trees: 1130; CHECK: }131 132; CHECK: After statements {133; CHECK-NEXT: Stmt_bodyA134; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]135; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };136; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]137; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };138; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]139; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };140; CHECK-NEXT: Instructions {141; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 8142; CHECK-NEXT: %val2 = fadd double %val1, %val1143; CHECK-NEXT: }144; CHECK-NEXT: Stmt_bodyB145; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]146; CHECK-NEXT: ;147; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };148; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]149; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };150; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]151; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };152; CHECK-NEXT: Instructions {153; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 8154; CHECK-NEXT: %val1 = load double, ptr %A_idx, align 8155; CHECK-NEXT: %val2 = fadd double %val1, %val1156; CHECK-NEXT: store double %val2, ptr %B_idx, align 8157; CHECK-NEXT: store double %val1, ptr %C_idx, align 8158; CHECK-NEXT: }159; CHECK-NEXT: }160