[DAGCombiner] Fold together mul and shl when both are by a constant
[oota-llvm.git] / test / CodeGen / ARM / gep-optimization.ll
1 ; RUN: llc < %s -mtriple=armv7a-eabi   | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-AT2
2 ; RUN: llc < %s -mtriple=thumbv7m-eabi | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-AT2
3 ; RUN: llc < %s -mtriple=thumbv6m-eabi | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-T1
4
5 ; This test checks that various kinds of getelementptr are all optimised to a
6 ; simple multiply plus add, with the add being done by a register offset if the
7 ; result is used in a load.
8
9 ; CHECK-LABEL: calc_1d:
10 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
11 ; CHECK-AT2: mla r0, r1, [[REG1]], r0
12 ; CHECK-T1: muls [[REG2:r[0-9]+]], r1, [[REG1]]
13 ; CHECK-T1: adds r0, r0, [[REG2]]
14 define i32* @calc_1d(i32* %p, i32 %n) {
15 entry:
16   %mul = mul nsw i32 %n, 21
17   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %mul
18   ret i32* %add.ptr
19 }
20
21 ; CHECK-LABEL: load_1d:
22 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
23 ; CHECK: mul{{s?}} [[REG2:r[0-9]+]],{{( r1,)?}} [[REG1]]{{(, r1)?}}
24 ; CHECK: ldr r0, [r0, [[REG2]]]
25 define i32 @load_1d(i32* %p, i32 %n) #1 {
26 entry:
27   %mul = mul nsw i32 %n, 21
28   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %mul
29   %0 = load i32, i32* %arrayidx, align 4
30   ret i32 %0
31 }
32
33 ; CHECK-LABEL: calc_2d_a:
34 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
35 ; CHECK-AT2: mla r0, r1, [[REG1]], r0
36 ; CHECK-T1: muls [[REG2:r[0-9]+]], r1, [[REG1]]
37 ; CHECK-T1: adds r0, r0, [[REG2]]
38 define i32* @calc_2d_a([100 x i32]* %p, i32 %n) {
39 entry:
40   %mul = mul nsw i32 %n, 21
41   %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %p, i32 0, i32 %mul
42   ret i32* %arrayidx1
43 }
44
45 ; CHECK-LABEL: load_2d_a:
46 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
47 ; CHECK: mul{{s?}} [[REG2:r[0-9]+]],{{( r1,)?}} [[REG1]]{{(, r1)?}}
48 ; CHECK: ldr r0, [r0, [[REG2]]]
49 define i32 @load_2d_a([100 x i32]* %p, i32 %n) #1 {
50 entry:
51   %mul = mul nsw i32 %n, 21
52   %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %p, i32 0, i32 %mul
53   %0 = load i32, i32* %arrayidx1, align 4
54   ret i32 %0
55 }
56
57 ; CHECK-LABEL: calc_2d_b:
58 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
59 ; CHECK-AT2: mla r0, r1, [[REG1]], r0
60 ; CHECK-T1: muls [[REG2:r[0-9]+]], r1, [[REG1]]
61 ; CHECK-T1: adds r0, r0, [[REG2]]
62 define i32* @calc_2d_b([21 x i32]* %p, i32 %n) {
63 entry:
64   %arrayidx1 = getelementptr inbounds [21 x i32], [21 x i32]* %p, i32 %n, i32 0
65   ret i32* %arrayidx1
66 }
67
68 ; CHECK-LABEL: load_2d_b:
69 ; CHECK: mov{{s?}} [[REG1:r[0-9]+]], #84
70 ; CHECK: mul{{s?}} [[REG2:r[0-9]+]],{{( r1,)?}} [[REG1]]{{(, r1)?}}
71 ; CHECK: ldr r0, [r0, [[REG2]]]
72 define i32 @load_2d_b([21 x i32]* %p, i32 %n) {
73 entry:
74   %arrayidx1 = getelementptr inbounds [21 x i32], [21 x i32]* %p, i32 %n, i32 0
75   %0 = load i32, i32* %arrayidx1, align 4
76   ret i32 %0
77 }