1 ; RUN: llc < %s -mtriple=arm-apple-darwin -mcpu=cortex-a8 | FileCheck %s -check-prefix=ARM 2 ; RUN: llc < %s -mtriple=thumb-apple-darwin -mcpu=cortex-a8 | FileCheck %s -check-prefix=T2 3 ; rdar://8662825 4 5 define i32 @t1(i32 %a, i32 %b, i32 %c) nounwind { 6 ; ARM-LABEL: t1: 7 ; ARM: suble r1, r1, #-2147483647 8 ; ARM: mov r0, r1 9 10 ; T2-LABEL: t1: 11 ; T2: mvn r0, #-2147483648 12 ; T2: addle r1, r0 13 ; T2: mov r0, r1 14 %tmp1 = icmp sgt i32 %c, 10 15 %tmp2 = select i1 %tmp1, i32 0, i32 2147483647 16 %tmp3 = add i32 %tmp2, %b 17 ret i32 %tmp3 18 } 19 20 define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 21 ; ARM-LABEL: t2: 22 ; ARM: suble r1, r1, #10 23 ; ARM: mov r0, r1 24 25 ; T2-LABEL: t2: 26 ; T2: suble r1, #10 27 ; T2: mov r0, r1 28 %tmp1 = icmp sgt i32 %c, 10 29 %tmp2 = select i1 %tmp1, i32 0, i32 10 30 %tmp3 = sub i32 %b, %tmp2 31 ret i32 %tmp3 32 } 33 34 define i32 @t3(i32 %a, i32 %b, i32 %x, i32 %y) nounwind { 35 ; ARM-LABEL: t3: 36 ; ARM: andge r3, r3, r2 37 ; ARM: mov r0, r3 38 39 ; T2-LABEL: t3: 40 ; T2: andge r3, r2 41 ; T2: mov r0, r3 42 %cond = icmp slt i32 %a, %b 43 %z = select i1 %cond, i32 -1, i32 %x 44 %s = and i32 %z, %y 45 ret i32 %s 46 } 47 48 define i32 @t4(i32 %a, i32 %b, i32 %x, i32 %y) nounwind { 49 ; ARM-LABEL: t4: 50 ; ARM: orrge r3, r3, r2 51 ; ARM: mov r0, r3 52 53 ; T2-LABEL: t4: 54 ; T2: orrge r3, r2 55 ; T2: mov r0, r3 56 %cond = icmp slt i32 %a, %b 57 %z = select i1 %cond, i32 0, i32 %x 58 %s = or i32 %z, %y 59 ret i32 %s 60 } 61 62 define i32 @t5(i32 %a, i32 %b, i32 %c) nounwind { 63 entry: 64 ; ARM-LABEL: t5: 65 ; ARM-NOT: moveq 66 ; ARM: orreq r2, r2, #1 67 68 ; T2-LABEL: t5: 69 ; T2-NOT: moveq 70 ; T2: orreq r2, r2, #1 71 %tmp1 = icmp eq i32 %a, %b 72 %tmp2 = zext i1 %tmp1 to i32 73 %tmp3 = or i32 %tmp2, %c 74 ret i32 %tmp3 75 } 76 77 define i32 @t6(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 78 ; ARM-LABEL: t6: 79 ; ARM-NOT: movge 80 ; ARM: eorlt r3, r3, r2 81 82 ; T2-LABEL: t6: 83 ; T2-NOT: movge 84 ; T2: eorlt r3, r2 85 %cond = icmp slt i32 %a, %b 86 %tmp1 = select i1 %cond, i32 %c, i32 0 87 %tmp2 = xor i32 %tmp1, %d 88 ret i32 %tmp2 89 } 90 91 define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind { 92 entry: 93 ; ARM-LABEL: t7: 94 ; ARM-NOT: lsleq 95 ; ARM: andeq r2, r2, r2, lsl #1 96 97 ; T2-LABEL: t7: 98 ; T2-NOT: lsleq.w 99 ; T2: andeq.w r2, r2, r2, lsl #1 100 %tmp1 = shl i32 %c, 1 101 %cond = icmp eq i32 %a, %b 102 %tmp2 = select i1 %cond, i32 %tmp1, i32 -1 103 %tmp3 = and i32 %c, %tmp2 104 ret i32 %tmp3 105 } 106 107 ; Fold ORRri into movcc. 108 define i32 @t8(i32 %a, i32 %b) nounwind { 109 ; ARM-LABEL: t8: 110 ; ARM: cmp r0, r1 111 ; ARM: orrge r0, r1, #1 112 113 ; T2-LABEL: t8: 114 ; T2: cmp r0, r1 115 ; T2: orrge r0, r1, #1 116 %x = or i32 %b, 1 117 %cond = icmp slt i32 %a, %b 118 %tmp1 = select i1 %cond, i32 %a, i32 %x 119 ret i32 %tmp1 120 } 121 122 ; Fold ANDrr into movcc. 123 define i32 @t9(i32 %a, i32 %b, i32 %c) nounwind { 124 ; ARM-LABEL: t9: 125 ; ARM: cmp r0, r1 126 ; ARM: andge r0, r1, r2 127 128 ; T2-LABEL: t9: 129 ; T2: cmp r0, r1 130 ; T2: andge.w r0, r1, r2 131 %x = and i32 %b, %c 132 %cond = icmp slt i32 %a, %b 133 %tmp1 = select i1 %cond, i32 %a, i32 %x 134 ret i32 %tmp1 135 } 136 137 ; Fold EORrs into movcc. 138 define i32 @t10(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 139 ; ARM-LABEL: t10: 140 ; ARM: cmp r0, r1 141 ; ARM: eorge r0, r1, r2, lsl #7 142 143 ; T2-LABEL: t10: 144 ; T2: cmp r0, r1 145 ; T2: eorge.w r0, r1, r2, lsl #7 146 %s = shl i32 %c, 7 147 %x = xor i32 %b, %s 148 %cond = icmp slt i32 %a, %b 149 %tmp1 = select i1 %cond, i32 %a, i32 %x 150 ret i32 %tmp1 151 } 152 153 ; Fold ORRri into movcc, reversing the condition. 154 define i32 @t11(i32 %a, i32 %b) nounwind { 155 ; ARM-LABEL: t11: 156 ; ARM: cmp r0, r1 157 ; ARM: orrlt r0, r1, #1 158 159 ; T2-LABEL: t11: 160 ; T2: cmp r0, r1 161 ; T2: orrlt r0, r1, #1 162 %x = or i32 %b, 1 163 %cond = icmp slt i32 %a, %b 164 %tmp1 = select i1 %cond, i32 %x, i32 %a 165 ret i32 %tmp1 166 } 167 168 ; Fold ADDri12 into movcc 169 define i32 @t12(i32 %a, i32 %b) nounwind { 170 ; ARM-LABEL: t12: 171 ; ARM: cmp r0, r1 172 ; ARM: addge r0, r1, 173 174 ; T2-LABEL: t12: 175 ; T2: cmp r0, r1 176 ; T2: addwge r0, r1, #3000 177 %x = add i32 %b, 3000 178 %cond = icmp slt i32 %a, %b 179 %tmp1 = select i1 %cond, i32 %a, i32 %x 180 ret i32 %tmp1 181 } 182 183 ; Handle frame index operands. 184 define void @pr13628() nounwind uwtable align 2 { 185 %x3 = alloca i8, i32 256, align 8 186 %x4 = load i8, i8* undef, align 1 187 %x5 = icmp ne i8 %x4, 0 188 %x6 = select i1 %x5, i8* %x3, i8* null 189 call void @bar(i8* %x6) nounwind 190 ret void 191 } 192 declare void @bar(i8*) 193 194 ; Fold zext i1 into predicated add 195 define i32 @t13(i32 %c, i32 %a) nounwind readnone ssp { 196 entry: 197 ; ARM: t13 198 ; ARM: cmp r1, #10 199 ; ARM: addgt r0, r0, #1 200 201 ; T2: t13 202 ; T2: cmp r1, #10 203 ; T2: addgt r0, #1 204 %cmp = icmp sgt i32 %a, 10 205 %conv = zext i1 %cmp to i32 206 %add = add i32 %conv, %c 207 ret i32 %add 208 } 209 210 ; Fold sext i1 into predicated sub 211 define i32 @t14(i32 %c, i32 %a) nounwind readnone ssp { 212 entry: 213 ; ARM: t14 214 ; ARM: cmp r1, #10 215 ; ARM: subgt r0, r0, #1 216 217 ; T2: t14 218 ; T2: cmp r1, #10 219 ; T2: subgt r0, #1 220 %cmp = icmp sgt i32 %a, 10 221 %conv = sext i1 %cmp to i32 222 %add = add i32 %conv, %c 223 ret i32 %add 224 } 225 226 ; Do not fold the xor into the select 227 define i32 @t15(i32 %p) { 228 entry: 229 ; ARM-LABEL: t15: 230 ; ARM: mov [[REG:r[0-9]+]], #2 231 ; ARM: cmp r0, #8 232 ; ARM: movwgt [[REG:r[0-9]+]], #1 233 ; ARM: eor r0, [[REG:r[0-9]+]], #1 234 235 ; T2-LABEL: t15: 236 ; T2: movs [[REG:r[0-9]+]], #2 237 ; T2: cmp [[REG:r[0-9]+]], #8 238 ; T2: it gt 239 ; T2: movgt [[REG:r[0-9]+]], #1 240 ; T2: eor r0, [[REG:r[0-9]+]], #1 241 %cmp = icmp sgt i32 %p, 8 242 %a = select i1 %cmp, i32 1, i32 2 243 %xor = xor i32 %a, 1 244 ret i32 %xor 245 } 246 247 define i32 @t16(i32 %x, i32 %y) { 248 entry: 249 ; ARM-LABEL: t16: 250 ; ARM: and r0, {{r[0-9]+}}, {{r[0-9]+}} 251 252 ; T2-LABEL: t16: 253 ; T2: ands r0, {{r[0-9]+}} 254 %cmp = icmp eq i32 %x, 0 255 %cond = select i1 %cmp, i32 5, i32 2 256 %cmp1 = icmp eq i32 %y, 0 257 %cond2 = select i1 %cmp1, i32 3, i32 4 258 %and = and i32 %cond2, %cond 259 ret i32 %and 260 } 261 262 define i32 @t17(i32 %x, i32 %y) #0 { 263 entry: 264 ; ARM-LABEL: t17: 265 ; ARM: and r0, {{r[0-9]+}}, {{r[0-9]+}} 266 267 ; T2-LABEL: t17: 268 ; T2: ands r0, {{r[0-9]+}} 269 %cmp = icmp eq i32 %x, -1 270 %cond = select i1 %cmp, i32 5, i32 2 271 %cmp1 = icmp eq i32 %y, -1 272 %cond2 = select i1 %cmp1, i32 3, i32 4 273 %and = and i32 %cond2, %cond 274 ret i32 %and 275 } 276 277 define i32 @t18(i32 %x, i32 %y) #0 { 278 entry: 279 ; ARM-LABEL: t18: 280 ; ARM: and r0, {{r[0-9]+}}, {{r[0-9]+}} 281 282 ; T2-LABEL: t18: 283 ; T2: and.w r0, {{r[0-9]+}} 284 %cmp = icmp ne i32 %x, 0 285 %cond = select i1 %cmp, i32 5, i32 2 286 %cmp1 = icmp ne i32 %x, -1 287 %cond2 = select i1 %cmp1, i32 3, i32 4 288 %and = and i32 %cond2, %cond 289 ret i32 %and 290 } 291 292 define i32 @t19(i32 %x, i32 %y) #0 { 293 entry: 294 ; ARM-LABEL: t19: 295 ; ARM: orr r0, {{r[0-9]+}}, {{r[0-9]+}} 296 297 ; T2-LABEL: t19: 298 ; T2: orrs r0, {{r[0-9]+}} 299 %cmp = icmp ne i32 %x, 0 300 %cond = select i1 %cmp, i32 5, i32 2 301 %cmp1 = icmp ne i32 %y, 0 302 %cond2 = select i1 %cmp1, i32 3, i32 4 303 %or = or i32 %cond2, %cond 304 ret i32 %or 305 } 306 307 define i32 @t20(i32 %x, i32 %y) #0 { 308 entry: 309 ; ARM-LABEL: t20: 310 ; ARM: orr r0, {{r[0-9]+}}, {{r[0-9]+}} 311 312 ; T2-LABEL: t20: 313 ; T2: orrs r0, {{r[0-9]+}} 314 %cmp = icmp ne i32 %x, -1 315 %cond = select i1 %cmp, i32 5, i32 2 316 %cmp1 = icmp ne i32 %y, -1 317 %cond2 = select i1 %cmp1, i32 3, i32 4 318 %or = or i32 %cond2, %cond 319 ret i32 %or 320 } 321 322 define <2 x i32> @t21(<2 x i32> %lhs, <2 x i32> %rhs) { 323 ; CHECK-LABEL: t21: 324 ; CHECK-NOT: eor 325 ; CHECK: mvn 326 ; CHECK-NOT: eor 327 %tst = icmp eq <2 x i32> %lhs, %rhs 328 %ntst = xor <2 x i1> %tst, <i1 1 , i1 undef> 329 %btst = sext <2 x i1> %ntst to <2 x i32> 330 ret <2 x i32> %btst 331 } 332