1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3 4; Various tests for ands that should be implemented with movzx, but aren't due 5; demanded bits shortcomings. 6 7; The backend will insert a zext to promote the shift to i32. 8define i16 @test1(i16 %x) { 9; CHECK-LABEL: test1: 10; CHECK: # %bb.0: 11; CHECK-NEXT: movzwl %di, %eax 12; CHECK-NEXT: shrl %eax 13; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 14; CHECK-NEXT: retq 15 %y = lshr i16 %x, 1 16 ret i16 %y 17} 18 19define i32 @test2(i32 %x) { 20; CHECK-LABEL: test2: 21; CHECK: # %bb.0: 22; CHECK-NEXT: movzwl %di, %eax 23; CHECK-NEXT: shrl %eax 24; CHECK-NEXT: retq 25 %y = and i32 %x, 65535 26 %z = lshr i32 %y, 1 27 ret i32 %z 28} 29 30define i32 @test3(i32 %x) { 31; CHECK-LABEL: test3: 32; CHECK: # %bb.0: 33; CHECK-NEXT: movzbl %dil, %eax 34; CHECK-NEXT: shrl %eax 35; CHECK-NEXT: retq 36 %y = and i32 %x, 255 37 %z = lshr i32 %y, 1 38 ret i32 %z 39} 40 41define i16 @test4(i16 %x) { 42; CHECK-LABEL: test4: 43; CHECK: # %bb.0: 44; CHECK-NEXT: movzbl %dil, %eax 45; CHECK-NEXT: shrl %eax 46; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 47; CHECK-NEXT: retq 48 %y = and i16 %x, 255 49 %z = lshr i16 %y, 1 50 ret i16 %z 51} 52 53define i16 @test5(i16 %x) { 54; CHECK-LABEL: test5: 55; CHECK: # %bb.0: 56; CHECK-NEXT: movzwl %di, %eax 57; CHECK-NEXT: shrl $9, %eax 58; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 59; CHECK-NEXT: retq 60 %y = lshr i16 %x, 9 61 ret i16 %y 62} 63 64define i32 @test6(i32 %x) { 65; CHECK-LABEL: test6: 66; CHECK: # %bb.0: 67; CHECK-NEXT: movzwl %di, %eax 68; CHECK-NEXT: shrl $9, %eax 69; CHECK-NEXT: retq 70 %y = and i32 %x, 65535 71 %z = lshr i32 %y, 9 72 ret i32 %z 73} 74 75; TODO: We could turn this and into a zero extend. 76define i32 @test7(i32 %x) { 77; CHECK-LABEL: test7: 78; CHECK: # %bb.0: 79; CHECK-NEXT: orl $1, %edi 80; CHECK-NEXT: movzwl %di, %eax 81; CHECK-NEXT: retq 82 %y = and i32 %x, 65534 83 %z = or i32 %y, 1 84 ret i32 %z 85} 86 87; We actually get a movzx on this one, but only because we canonicalize the and 88; after the or before SimplifyDemandedBits messes it up. 89define i32 @test8(i32 %x) { 90; CHECK-LABEL: test8: 91; CHECK: # %bb.0: 92; CHECK-NEXT: orl $1, %edi 93; CHECK-NEXT: movzwl %di, %eax 94; CHECK-NEXT: retq 95 %y = and i32 %x, 65535 96 %z = or i32 %y, 1 97 ret i32 %z 98} 99 100define i64 @add_neg_one(i64 %x) { 101; CHECK-LABEL: add_neg_one: 102; CHECK: # %bb.0: 103; CHECK-NEXT: leal -1(%rdi), %eax 104; CHECK-NEXT: andl %edi, %eax 105; CHECK-NEXT: movzwl %ax, %eax 106; CHECK-NEXT: retq 107 %a1 = and i64 %x, 65535 108 %a2 = add i64 %x, 65535 109 %r = and i64 %a1, %a2 110 ret i64 %r 111} 112 113define i64 @sub_neg_one(i64 %x) { 114; CHECK-LABEL: sub_neg_one: 115; CHECK: # %bb.0: 116; CHECK-NEXT: leal -65535(%rdi), %eax 117; CHECK-NEXT: andl %edi, %eax 118; CHECK-NEXT: movzwl %ax, %eax 119; CHECK-NEXT: retq 120 %a1 = and i64 %x, 65535 121 %a2 = sub i64 %x, 65535 122 %r = and i64 %a1, %a2 123 ret i64 %r 124} 125 126define i64 @mul_neg_one(i64 %x) { 127; CHECK-LABEL: mul_neg_one: 128; CHECK: # %bb.0: 129; CHECK-NEXT: movl %edi, %eax 130; CHECK-NEXT: negl %eax 131; CHECK-NEXT: andl %edi, %eax 132; CHECK-NEXT: movzwl %ax, %eax 133; CHECK-NEXT: retq 134 %a1 = and i64 %x, 65535 135 %a2 = mul i64 %x, 65535 136 %r = and i64 %a1, %a2 137 ret i64 %r 138} 139 140define i32 @PR36689(i32*) { 141; CHECK-LABEL: PR36689: 142; CHECK: # %bb.0: 143; CHECK-NEXT: movzwl (%rdi), %eax 144; CHECK-NEXT: orl $255, %eax 145; CHECK-NEXT: retq 146 %2 = load i32, i32* %0 147 %3 = and i32 %2, 65280 148 %4 = or i32 %3, 255 149 ret i32 %4 150} 151