1*9880d681SAndroid Build Coastguard Worker; RUN: llc -O3 -mcpu=pwr7 < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -O3 -print-after=codegenprepare -mcpu=ppc64 < %s >%t 2>&1 && FileCheck --check-prefix=CHECK-NoAA <%t %s 3*9880d681SAndroid Build Coastguard Worker; RUN: llc -O3 -print-after=codegenprepare -mcpu=pwr7 < %s >%t 2>&1 && FileCheck --check-prefix=CHECK-UseAA <%t %s 4*9880d681SAndroid Build Coastguard Workertarget datalayout = "E-m:e-i64:64-n32:64" 5*9880d681SAndroid Build Coastguard Workertarget triple = "powerpc64-unknown-linux-gnu" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Following test cases test enabling SeparateConstOffsetFromGEP pass in the PPC 8*9880d681SAndroid Build Coastguard Worker; backend. If useAA() returns true, it will lower a GEP with multiple indices 9*9880d681SAndroid Build Coastguard Worker; into GEPs with a single index, otherwise it will lower it into a 10*9880d681SAndroid Build Coastguard Worker; "ptrtoint+arithmetics+inttoptr" form. 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker%struct = type { i32, i32, i32, i32, [20 x i32] } 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; Check that when two complex GEPs are used in two basic blocks, LLVM can 15*9880d681SAndroid Build Coastguard Worker; elimilate the common subexpression for the second use. 16*9880d681SAndroid Build Coastguard Workerdefine void @test_GEP_CSE([240 x %struct]* %string, i32* %adj, i32 %lib, i64 %idxprom) { 17*9880d681SAndroid Build Coastguard Worker %liberties = getelementptr [240 x %struct], [240 x %struct]* %string, i64 1, i64 %idxprom, i32 3 18*9880d681SAndroid Build Coastguard Worker %1 = load i32, i32* %liberties, align 4 19*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %1, %lib 20*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then, label %if.end 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 23*9880d681SAndroid Build Coastguard Worker %origin = getelementptr [240 x %struct], [240 x %struct]* %string, i64 1, i64 %idxprom, i32 2 24*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %origin, align 4 25*9880d681SAndroid Build Coastguard Worker store i32 %2, i32* %adj, align 4 26*9880d681SAndroid Build Coastguard Worker br label %if.end 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.then, %entry 29*9880d681SAndroid Build Coastguard Worker ret void 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-LABEL: @test_GEP_CSE( 33*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: [[PTR0:%[a-zA-Z0-9]+]] = ptrtoint [240 x %struct]* %string to i64 34*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: [[PTR1:%[a-zA-Z0-9]+]] = mul i64 %idxprom, 96 35*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: [[PTR2:%[a-zA-Z0-9]+]] = add i64 [[PTR0]], [[PTR1]] 36*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 [[PTR2]], 23052 37*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: inttoptr 38*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: if.then: 39*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-NOT: ptrtoint 40*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-NOT: mul 41*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 [[PTR2]], 23048 42*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: inttoptr 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA-LABEL: @test_GEP_CSE( 45*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: [[PTR0:%[a-zA-Z0-9]+]] = bitcast [240 x %struct]* %string to i8* 46*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: [[IDX:%[a-zA-Z0-9]+]] = mul i64 %idxprom, 96 47*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: [[PTR1:%[a-zA-Z0-9]+]] = getelementptr i8, i8* [[PTR0]], i64 [[IDX]] 48*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* [[PTR1]], i64 23052 49*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: bitcast 50*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: if.then: 51*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* [[PTR1]], i64 23048 52*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: bitcast 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker%class.my = type { i32, [128 x i32], i32, [256 x %struct.pt]} 55*9880d681SAndroid Build Coastguard Worker%struct.pt = type { %struct.point*, i32, i32 } 56*9880d681SAndroid Build Coastguard Worker%struct.point = type { i32, i32 } 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; Check when a GEP is used across two basic block, LLVM can sink the address 59*9880d681SAndroid Build Coastguard Worker; calculation and code gen can generate a better addressing mode for the second 60*9880d681SAndroid Build Coastguard Worker; use. 61*9880d681SAndroid Build Coastguard Workerdefine void @test_GEP_across_BB(%class.my* %this, i64 %idx) { 62*9880d681SAndroid Build Coastguard Worker %1 = getelementptr %class.my, %class.my* %this, i64 0, i32 3, i64 %idx, i32 1 63*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %1, align 4 64*9880d681SAndroid Build Coastguard Worker %3 = getelementptr %class.my, %class.my* %this, i64 0, i32 3, i64 %idx, i32 2 65*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %3, align 4 66*9880d681SAndroid Build Coastguard Worker %5 = icmp eq i32 %2, %4 67*9880d681SAndroid Build Coastguard Worker br i1 %5, label %if.true, label %exit 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Workerif.true: 70*9880d681SAndroid Build Coastguard Worker %6 = shl i32 %4, 1 71*9880d681SAndroid Build Coastguard Worker store i32 %6, i32* %3, align 4 72*9880d681SAndroid Build Coastguard Worker br label %exit 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerexit: 75*9880d681SAndroid Build Coastguard Worker %7 = add nsw i32 %4, 1 76*9880d681SAndroid Build Coastguard Worker store i32 %7, i32* %1, align 4 77*9880d681SAndroid Build Coastguard Worker ret void 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_GEP_across_BB: 80*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: lwzu 81*9880d681SAndroid Build Coastguard Worker; CHECK: blr 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-LABEL: test_GEP_across_BB( 84*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 [[TMP:%[a-zA-Z0-9]+]], 528 85*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 [[TMP]], 532 86*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: if.true: 87*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: {{%sunk[a-zA-Z0-9]+}} = add i64 [[TMP]], 532 88*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: exit: 89*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: {{%sunk[a-zA-Z0-9]+}} = add i64 [[TMP]], 528 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA-LABEL: test_GEP_across_BB( 92*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: [[PTR0:%[a-zA-Z0-9]+]] = getelementptr 93*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* [[PTR0]], i64 528 94*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* [[PTR0]], i64 532 95*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: if.true: 96*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: {{%sunk[a-zA-Z0-9]+}} = getelementptr i8, i8* [[PTR0]], i64 532 97*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: exit: 98*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: {{%sunk[a-zA-Z0-9]+}} = getelementptr i8, i8* [[PTR0]], i64 528 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker%struct.S = type { float, double } 101*9880d681SAndroid Build Coastguard Worker@struct_array = global [1024 x %struct.S] zeroinitializer, align 16 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; The following two test cases check we can extract constant from indices of 104*9880d681SAndroid Build Coastguard Worker; struct type. 105*9880d681SAndroid Build Coastguard Worker; The constant offsets are from indices "i64 %idxprom" and "i32 1". As the 106*9880d681SAndroid Build Coastguard Worker; alloca size of %struct.S is 16, and "i32 1" is the 2rd element whose field 107*9880d681SAndroid Build Coastguard Worker; offset is 8, the total constant offset is (5 * 16 + 8) = 88. 108*9880d681SAndroid Build Coastguard Workerdefine double* @test-struct_1(i32 %i) { 109*9880d681SAndroid Build Coastguard Workerentry: 110*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %i, 5 111*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %add to i64 112*9880d681SAndroid Build Coastguard Worker %p = getelementptr [1024 x %struct.S], [1024 x %struct.S]* @struct_array, i64 0, i64 %idxprom, i32 1 113*9880d681SAndroid Build Coastguard Worker ret double* %p 114*9880d681SAndroid Build Coastguard Worker} 115*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-LABEL: @test-struct_1( 116*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-NOT: getelementptr 117*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 %{{[a-zA-Z0-9]+}}, 88 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA-LABEL: @test-struct_1( 120*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* %{{[a-zA-Z0-9]+}}, i64 88 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker%struct3 = type { i64, i32 } 123*9880d681SAndroid Build Coastguard Worker%struct2 = type { %struct3, i32 } 124*9880d681SAndroid Build Coastguard Worker%struct1 = type { i64, %struct2 } 125*9880d681SAndroid Build Coastguard Worker%struct0 = type { i32, i32, i64*, [100 x %struct1] } 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker; The constant offsets are from indices "i32 3", "i64 %arrayidx" and "i32 1". 128*9880d681SAndroid Build Coastguard Worker; "i32 3" is the 4th element whose field offset is 16. The alloca size of 129*9880d681SAndroid Build Coastguard Worker; %struct1 is 32. "i32 1" is the 2rd element whose field offset is 8. So the 130*9880d681SAndroid Build Coastguard Worker; total constant offset is 16 + (-2 * 32) + 8 = -40 131*9880d681SAndroid Build Coastguard Workerdefine %struct2* @test-struct_2(%struct0* %ptr, i64 %idx) { 132*9880d681SAndroid Build Coastguard Workerentry: 133*9880d681SAndroid Build Coastguard Worker %arrayidx = add nsw i64 %idx, -2 134*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr %struct0, %struct0* %ptr, i64 0, i32 3, i64 %arrayidx, i32 1 135*9880d681SAndroid Build Coastguard Worker ret %struct2* %ptr2 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-LABEL: @test-struct_2( 138*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA-NOT: = getelementptr 139*9880d681SAndroid Build Coastguard Worker; CHECK-NoAA: add i64 %{{[a-zA-Z0-9]+}}, -40 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA-LABEL: @test-struct_2( 142*9880d681SAndroid Build Coastguard Worker; CHECK-UseAA: getelementptr i8, i8* %{{[a-zA-Z0-9]+}}, i64 -40 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker; Test that when a index is added from two constant, SeparateConstOffsetFromGEP 145*9880d681SAndroid Build Coastguard Worker; pass does not generate incorrect result. 146*9880d681SAndroid Build Coastguard Workerdefine void @test_const_add([3 x i32]* %in) { 147*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 2, 1 148*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %inc to i64 149*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr [3 x i32], [3 x i32]* %in, i64 %idxprom, i64 2 150*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %arrayidx, align 4 151*9880d681SAndroid Build Coastguard Worker ret void 152*9880d681SAndroid Build Coastguard Worker} 153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_const_add: 154*9880d681SAndroid Build Coastguard Worker; CHECK: li [[REG:[0-9]+]], 0 155*9880d681SAndroid Build Coastguard Worker; CHECK: stw [[REG]], 44(3) 156*9880d681SAndroid Build Coastguard Worker; CHECK: blr 157*9880d681SAndroid Build Coastguard Worker 158