1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+bmi2,+popcnt,+lzcnt | FileCheck %s 3declare dso_local void @foo(i32) 4declare dso_local void @foo32(i32) 5declare dso_local void @foo64(i64) 6 7define void @neg(i32 %x) nounwind { 8; CHECK-LABEL: neg: 9; CHECK: # %bb.0: 10; CHECK-NEXT: negl %edi 11; CHECK-NEXT: jne foo # TAILCALL 12; CHECK-NEXT: # %bb.1: # %return 13; CHECK-NEXT: retq 14 %sub = sub i32 0, %x 15 %cmp = icmp eq i32 %sub, 0 16 br i1 %cmp, label %return, label %bb 17 18bb: 19 tail call void @foo(i32 %sub) 20 br label %return 21 22return: 23 ret void 24} 25 26define void @sar(i32 %x) nounwind { 27; CHECK-LABEL: sar: 28; CHECK: # %bb.0: 29; CHECK-NEXT: sarl %edi 30; CHECK-NEXT: jne foo # TAILCALL 31; CHECK-NEXT: # %bb.1: # %return 32; CHECK-NEXT: retq 33 %ashr = ashr i32 %x, 1 34 %cmp = icmp eq i32 %ashr, 0 35 br i1 %cmp, label %return, label %bb 36 37bb: 38 tail call void @foo(i32 %ashr) 39 br label %return 40 41return: 42 ret void 43} 44 45define void @shr(i32 %x) nounwind { 46; CHECK-LABEL: shr: 47; CHECK: # %bb.0: 48; CHECK-NEXT: shrl %edi 49; CHECK-NEXT: jne foo # TAILCALL 50; CHECK-NEXT: # %bb.1: # %return 51; CHECK-NEXT: retq 52 %ashr = lshr i32 %x, 1 53 %cmp = icmp eq i32 %ashr, 0 54 br i1 %cmp, label %return, label %bb 55 56bb: 57 tail call void @foo(i32 %ashr) 58 br label %return 59 60return: 61 ret void 62} 63 64define void @shri(i32 %x) nounwind { 65; CHECK-LABEL: shri: 66; CHECK: # %bb.0: 67; CHECK-NEXT: shrl $3, %edi 68; CHECK-NEXT: jne foo # TAILCALL 69; CHECK-NEXT: # %bb.1: # %return 70; CHECK-NEXT: retq 71 %ashr = lshr i32 %x, 3 72 %cmp = icmp eq i32 %ashr, 0 73 br i1 %cmp, label %return, label %bb 74 75bb: 76 tail call void @foo(i32 %ashr) 77 br label %return 78 79return: 80 ret void 81} 82 83define void @shl(i32 %x) nounwind { 84; CHECK-LABEL: shl: 85; CHECK: # %bb.0: 86; CHECK-NEXT: addl %edi, %edi 87; CHECK-NEXT: jne foo # TAILCALL 88; CHECK-NEXT: # %bb.1: # %return 89; CHECK-NEXT: retq 90 %shl = shl i32 %x, 1 91 %cmp = icmp eq i32 %shl, 0 92 br i1 %cmp, label %return, label %bb 93 94bb: 95 tail call void @foo(i32 %shl) 96 br label %return 97 98return: 99 ret void 100} 101 102define void @shli(i32 %x) nounwind { 103; CHECK-LABEL: shli: 104; CHECK: # %bb.0: 105; CHECK-NEXT: shll $4, %edi 106; CHECK-NEXT: jne foo # TAILCALL 107; CHECK-NEXT: # %bb.1: # %return 108; CHECK-NEXT: retq 109 %shl = shl i32 %x, 4 110 %cmp = icmp eq i32 %shl, 0 111 br i1 %cmp, label %return, label %bb 112 113bb: 114 tail call void @foo(i32 %shl) 115 br label %return 116 117return: 118 ret void 119} 120 121define zeroext i1 @adc(i128 %x) nounwind { 122; CHECK-LABEL: adc: 123; CHECK: # %bb.0: 124; CHECK-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000 125; CHECK-NEXT: addq %rdi, %rax 126; CHECK-NEXT: adcq $0, %rsi 127; CHECK-NEXT: sete %al 128; CHECK-NEXT: retq 129 %add = add i128 %x, 9223372036854775808 130 %cmp = icmp ult i128 %add, 18446744073709551616 131 ret i1 %cmp 132} 133 134define zeroext i1 @sbb(i128 %x, i128 %y) nounwind { 135; CHECK-LABEL: sbb: 136; CHECK: # %bb.0: 137; CHECK-NEXT: cmpq %rdx, %rdi 138; CHECK-NEXT: sbbq %rcx, %rsi 139; CHECK-NEXT: setns %al 140; CHECK-NEXT: retq 141 %sub = sub i128 %x, %y 142 %cmp = icmp sge i128 %sub, 0 143 ret i1 %cmp 144} 145 146define void @andn(i32 %x, i32 %y) nounwind { 147; CHECK-LABEL: andn: 148; CHECK: # %bb.0: 149; CHECK-NEXT: andnl %esi, %edi, %edi 150; CHECK-NEXT: jne foo # TAILCALL 151; CHECK-NEXT: # %bb.1: # %return 152; CHECK-NEXT: retq 153 %not = xor i32 %x, -1 154 %andn = and i32 %y, %not 155 %cmp = icmp eq i32 %andn, 0 156 br i1 %cmp, label %return, label %bb 157 158bb: 159 tail call void @foo(i32 %andn) 160 br label %return 161 162return: 163 ret void 164} 165 166declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone 167define void @bextr(i32 %x, i32 %y) nounwind { 168; CHECK-LABEL: bextr: 169; CHECK: # %bb.0: 170; CHECK-NEXT: bextrl %esi, %edi, %edi 171; CHECK-NEXT: jne foo # TAILCALL 172; CHECK-NEXT: # %bb.1: # %return 173; CHECK-NEXT: retq 174 %bextr = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y) 175 %cmp = icmp eq i32 %bextr, 0 176 br i1 %cmp, label %return, label %bb 177 178bb: 179 tail call void @foo(i32 %bextr) 180 br label %return 181 182return: 183 ret void 184} 185 186declare i32 @llvm.ctpop.i32(i32) nounwind readnone 187define void @popcnt(i32 %x) nounwind { 188; CHECK-LABEL: popcnt: 189; CHECK: # %bb.0: 190; CHECK-NEXT: popcntl %edi, %edi 191; CHECK-NEXT: jne foo # TAILCALL 192; CHECK-NEXT: # %bb.1: # %return 193; CHECK-NEXT: retq 194 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %x) 195 %cmp = icmp eq i32 %popcnt, 0 196 br i1 %cmp, label %return, label %bb 197bb: 198 tail call void @foo(i32 %popcnt) 199 br label %return 200return: 201 ret void 202} 203 204declare i64 @llvm.cttz.i64(i64, i1) 205define i64 @testCTZ(i64 %v) nounwind { 206; CHECK-LABEL: testCTZ: 207; CHECK: # %bb.0: 208; CHECK-NEXT: tzcntq %rdi, %rcx 209; CHECK-NEXT: movl $255, %eax 210; CHECK-NEXT: cmovaeq %rcx, %rax 211; CHECK-NEXT: retq 212 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 213 %tobool = icmp eq i64 %v, 0 214 %cond = select i1 %tobool, i64 255, i64 %cnt 215 ret i64 %cond 216} 217 218declare i32 @llvm.cttz.i32(i32, i1) 219define void @testCTZ2(i32 %v) nounwind { 220; CHECK-LABEL: testCTZ2: 221; CHECK: # %bb.0: 222; CHECK-NEXT: pushq %rbx 223; CHECK-NEXT: tzcntl %edi, %ebx 224; CHECK-NEXT: jb .LBB12_2 225; CHECK-NEXT: # %bb.1: # %bb 226; CHECK-NEXT: movl %ebx, %edi 227; CHECK-NEXT: callq foo 228; CHECK-NEXT: .LBB12_2: # %return 229; CHECK-NEXT: movl %ebx, %edi 230; CHECK-NEXT: popq %rbx 231; CHECK-NEXT: jmp foo32 # TAILCALL 232 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 233 %cmp = icmp eq i32 %v, 0 234 br i1 %cmp, label %return, label %bb 235 236bb: 237 tail call void @foo(i32 %cnt) 238 br label %return 239 240return: 241 tail call void @foo32(i32 %cnt) 242 ret void 243} 244 245define void @testCTZ3(i32 %v) nounwind { 246; CHECK-LABEL: testCTZ3: 247; CHECK: # %bb.0: 248; CHECK-NEXT: pushq %rbx 249; CHECK-NEXT: tzcntl %edi, %ebx 250; CHECK-NEXT: jae .LBB13_2 251; CHECK-NEXT: # %bb.1: # %bb 252; CHECK-NEXT: movl %ebx, %edi 253; CHECK-NEXT: callq foo 254; CHECK-NEXT: .LBB13_2: # %return 255; CHECK-NEXT: movl %ebx, %edi 256; CHECK-NEXT: popq %rbx 257; CHECK-NEXT: jmp foo32 # TAILCALL 258 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 259 %cmp = icmp ne i32 %v, 0 260 br i1 %cmp, label %return, label %bb 261 262bb: 263 tail call void @foo(i32 %cnt) 264 br label %return 265 266return: 267 tail call void @foo32(i32 %cnt) 268 ret void 269} 270 271declare i64 @llvm.ctlz.i64(i64, i1) 272define i64 @testCLZ(i64 %v) nounwind { 273; CHECK-LABEL: testCLZ: 274; CHECK: # %bb.0: 275; CHECK-NEXT: lzcntq %rdi, %rcx 276; CHECK-NEXT: movl $255, %eax 277; CHECK-NEXT: cmovaeq %rcx, %rax 278; CHECK-NEXT: retq 279 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true) 280 %tobool = icmp ne i64 %v, 0 281 %cond = select i1 %tobool, i64 %cnt, i64 255 282 ret i64 %cond 283} 284 285declare i64 @llvm.ctpop.i64(i64) 286define i64 @testPOPCNT(i64 %v) nounwind { 287; CHECK-LABEL: testPOPCNT: 288; CHECK: # %bb.0: 289; CHECK-NEXT: popcntq %rdi, %rcx 290; CHECK-NEXT: movl $255, %eax 291; CHECK-NEXT: cmovneq %rcx, %rax 292; CHECK-NEXT: retq 293 %cnt = tail call i64 @llvm.ctpop.i64(i64 %v) 294 %tobool = icmp ne i64 %v, 0 295 %cond = select i1 %tobool, i64 %cnt, i64 255 296 ret i64 %cond 297} 298