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