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