1; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s --check-prefix=ARM 2 3; RUN: llc -mtriple=arm-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - \ 4; RUN: | FileCheck %s --check-prefix=ARMT2 5 6; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m0 %s -o - \ 7; RUN: | FileCheck %s --check-prefix=THUMB1 8 9; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - \ 10; RUN: | FileCheck %s --check-prefix=THUMB2 11 12; RUN: llc -mtriple=thumbv8m.base-eabi %s -o - \ 13; RUN: | FileCheck %s --check-prefix=V8MBASE 14 15define i32 @t1(i32 %c) nounwind readnone { 16entry: 17; ARM-LABEL: t1: 18; ARM: mov [[R1:r[0-9]+]], #101 19; ARM: orr [[R1b:r[0-9]+]], [[R1]], #256 20; ARM: movgt {{r[0-1]}}, #123 21 22; ARMT2-LABEL: t1: 23; ARMT2: movw [[R:r[0-1]]], #357 24; ARMT2: movwgt [[R]], #123 25 26; THUMB1-LABEL: t1: 27; THUMB1: mov r1, r0 28; THUMB1: movs r2, #255 29; THUMB1: adds r2, #102 30; THUMB1: movs r0, #123 31; THUMB1: cmp r1, #1 32; THUMB1: bgt 33 34; THUMB2-LABEL: t1: 35; THUMB2: movw [[R:r[0-1]]], #357 36; THUMB2: movgt [[R]], #123 37 38 %0 = icmp sgt i32 %c, 1 39 %1 = select i1 %0, i32 123, i32 357 40 ret i32 %1 41} 42 43define i32 @t2(i32 %c) nounwind readnone { 44entry: 45; ARM-LABEL: t2: 46; ARM: mov [[R:r[0-9]+]], #101 47; ARM: orr [[R]], [[R]], #256 48; ARM: movle [[R]], #123 49 50; ARMT2-LABEL: t2: 51; ARMT2: mov [[R:r[0-1]]], #123 52; ARMT2: movwgt [[R]], #357 53 54; THUMB1-LABEL: t2: 55; THUMB1: cmp r{{[0-9]+}}, #1 56; THUMB1: bgt 57 58; THUMB2-LABEL: t2: 59; THUMB2: mov{{(s|\.w)}} [[R:r[0-1]]], #123 60; THUMB2: movwgt [[R]], #357 61 62 %0 = icmp sgt i32 %c, 1 63 %1 = select i1 %0, i32 357, i32 123 64 ret i32 %1 65} 66 67define i32 @t3(i32 %a) nounwind readnone { 68entry: 69; ARM-LABEL: t3: 70; ARM: mov [[R:r[0-1]]], #0 71; ARM: moveq [[R]], #1 72 73; ARMT2-LABEL: t3: 74; ARMT2: mov [[R:r[0-1]]], #0 75; ARMT2: movweq [[R]], #1 76 77; THUMB1-LABEL: t3: 78; THUMB1: mov r1, r0 79; THUMB1: movs r0, #1 80; THUMB1: movs r2, #0 81; THUMB1: cmp r1, #160 82; THUMB1: beq 83 84; THUMB2-LABEL: t3: 85; THUMB2: mov{{(s|\.w)}} [[R:r[0-1]]], #0 86; THUMB2: moveq [[R]], #1 87 %0 = icmp eq i32 %a, 160 88 %1 = zext i1 %0 to i32 89 ret i32 %1 90} 91 92define i32 @t4(i32 %a, i32 %b, i32 %x) nounwind { 93entry: 94; ARM-LABEL: t4: 95; ARM: ldr 96; ARM: mov{{lt|ge}} 97 98; ARMT2-LABEL: t4: 99; ARMT2: movwlt [[R0:r[0-9]+]], #65365 100; ARMT2: movtlt [[R0]], #65365 101 102; THUMB1-LABEL: t4: 103; THUMB1: cmp r{{[0-9]+}}, r{{[0-9]+}} 104; THUMB1: b{{lt|ge}} 105 106; THUMB2-LABEL: t4: 107; THUMB2: mvnlt [[R0:r[0-9]+]], #11141290 108 %0 = icmp slt i32 %a, %b 109 %1 = select i1 %0, i32 4283826005, i32 %x 110 ret i32 %1 111} 112 113; rdar://9758317 114define i32 @t5(i32 %a) nounwind { 115entry: 116; ARM-LABEL: t5: 117; ARM-NOT: mov 118; ARM: cmp r0, #1 119; ARM-NOT: mov 120; ARM: movne r0, #0 121 122; THUMB1-LABEL: t5: 123; THUMB1: mov r1, r0 124; THUMB1: movs r0, #0 125; THUMB1: cmp r1, #1 126; THUMB1: bne 127 128; THUMB2-LABEL: t5: 129; THUMB2-NOT: mov 130; THUMB2: cmp r0, #1 131; THUMB2: it ne 132; THUMB2: movne r0, #0 133 %cmp = icmp eq i32 %a, 1 134 %conv = zext i1 %cmp to i32 135 ret i32 %conv 136} 137 138define i32 @t6(i32 %a) nounwind { 139entry: 140; ARM-LABEL: t6: 141; ARM-NOT: mov 142; ARM: cmp r0, #0 143; ARM: movne r0, #1 144 145; THUMB1-LABEL: t6: 146; THUMB1: cmp r{{[0-9]+}}, #0 147; THUMB1: bne 148 149; THUMB2-LABEL: t6: 150; THUMB2-NOT: mov 151; THUMB2: cmp r0, #0 152; THUMB2: it ne 153; THUMB2: movne r0, #1 154 %tobool = icmp ne i32 %a, 0 155 %lnot.ext = zext i1 %tobool to i32 156 ret i32 %lnot.ext 157} 158 159define i32 @t7(i32 %a, i32 %b) nounwind readnone { 160entry: 161; ARM-LABEL: t7: 162; ARM: mov r2, #0 163; ARM: cmp r0, r1 164; ARM: movne r2, #1 165; ARM: lsl r0, r2, #2 166 167; ARMT2-LABEL: t7: 168; ARMT2: mov r2, #0 169; ARMT2: cmp r0, r1 170; ARMT2: movwne r2, #1 171; ARMT2: lsl r0, r2, #2 172 173; THUMB1-LABEL: t7: 174; THUMB1: movs r2, #1 175; THUMB1: movs r3, #0 176; THUMB1: cmp r0, r1 177; THUMB1: bne .LBB6_2 178; THUMB1: mov r2, r3 179; THUMB1: .LBB6_2: 180; THUMB1: lsls r0, r2, #2 181 182; THUMB2-LABEL: t7: 183; THUMB2: movs r2, #0 184; THUMB2: cmp r0, r1 185; THUMB2: it ne 186; THUMB2: movne r2, #1 187; THUMB2: lsls r0, r2, #2 188 %0 = icmp ne i32 %a, %b 189 %1 = select i1 %0, i32 4, i32 0 190 ret i32 %1 191} 192 193define void @t8(i32 %a) { 194entry: 195 196; ARM scheduler emits icmp/zext before both calls, so isn't relevant 197 198; ARMT2-LABEL: t8: 199; ARMT2: mov r1, r0 200; ARMT2: mov r0, #9 201; ARMT2: mov r4, #0 202; ARMT2: cmp r1, #5 203; ARMT2: movweq r4, #1 204; ARMT2: bl t7 205 206; THUMB1-LABEL: t8: 207; THUMB1: mov r1, r0 208; THUMB1: movs r4, #1 209; THUMB1: movs r0, #0 210; THUMB1: cmp r1, #5 211; THUMB1: beq .LBB7_2 212; THUMB1: mov r4, r0 213 214; THUMB2-LABEL: t8: 215; THUMB2: mov r1, r0 216; THUMB2: movs r4, #0 217; THUMB2: cmp r1, #5 218; THUMB2: it eq 219; THUMB2: moveq r4, #1 220 %cmp = icmp eq i32 %a, 5 221 %conv = zext i1 %cmp to i32 222 %call = tail call i32 @t7(i32 9, i32 %a) 223 tail call i32 @t7(i32 %conv, i32 %call) 224 ret void 225} 226 227define void @t9(i8* %a, i8 %b) { 228entry: 229 230; ARM scheduler emits icmp/zext before both calls, so isn't relevant 231 232; ARMT2-LABEL: t9: 233; ARMT2: cmp r4, r4 234; ARMT2: movweq r0, #1 235 236; THUMB1-LABEL: t9: 237; THUMB1: cmp r4, r4 238; THUMB1: beq .LBB8_2 239; THUMB1: mov r0, r1 240 241; THUMB2-LABEL: t9: 242; THUMB2: cmp r4, r4 243; THUMB2: it eq 244; THUMB2: moveq r0, #1 245 246 %0 = load i8, i8* %a 247 %conv = sext i8 %0 to i32 248 %conv119 = zext i8 %0 to i32 249 %conv522 = and i32 %conv, 255 250 %cmp723 = icmp eq i32 %conv522, %conv119 251 tail call void @f(i1 zeroext %cmp723) 252 br i1 %cmp723, label %while.body, label %while.end 253 254while.body: ; preds = %entry, %while.body 255 %ref.025 = phi i8 [ %inc9, %while.body ], [ %0, %entry ] 256 %in.024 = phi i32 [ %inc, %while.body ], [ %conv, %entry ] 257 %inc = add i32 %in.024, 1 258 %inc9 = add i8 %ref.025, 1 259 %conv1 = zext i8 %inc9 to i32 260 %cmp = icmp slt i32 %conv1, %conv119 261 %conv5 = and i32 %inc, 255 262 br i1 %cmp, label %while.body, label %while.end 263 264while.end: 265 ret void 266} 267 268declare void @f(i1 zeroext) 269 270 271define i1 @t10() { 272entry: 273 %q = alloca i32 274 %p = alloca i32 275 store i32 -3, i32* %q 276 store i32 -8, i32* %p 277 %0 = load i32, i32* %q 278 %1 = load i32, i32* %p 279 %div = sdiv i32 %0, %1 280 %mul = mul nsw i32 %div, %1 281 %rem = srem i32 %0, %1 282 %add = add nsw i32 %mul, %rem 283 %cmp = icmp eq i32 %add, %0 284 ret i1 %cmp 285 286; ARM-LABEL: t10: 287; ARM: mov r0, #0 288; ARM: cmn r1, #3 289; ARM: moveq r0, #1 290 291; ARMT2-LABEL: t10: 292; ARMT2: mov r0, #0 293; ARMT2: cmn r1, #3 294; ARMT2: movweq r0, #1 295 296; THUMB1-LABEL: t10: 297; THUMB1: movs r0, #1 298; THUMB1: movs r1, #0 299; THUMB1: cmp r2, r5 300; THUMB1: beq .LBB9_2 301; THUMB1: mov r0, r1 302 303; THUMB2-LABEL: t10: 304; THUMB2: adds r0, #3 305; THUMB2: mov.w r0, #0 306; THUMB2: it eq 307; THUMB2: moveq r0, #1 308 309; V8MBASE-LABEL: t10: 310; V8MBASE-NOT: movs r0, #0 311; V8MBASE: movs r0, #7 312} 313 314define i1 @t11() { 315entry: 316 %bit = alloca i32 317 %load = load i32, i32* %bit 318 %clear = and i32 %load, -4096 319 %set = or i32 %clear, 33 320 store i32 %set, i32* %bit 321 %load1 = load i32, i32* %bit 322 %clear2 = and i32 %load1, -33550337 323 %set3 = or i32 %clear2, 40960 324 %clear5 = and i32 %set3, 4095 325 %rem = srem i32 %clear5, 10 326 %clear9 = and i32 %set3, -4096 327 %set10 = or i32 %clear9, %rem 328 store i32 %set10, i32* %bit 329 %clear12 = and i32 %set10, 4095 330 %cmp = icmp eq i32 %clear12, 3 331 ret i1 %cmp 332 333; ARM-LABEL: t11: 334; ARM: mov r0, #0 335; ARM: cmp r1, #3 336; ARM: moveq r0, #1 337 338; ARMT2-LABEL: t11: 339; ARMT2: mov r0, #0 340; ARMT2: cmp r1, #3 341; ARMT2: movweq r0, #1 342 343; THUMB1-LABEL: t11: 344; THUMB1-NOT: movs r0, #0 345; THUMB1: movs r0, #5 346 347; THUMB2-LABEL: t11: 348; THUMB2: movs r0, #0 349; THUMB2: cmp r1, #3 350; THUMB2: it eq 351; THUMB2: moveq r0, #1 352 353; V8MBASE-LABEL: t11: 354; V8MBASE-NOT: movs r0, #0 355; V8MBASE: movw r0, #40960 356} 357