1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -basicaa -sink -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -aa-pipeline='basic-aa' -passes='sink' -S | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker@A = external global i32 5*9880d681SAndroid Build Coastguard Worker@B = external global i32 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Sink should sink the load past the store (which doesn't overlap) into 8*9880d681SAndroid Build Coastguard Worker; the block that uses it. 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @foo( 11*9880d681SAndroid Build Coastguard Worker; CHECK: true: 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %l = load i32, i32* @A 13*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %l 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i1 %z) { 16*9880d681SAndroid Build Coastguard Worker %l = load i32, i32* @A 17*9880d681SAndroid Build Coastguard Worker store i32 0, i32* @B 18*9880d681SAndroid Build Coastguard Worker br i1 %z, label %true, label %false 19*9880d681SAndroid Build Coastguard Workertrue: 20*9880d681SAndroid Build Coastguard Worker ret i32 %l 21*9880d681SAndroid Build Coastguard Workerfalse: 22*9880d681SAndroid Build Coastguard Worker ret i32 0 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker; But don't sink load volatiles... 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @foo2( 28*9880d681SAndroid Build Coastguard Worker; CHECK: load volatile 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i32 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Workerdefine i32 @foo2(i1 %z) { 32*9880d681SAndroid Build Coastguard Worker %l = load volatile i32, i32* @A 33*9880d681SAndroid Build Coastguard Worker store i32 0, i32* @B 34*9880d681SAndroid Build Coastguard Worker br i1 %z, label %true, label %false 35*9880d681SAndroid Build Coastguard Workertrue: 36*9880d681SAndroid Build Coastguard Worker ret i32 %l 37*9880d681SAndroid Build Coastguard Workerfalse: 38*9880d681SAndroid Build Coastguard Worker ret i32 0 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker; Sink to the nearest post-dominator 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @diamond( 44*9880d681SAndroid Build Coastguard Worker; CHECK: X: 45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: phi 46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mul nsw 47*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerdefine i32 @diamond(i32 %a, i32 %b, i32 %c) { 50*9880d681SAndroid Build Coastguard Worker %1 = mul nsw i32 %c, %b 51*9880d681SAndroid Build Coastguard Worker %2 = icmp sgt i32 %a, 0 52*9880d681SAndroid Build Coastguard Worker br i1 %2, label %B0, label %B1 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard WorkerB0: ; preds = %0 55*9880d681SAndroid Build Coastguard Worker br label %X 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard WorkerB1: ; preds = %0 58*9880d681SAndroid Build Coastguard Worker br label %X 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard WorkerX: ; preds = %5, %3 61*9880d681SAndroid Build Coastguard Worker %.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ] 62*9880d681SAndroid Build Coastguard Worker %R = sub i32 %1, %.01 63*9880d681SAndroid Build Coastguard Worker ret i32 %R 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; We shouldn't sink constant sized allocas from the entry block, since CodeGen 67*9880d681SAndroid Build Coastguard Worker; interprets allocas outside the entry block as dynamically sized stack objects. 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @alloca_nosink 70*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: alloca 72*9880d681SAndroid Build Coastguard Workerdefine i32 @alloca_nosink(i32 %a, i32 %b) { 73*9880d681SAndroid Build Coastguard Workerentry: 74*9880d681SAndroid Build Coastguard Worker %0 = alloca i32 75*9880d681SAndroid Build Coastguard Worker %1 = icmp ne i32 %a, 0 76*9880d681SAndroid Build Coastguard Worker br i1 %1, label %if, label %endif 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerif: 79*9880d681SAndroid Build Coastguard Worker %2 = getelementptr i32, i32* %0, i32 1 80*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %0 81*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %2 82*9880d681SAndroid Build Coastguard Worker %3 = getelementptr i32, i32* %0, i32 %b 83*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %3 84*9880d681SAndroid Build Coastguard Worker ret i32 %4 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerendif: 87*9880d681SAndroid Build Coastguard Worker ret i32 0 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; Make sure we sink dynamic sized allocas 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @alloca_sink_dynamic 93*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 94*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: alloca 95*9880d681SAndroid Build Coastguard Worker; CHECK: if: 96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: alloca 97*9880d681SAndroid Build Coastguard Workerdefine i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) { 98*9880d681SAndroid Build Coastguard Workerentry: 99*9880d681SAndroid Build Coastguard Worker %0 = alloca i32, i32 %size 100*9880d681SAndroid Build Coastguard Worker %1 = icmp ne i32 %a, 0 101*9880d681SAndroid Build Coastguard Worker br i1 %1, label %if, label %endif 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerif: 104*9880d681SAndroid Build Coastguard Worker %2 = getelementptr i32, i32* %0, i32 1 105*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %0 106*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %2 107*9880d681SAndroid Build Coastguard Worker %3 = getelementptr i32, i32* %0, i32 %b 108*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %3 109*9880d681SAndroid Build Coastguard Worker ret i32 %4 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerendif: 112*9880d681SAndroid Build Coastguard Worker ret i32 0 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; We also want to sink allocas that are not in the entry block. These 116*9880d681SAndroid Build Coastguard Worker; will already be considered as dynamically sized stack objects, so sinking 117*9880d681SAndroid Build Coastguard Worker; them does no further damage. 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @alloca_sink_nonentry 120*9880d681SAndroid Build Coastguard Worker; CHECK: if0: 121*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: alloca 122*9880d681SAndroid Build Coastguard Worker; CHECK: if: 123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: alloca 124*9880d681SAndroid Build Coastguard Workerdefine i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) { 125*9880d681SAndroid Build Coastguard Workerentry: 126*9880d681SAndroid Build Coastguard Worker %cmp = icmp ne i32 %c, 0 127*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %endif, label %if0 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Workerif0: 130*9880d681SAndroid Build Coastguard Worker %0 = alloca i32 131*9880d681SAndroid Build Coastguard Worker %1 = icmp ne i32 %a, 0 132*9880d681SAndroid Build Coastguard Worker br i1 %1, label %if, label %endif 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Workerif: 135*9880d681SAndroid Build Coastguard Worker %2 = getelementptr i32, i32* %0, i32 1 136*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %0 137*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %2 138*9880d681SAndroid Build Coastguard Worker %3 = getelementptr i32, i32* %0, i32 %b 139*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %3 140*9880d681SAndroid Build Coastguard Worker ret i32 %4 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Workerendif: 143*9880d681SAndroid Build Coastguard Worker ret i32 0 144*9880d681SAndroid Build Coastguard Worker} 145