1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -nary-reassociate -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 Worker 5*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i32) 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; foo(a + c); 8*9880d681SAndroid Build Coastguard Worker; foo((a + (b + c)); 9*9880d681SAndroid Build Coastguard Worker; => 10*9880d681SAndroid Build Coastguard Worker; t = a + c; 11*9880d681SAndroid Build Coastguard Worker; foo(t); 12*9880d681SAndroid Build Coastguard Worker; foo(t + b); 13*9880d681SAndroid Build Coastguard Workerdefine void @left_reassociate(i32 %a, i32 %b, i32 %c) { 14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @left_reassociate( 15*9880d681SAndroid Build Coastguard Worker %1 = add i32 %a, %c 16*9880d681SAndroid Build Coastguard Worker; CHECK: [[BASE:%[a-zA-Z0-9]+]] = add i32 %a, %c 17*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) 18*9880d681SAndroid Build Coastguard Worker %2 = add i32 %b, %c 19*9880d681SAndroid Build Coastguard Worker %3 = add i32 %a, %2 20*9880d681SAndroid Build Coastguard Worker; CHECK: [[RESULT:%[a-zA-Z0-9]+]] = add i32 [[BASE]], %b 21*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %3) 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 [[RESULT]]) 23*9880d681SAndroid Build Coastguard Worker ret void 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; foo(a + c); 27*9880d681SAndroid Build Coastguard Worker; foo((a + b) + c); 28*9880d681SAndroid Build Coastguard Worker; => 29*9880d681SAndroid Build Coastguard Worker; t = a + c; 30*9880d681SAndroid Build Coastguard Worker; foo(t); 31*9880d681SAndroid Build Coastguard Worker; foo(t + b); 32*9880d681SAndroid Build Coastguard Workerdefine void @right_reassociate(i32 %a, i32 %b, i32 %c) { 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @right_reassociate( 34*9880d681SAndroid Build Coastguard Worker %1 = add i32 %a, %c 35*9880d681SAndroid Build Coastguard Worker; CHECK: [[BASE:%[a-zA-Z0-9]+]] = add i32 %a, %c 36*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) 37*9880d681SAndroid Build Coastguard Worker %2 = add i32 %a, %b 38*9880d681SAndroid Build Coastguard Worker %3 = add i32 %2, %c 39*9880d681SAndroid Build Coastguard Worker; CHECK: [[RESULT:%[a-zA-Z0-9]+]] = add i32 [[BASE]], %b 40*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %3) 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 [[RESULT]]) 42*9880d681SAndroid Build Coastguard Worker ret void 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; t1 = a + c; 46*9880d681SAndroid Build Coastguard Worker; foo(t1); 47*9880d681SAndroid Build Coastguard Worker; t2 = a + b; 48*9880d681SAndroid Build Coastguard Worker; foo(t2); 49*9880d681SAndroid Build Coastguard Worker; t3 = t2 + c; 50*9880d681SAndroid Build Coastguard Worker; foo(t3); 51*9880d681SAndroid Build Coastguard Worker; 52*9880d681SAndroid Build Coastguard Worker; Do not rewrite t3 into t1 + b because t2 is used elsewhere and is likely free. 53*9880d681SAndroid Build Coastguard Workerdefine void @no_reassociate(i32 %a, i32 %b, i32 %c) { 54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @no_reassociate( 55*9880d681SAndroid Build Coastguard Worker %1 = add i32 %a, %c 56*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %a, %c 57*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) 58*9880d681SAndroid Build Coastguard Worker %2 = add i32 %a, %b 59*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %a, %b 60*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %2) 61*9880d681SAndroid Build Coastguard Worker %3 = add i32 %2, %c 62*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %2, %c 63*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %3) 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; if (p1) 68*9880d681SAndroid Build Coastguard Worker; foo(a + c); 69*9880d681SAndroid Build Coastguard Worker; if (p2) 70*9880d681SAndroid Build Coastguard Worker; foo(a + c); 71*9880d681SAndroid Build Coastguard Worker; if (p3) 72*9880d681SAndroid Build Coastguard Worker; foo((a + b) + c); 73*9880d681SAndroid Build Coastguard Worker; 74*9880d681SAndroid Build Coastguard Worker; No action because (a + c) does not dominate ((a + b) + c). 75*9880d681SAndroid Build Coastguard Workerdefine void @conditional(i1 %p1, i1 %p2, i1 %p3, i32 %a, i32 %b, i32 %c) { 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @conditional( 77*9880d681SAndroid Build Coastguard Workerentry: 78*9880d681SAndroid Build Coastguard Worker br i1 %p1, label %then1, label %branch1 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Workerthen1: 81*9880d681SAndroid Build Coastguard Worker %0 = add i32 %a, %c 82*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %a, %c 83*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %0) 84*9880d681SAndroid Build Coastguard Worker br label %branch1 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerbranch1: 87*9880d681SAndroid Build Coastguard Worker br i1 %p2, label %then2, label %branch2 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerthen2: 90*9880d681SAndroid Build Coastguard Worker %1 = add i32 %a, %c 91*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %a, %c 92*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) 93*9880d681SAndroid Build Coastguard Worker br label %branch2 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Workerbranch2: 96*9880d681SAndroid Build Coastguard Worker br i1 %p3, label %then3, label %return 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerthen3: 99*9880d681SAndroid Build Coastguard Worker %2 = add i32 %a, %b 100*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add i32 %a, %b 101*9880d681SAndroid Build Coastguard Worker %3 = add i32 %2, %c 102*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %2, %c 103*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %3) 104*9880d681SAndroid Build Coastguard Worker br label %return 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerreturn: 107*9880d681SAndroid Build Coastguard Worker ret void 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker; This test involves more conditional reassociation candidates. It exercises 111*9880d681SAndroid Build Coastguard Worker; the stack optimization in tryReassociatedAdd that pops the candidates that 112*9880d681SAndroid Build Coastguard Worker; do not dominate the current instruction. 113*9880d681SAndroid Build Coastguard Worker; 114*9880d681SAndroid Build Coastguard Worker; def1 115*9880d681SAndroid Build Coastguard Worker; cond1 116*9880d681SAndroid Build Coastguard Worker; / \ 117*9880d681SAndroid Build Coastguard Worker; / \ 118*9880d681SAndroid Build Coastguard Worker; cond2 use2 119*9880d681SAndroid Build Coastguard Worker; / \ 120*9880d681SAndroid Build Coastguard Worker; / \ 121*9880d681SAndroid Build Coastguard Worker; def2 def3 122*9880d681SAndroid Build Coastguard Worker; cond3 123*9880d681SAndroid Build Coastguard Worker; / \ 124*9880d681SAndroid Build Coastguard Worker; / \ 125*9880d681SAndroid Build Coastguard Worker; def4 use1 126*9880d681SAndroid Build Coastguard Worker; 127*9880d681SAndroid Build Coastguard Worker; NaryReassociate should match use1 with def3, and use2 with def1. 128*9880d681SAndroid Build Coastguard Workerdefine void @conditional2(i32 %a, i32 %b, i32 %c, i1 %cond1, i1 %cond2, i1 %cond3) { 129*9880d681SAndroid Build Coastguard Workerentry: 130*9880d681SAndroid Build Coastguard Worker %def1 = add i32 %a, %b 131*9880d681SAndroid Build Coastguard Worker br i1 %cond1, label %bb1, label %bb6 132*9880d681SAndroid Build Coastguard Workerbb1: 133*9880d681SAndroid Build Coastguard Worker br i1 %cond2, label %bb2, label %bb3 134*9880d681SAndroid Build Coastguard Workerbb2: 135*9880d681SAndroid Build Coastguard Worker %def2 = add i32 %a, %b 136*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %def2) 137*9880d681SAndroid Build Coastguard Worker ret void 138*9880d681SAndroid Build Coastguard Workerbb3: 139*9880d681SAndroid Build Coastguard Worker %def3 = add i32 %a, %b 140*9880d681SAndroid Build Coastguard Worker br i1 %cond3, label %bb4, label %bb5 141*9880d681SAndroid Build Coastguard Workerbb4: 142*9880d681SAndroid Build Coastguard Worker %def4 = add i32 %a, %b 143*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %def4) 144*9880d681SAndroid Build Coastguard Worker ret void 145*9880d681SAndroid Build Coastguard Workerbb5: 146*9880d681SAndroid Build Coastguard Worker %0 = add i32 %a, %c 147*9880d681SAndroid Build Coastguard Worker %1 = add i32 %0, %b 148*9880d681SAndroid Build Coastguard Worker; CHECK: [[t1:%[0-9]+]] = add i32 %def3, %c 149*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %1) ; foo((a + c) + b); 150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 [[t1]]) 151*9880d681SAndroid Build Coastguard Worker ret void 152*9880d681SAndroid Build Coastguard Workerbb6: 153*9880d681SAndroid Build Coastguard Worker %2 = add i32 %a, %c 154*9880d681SAndroid Build Coastguard Worker %3 = add i32 %2, %b 155*9880d681SAndroid Build Coastguard Worker; CHECK: [[t2:%[0-9]+]] = add i32 %def1, %c 156*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %3) ; foo((a + c) + b); 157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 [[t2]]) 158*9880d681SAndroid Build Coastguard Worker ret void 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker; foo((a + b) + c) 162*9880d681SAndroid Build Coastguard Worker; foo(((a + d) + b) + c) 163*9880d681SAndroid Build Coastguard Worker; => 164*9880d681SAndroid Build Coastguard Worker; t = (a + b) + c; 165*9880d681SAndroid Build Coastguard Worker; foo(t); 166*9880d681SAndroid Build Coastguard Worker; foo(t + d); 167*9880d681SAndroid Build Coastguard Workerdefine void @quaternary(i32 %a, i32 %b, i32 %c, i32 %d) { 168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @quaternary( 169*9880d681SAndroid Build Coastguard Worker %1 = add i32 %a, %b 170*9880d681SAndroid Build Coastguard Worker %2 = add i32 %1, %c 171*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %2) 172*9880d681SAndroid Build Coastguard Worker; CHECK: call void @foo(i32 [[TMP1:%[a-zA-Z0-9]]]) 173*9880d681SAndroid Build Coastguard Worker %3 = add i32 %a, %d 174*9880d681SAndroid Build Coastguard Worker %4 = add i32 %3, %b 175*9880d681SAndroid Build Coastguard Worker %5 = add i32 %4, %c 176*9880d681SAndroid Build Coastguard Worker; CHECK: [[TMP2:%[a-zA-Z0-9]]] = add i32 [[TMP1]], %d 177*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %5) 178*9880d681SAndroid Build Coastguard Worker; CHECK: call void @foo(i32 [[TMP2]] 179*9880d681SAndroid Build Coastguard Worker ret void 180*9880d681SAndroid Build Coastguard Worker} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerdefine void @iterative(i32 %a, i32 %b, i32 %c) { 183*9880d681SAndroid Build Coastguard Worker %ab = add i32 %a, %b 184*9880d681SAndroid Build Coastguard Worker %abc = add i32 %ab, %c 185*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %abc) 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker %ab2 = add i32 %ab, %b 188*9880d681SAndroid Build Coastguard Worker %ab2c = add i32 %ab2, %c 189*9880d681SAndroid Build Coastguard Worker; CHECK: %ab2c = add i32 %abc, %b 190*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %ab2c) 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 %ab2c) 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker %ab3 = add i32 %ab2, %b 194*9880d681SAndroid Build Coastguard Worker %ab3c = add i32 %ab3, %c 195*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ab3c = add i32 %ab2c, %b 196*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %ab3c) 197*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @foo(i32 %ab3c) 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker ret void 200*9880d681SAndroid Build Coastguard Worker} 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Workerdefine void @avoid_infinite_loop(i32 %a, i32 %b) { 203*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @avoid_infinite_loop 204*9880d681SAndroid Build Coastguard Worker %ab = add i32 %a, %b 205*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ab 206*9880d681SAndroid Build Coastguard Worker %ab2 = add i32 %ab, %b 207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ab2 208*9880d681SAndroid Build Coastguard Worker call void @foo(i32 %ab2) 209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @foo(i32 %ab2) 210*9880d681SAndroid Build Coastguard Worker ret void 211*9880d681SAndroid Build Coastguard Worker} 212