Home | History | Annotate | Download | only in PowerPC
      1 ; RUN: llc -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck -check-prefix=POWER7 -check-prefix=CHECK %s
      2 ; RUN: llc -mcpu=pwr8 -O1 -code-model=medium <%s | FileCheck -check-prefix=POWER8 -check-prefix=CHECK %s
      3 
      4 ; Test peephole optimization for medium code model (32-bit TOC offsets)
      5 ; for loading and storing small offsets within aligned values.
      6 ; For power8, verify that the optimization doesn't fire, as it prevents fusion
      7 ; opportunities.
      8 
      9 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
     10 target triple = "powerpc64-unknown-linux-gnu"
     11 
     12 %struct.b4 = type<{ i8, i8, i8, i8 }>
     13 %struct.h2 = type<{ i16, i16 }>
     14 
     15 %struct.b8 = type<{ i8, i8, i8, i8, i8, i8, i8, i8 }>
     16 %struct.h4 = type<{ i16, i16, i16, i16 }>
     17 %struct.w2 = type<{ i32, i32 }>
     18 
     19 %struct.d2 = type<{ i64, i64 }>
     20 %struct.misalign = type<{ i8, i64 }>
     21 
     22 @b4v = global %struct.b4 <{ i8 1, i8 2, i8 3, i8 4 }>, align 4
     23 @h2v = global %struct.h2 <{ i16 1, i16 2 }>, align 4
     24 
     25 @b8v = global %struct.b8 <{ i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8 }>, align 8
     26 @h4v = global %struct.h4 <{ i16 1, i16 2, i16 3, i16 4 }>, align 8
     27 @w2v = global %struct.w2 <{ i32 1, i32 2 }>, align 8
     28 
     29 @d2v = global %struct.d2 <{ i64 1, i64 2 }>, align 16
     30 @misalign_v = global %struct.misalign <{ i8 1, i64 2 }>, align 16
     31 
     32 ; CHECK-LABEL: test_b4:
     33 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, b4v@toc@ha
     34 ; POWER7-DAG: lbz [[REG0_0:[0-9]+]], b4v@toc@l([[REGSTRUCT]])
     35 ; POWER7-DAG: lbz [[REG1_0:[0-9]+]], b4v@toc@l+1([[REGSTRUCT]])
     36 ; POWER7-DAG: lbz [[REG2_0:[0-9]+]], b4v@toc@l+2([[REGSTRUCT]])
     37 ; POWER7-DAG: lbz [[REG3_0:[0-9]+]], b4v@toc@l+3([[REGSTRUCT]])
     38 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
     39 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
     40 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
     41 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
     42 ; POWER7-DAG: stb [[REG0_1]], b4v@toc@l([[REGSTRUCT]])
     43 ; POWER7-DAG: stb [[REG1_1]], b4v@toc@l+1([[REGSTRUCT]])
     44 ; POWER7-DAG: stb [[REG2_1]], b4v@toc@l+2([[REGSTRUCT]])
     45 ; POWER7-DAG: stb [[REG3_1]], b4v@toc@l+3([[REGSTRUCT]])
     46 
     47 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, b4v@toc@ha
     48 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], b4v@toc@l
     49 ; POWER8-DAG: lbz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
     50 ; POWER8-DAG: lbz [[REG1_0:[0-9]+]], 1([[REGSTRUCT]])
     51 ; POWER8-DAG: lbz [[REG2_0:[0-9]+]], 2([[REGSTRUCT]])
     52 ; POWER8-DAG: lbz [[REG3_0:[0-9]+]], 3([[REGSTRUCT]])
     53 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
     54 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
     55 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
     56 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
     57 ; POWER8-DAG: stb [[REG0_1]], 0([[REGSTRUCT]])
     58 ; POWER8-DAG: stb [[REG1_1]], 1([[REGSTRUCT]])
     59 ; POWER8-DAG: stb [[REG2_1]], 2([[REGSTRUCT]])
     60 ; POWER8-DAG: stb [[REG3_1]], 3([[REGSTRUCT]])
     61 define void @test_b4() nounwind {
     62 entry:
     63   %0 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
     64   %inc0 = add nsw i8 %0, 1
     65   store i8 %inc0, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
     66   %1 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
     67   %inc1 = add nsw i8 %1, 2
     68   store i8 %inc1, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
     69   %2 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
     70   %inc2 = add nsw i8 %2, 3
     71   store i8 %inc2, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
     72   %3 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
     73   %inc3 = add nsw i8 %3, 4
     74   store i8 %inc3, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
     75   ret void
     76 }
     77 
     78 ; CHECK-LABEL: test_h2:
     79 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
     80 ; POWER7-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
     81 ; POWER7-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
     82 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
     83 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
     84 ; POWER7-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
     85 ; POWER7-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
     86 
     87 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
     88 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], h2v@toc@l
     89 ; POWER8-DAG: lhz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
     90 ; POWER8-DAG: lhz [[REG1_0:[0-9]+]], 2([[REGSTRUCT]])
     91 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
     92 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
     93 ; POWER8-DAG: sth [[REG0_1]], 0([[REGSTRUCT]])
     94 ; POWER8-DAG: sth [[REG1_1]], 2([[REGSTRUCT]])
     95 define void @test_h2() nounwind {
     96 entry:
     97   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
     98   %inc0 = add nsw i16 %0, 1
     99   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
    100   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
    101   %inc1 = add nsw i16 %1, 2
    102   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
    103   ret void
    104 }
    105 
    106 ; CHECK-LABEL: test_h2_optsize:
    107 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
    108 ; CHECK-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
    109 ; CHECK-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
    110 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    111 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    112 ; CHECK-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
    113 ; CHECK-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
    114 define void @test_h2_optsize() optsize nounwind {
    115 entry:
    116   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
    117   %inc0 = add nsw i16 %0, 1
    118   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
    119   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
    120   %inc1 = add nsw i16 %1, 2
    121   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
    122   ret void
    123 }
    124 
    125 ; CHECK-LABEL: test_b8:
    126 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, b8v@toc@ha
    127 ; POWER7-DAG: lbz [[REG0_0:[0-9]+]], b8v@toc@l([[REGSTRUCT]])
    128 ; POWER7-DAG: lbz [[REG1_0:[0-9]+]], b8v@toc@l+1([[REGSTRUCT]])
    129 ; POWER7-DAG: lbz [[REG2_0:[0-9]+]], b8v@toc@l+2([[REGSTRUCT]])
    130 ; POWER7-DAG: lbz [[REG3_0:[0-9]+]], b8v@toc@l+3([[REGSTRUCT]])
    131 ; POWER7-DAG: lbz [[REG4_0:[0-9]+]], b8v@toc@l+4([[REGSTRUCT]])
    132 ; POWER7-DAG: lbz [[REG5_0:[0-9]+]], b8v@toc@l+5([[REGSTRUCT]])
    133 ; POWER7-DAG: lbz [[REG6_0:[0-9]+]], b8v@toc@l+6([[REGSTRUCT]])
    134 ; POWER7-DAG: lbz [[REG7_0:[0-9]+]], b8v@toc@l+7([[REGSTRUCT]])
    135 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    136 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    137 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
    138 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
    139 ; POWER7-DAG: addi [[REG4_1:[0-9]+]], [[REG4_0]], 5
    140 ; POWER7-DAG: addi [[REG5_1:[0-9]+]], [[REG5_0]], 6
    141 ; POWER7-DAG: addi [[REG6_1:[0-9]+]], [[REG6_0]], 7
    142 ; POWER7-DAG: addi [[REG7_1:[0-9]+]], [[REG7_0]], 8
    143 ; POWER7-DAG: stb [[REG0_1]], b8v@toc@l([[REGSTRUCT]])
    144 ; POWER7-DAG: stb [[REG1_1]], b8v@toc@l+1([[REGSTRUCT]])
    145 ; POWER7-DAG: stb [[REG2_1]], b8v@toc@l+2([[REGSTRUCT]])
    146 ; POWER7-DAG: stb [[REG3_1]], b8v@toc@l+3([[REGSTRUCT]])
    147 ; POWER7-DAG: stb [[REG4_1]], b8v@toc@l+4([[REGSTRUCT]])
    148 ; POWER7-DAG: stb [[REG5_1]], b8v@toc@l+5([[REGSTRUCT]])
    149 ; POWER7-DAG: stb [[REG6_1]], b8v@toc@l+6([[REGSTRUCT]])
    150 ; POWER7-DAG: stb [[REG7_1]], b8v@toc@l+7([[REGSTRUCT]])
    151 
    152 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, b8v@toc@ha
    153 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], b8v@toc@l
    154 ; POWER8-DAG: lbz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
    155 ; POWER8-DAG: lbz [[REG1_0:[0-9]+]], 1([[REGSTRUCT]])
    156 ; POWER8-DAG: lbz [[REG2_0:[0-9]+]], 2([[REGSTRUCT]])
    157 ; POWER8-DAG: lbz [[REG3_0:[0-9]+]], 3([[REGSTRUCT]])
    158 ; POWER8-DAG: lbz [[REG4_0:[0-9]+]], 4([[REGSTRUCT]])
    159 ; POWER8-DAG: lbz [[REG5_0:[0-9]+]], 5([[REGSTRUCT]])
    160 ; POWER8-DAG: lbz [[REG6_0:[0-9]+]], 6([[REGSTRUCT]])
    161 ; POWER8-DAG: lbz [[REG7_0:[0-9]+]], 7([[REGSTRUCT]])
    162 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    163 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    164 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
    165 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
    166 ; POWER8-DAG: addi [[REG4_1:[0-9]+]], [[REG4_0]], 5
    167 ; POWER8-DAG: addi [[REG5_1:[0-9]+]], [[REG5_0]], 6
    168 ; POWER8-DAG: addi [[REG6_1:[0-9]+]], [[REG6_0]], 7
    169 ; POWER8-DAG: addi [[REG7_1:[0-9]+]], [[REG7_0]], 8
    170 ; POWER8-DAG: stb [[REG0_1]], 0([[REGSTRUCT]])
    171 ; POWER8-DAG: stb [[REG1_1]], 1([[REGSTRUCT]])
    172 ; POWER8-DAG: stb [[REG2_1]], 2([[REGSTRUCT]])
    173 ; POWER8-DAG: stb [[REG3_1]], 3([[REGSTRUCT]])
    174 ; POWER8-DAG: stb [[REG4_1]], 4([[REGSTRUCT]])
    175 ; POWER8-DAG: stb [[REG5_1]], 5([[REGSTRUCT]])
    176 ; POWER8-DAG: stb [[REG6_1]], 6([[REGSTRUCT]])
    177 ; POWER8-DAG: stb [[REG7_1]], 7([[REGSTRUCT]])
    178 define void @test_b8() nounwind {
    179 entry:
    180   %0 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
    181   %inc0 = add nsw i8 %0, 1
    182   store i8 %inc0, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
    183   %1 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
    184   %inc1 = add nsw i8 %1, 2
    185   store i8 %inc1, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
    186   %2 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
    187   %inc2 = add nsw i8 %2, 3
    188   store i8 %inc2, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
    189   %3 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
    190   %inc3 = add nsw i8 %3, 4
    191   store i8 %inc3, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
    192   %4 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
    193   %inc4 = add nsw i8 %4, 5
    194   store i8 %inc4, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
    195   %5 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
    196   %inc5 = add nsw i8 %5, 6
    197   store i8 %inc5, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
    198   %6 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
    199   %inc6 = add nsw i8 %6, 7
    200   store i8 %inc6, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
    201   %7 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
    202   %inc7 = add nsw i8 %7, 8
    203   store i8 %inc7, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
    204   ret void
    205 }
    206 
    207 ; CHECK-LABEL: test_h4:
    208 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, h4v@toc@ha
    209 ; POWER7-DAG: lhz [[REG0_0:[0-9]+]], h4v@toc@l([[REGSTRUCT]])
    210 ; POWER7-DAG: lhz [[REG1_0:[0-9]+]], h4v@toc@l+2([[REGSTRUCT]])
    211 ; POWER7-DAG: lhz [[REG2_0:[0-9]+]], h4v@toc@l+4([[REGSTRUCT]])
    212 ; POWER7-DAG: lhz [[REG3_0:[0-9]+]], h4v@toc@l+6([[REGSTRUCT]])
    213 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    214 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    215 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
    216 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
    217 ; POWER7-DAG: sth [[REG0_1]], h4v@toc@l([[REGSTRUCT]])
    218 ; POWER7-DAG: sth [[REG1_1]], h4v@toc@l+2([[REGSTRUCT]])
    219 ; POWER7-DAG: sth [[REG2_1]], h4v@toc@l+4([[REGSTRUCT]])
    220 ; POWER7-DAG: sth [[REG3_1]], h4v@toc@l+6([[REGSTRUCT]])
    221 
    222 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, h4v@toc@ha
    223 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], h4v@toc@l
    224 ; POWER8-DAG: lhz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
    225 ; POWER8-DAG: lhz [[REG1_0:[0-9]+]], 2([[REGSTRUCT]])
    226 ; POWER8-DAG: lhz [[REG2_0:[0-9]+]], 4([[REGSTRUCT]])
    227 ; POWER8-DAG: lhz [[REG3_0:[0-9]+]], 6([[REGSTRUCT]])
    228 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    229 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    230 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
    231 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
    232 ; POWER8-DAG: sth [[REG0_1]], 0([[REGSTRUCT]])
    233 ; POWER8-DAG: sth [[REG1_1]], 2([[REGSTRUCT]])
    234 ; POWER8-DAG: sth [[REG2_1]], 4([[REGSTRUCT]])
    235 ; POWER8-DAG: sth [[REG3_1]], 6([[REGSTRUCT]])
    236 define void @test_h4() nounwind {
    237 entry:
    238   %0 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
    239   %inc0 = add nsw i16 %0, 1
    240   store i16 %inc0, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
    241   %1 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
    242   %inc1 = add nsw i16 %1, 2
    243   store i16 %inc1, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
    244   %2 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
    245   %inc2 = add nsw i16 %2, 3
    246   store i16 %inc2, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
    247   %3 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
    248   %inc3 = add nsw i16 %3, 4
    249   store i16 %inc3, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
    250   ret void
    251 }
    252 
    253 ; CHECK-LABEL: test_w2:
    254 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, w2v@toc@ha
    255 ; POWER7-DAG: lwz [[REG0_0:[0-9]+]], w2v@toc@l([[REGSTRUCT]])
    256 ; POWER7-DAG: lwz [[REG1_0:[0-9]+]], w2v@toc@l+4([[REGSTRUCT]])
    257 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    258 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    259 ; POWER7-DAG: stw [[REG0_1]], w2v@toc@l([[REGSTRUCT]])
    260 ; POWER7-DAG: stw [[REG1_1]], w2v@toc@l+4([[REGSTRUCT]])
    261 
    262 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, w2v@toc@ha
    263 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], w2v@toc@l
    264 ; POWER8-DAG: lwz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
    265 ; POWER8-DAG: lwz [[REG1_0:[0-9]+]], 4([[REGSTRUCT]])
    266 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    267 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    268 ; POWER8-DAG: stw [[REG0_1]], 0([[REGSTRUCT]])
    269 ; POWER8-DAG: stw [[REG1_1]], 4([[REGSTRUCT]])
    270 define void @test_w2() nounwind {
    271 entry:
    272   %0 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
    273   %inc0 = add nsw i32 %0, 1
    274   store i32 %inc0, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
    275   %1 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
    276   %inc1 = add nsw i32 %1, 2
    277   store i32 %inc1, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
    278   ret void
    279 }
    280 
    281 ; CHECK-LABEL: test_d2:
    282 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
    283 ; POWER7-DAG: ld [[REG0_0:[0-9]+]], d2v@toc@l([[REGSTRUCT]])
    284 ; POWER7-DAG: ld [[REG1_0:[0-9]+]], d2v@toc@l+8([[REGSTRUCT]])
    285 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    286 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    287 ; POWER7-DAG: std [[REG0_1]], d2v@toc@l([[REGSTRUCT]])
    288 ; POWER7-DAG: std [[REG1_1]], d2v@toc@l+8([[REGSTRUCT]])
    289 
    290 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
    291 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], d2v@toc@l
    292 ; POWER8-DAG: ld [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
    293 ; POWER8-DAG: ld [[REG1_0:[0-9]+]], 8([[REGSTRUCT]])
    294 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    295 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
    296 ; POWER8-DAG: std [[REG0_1]], 0([[REGSTRUCT]])
    297 ; POWER8-DAG: std [[REG1_1]], 8([[REGSTRUCT]])
    298 define void @test_d2() nounwind {
    299 entry:
    300   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
    301   %inc0 = add nsw i64 %0, 1
    302   store i64 %inc0, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
    303   %1 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
    304   %inc1 = add nsw i64 %1, 2
    305   store i64 %inc1, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
    306   ret void
    307 }
    308 
    309 ; Make sure the optimization fires on power8 if there is a single use resulting
    310 ; in a better fusion opportunity.
    311 ; register 3 is the return value, so it should be chosen
    312 ; CHECK-LABEL: test_singleuse:
    313 ; CHECK: addis 3, 2, d2v@toc@ha
    314 ; CHECK: ld 3, d2v@toc@l+8(3)
    315 define i64 @test_singleuse() nounwind {
    316 entry:
    317   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
    318   ret i64 %0
    319 }
    320 
    321 ; Make sure the optimization fails to fire if the symbol is aligned, but the offset is not.
    322 ; CHECK-LABEL: test_misalign
    323 ; POWER7: addis [[REGSTRUCT_0:[0-9]+]], 2, misalign_v@toc@ha
    324 ; POWER7: addi [[REGSTRUCT:[0-9]+]], [[REGSTRUCT_0]], misalign_v@toc@l
    325 ; POWER7: li [[OFFSET_REG:[0-9]+]], 1
    326 ; POWER7: ldx [[REG0_0:[0-9]+]], [[REGSTRUCT]], [[OFFSET_REG]]
    327 ; POWER7: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
    328 ; POWER7: stdx [[REG0_1]], [[REGSTRUCT]], [[OFFSET_REG]]
    329 define void @test_misalign() nounwind {
    330 entry:
    331   %0 = load i64, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
    332   %inc0 = add nsw i64 %0, 1
    333   store i64 %inc0, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
    334   ret void
    335 }
    336