Home | History | Annotate | Download | only in ARM
      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 }
     78