298 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+bmi2,+popcnt,+lzcnt | FileCheck %s3declare 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 %edi11; CHECK-NEXT: jne foo # TAILCALL12; CHECK-NEXT: # %bb.1: # %return13; CHECK-NEXT: retq14 %sub = sub i32 0, %x15 %cmp = icmp eq i32 %sub, 016 br i1 %cmp, label %return, label %bb17 18bb:19 tail call void @foo(i32 %sub)20 br label %return21 22return:23 ret void24}25 26define void @sar(i32 %x) nounwind {27; CHECK-LABEL: sar:28; CHECK: # %bb.0:29; CHECK-NEXT: sarl %edi30; CHECK-NEXT: jne foo # TAILCALL31; CHECK-NEXT: # %bb.1: # %return32; CHECK-NEXT: retq33 %ashr = ashr i32 %x, 134 %cmp = icmp eq i32 %ashr, 035 br i1 %cmp, label %return, label %bb36 37bb:38 tail call void @foo(i32 %ashr)39 br label %return40 41return:42 ret void43}44 45define void @shr(i32 %x) nounwind {46; CHECK-LABEL: shr:47; CHECK: # %bb.0:48; CHECK-NEXT: shrl %edi49; CHECK-NEXT: jne foo # TAILCALL50; CHECK-NEXT: # %bb.1: # %return51; CHECK-NEXT: retq52 %ashr = lshr i32 %x, 153 %cmp = icmp eq i32 %ashr, 054 br i1 %cmp, label %return, label %bb55 56bb:57 tail call void @foo(i32 %ashr)58 br label %return59 60return:61 ret void62}63 64define void @shri(i32 %x) nounwind {65; CHECK-LABEL: shri:66; CHECK: # %bb.0:67; CHECK-NEXT: shrl $3, %edi68; CHECK-NEXT: jne foo # TAILCALL69; CHECK-NEXT: # %bb.1: # %return70; CHECK-NEXT: retq71 %ashr = lshr i32 %x, 372 %cmp = icmp eq i32 %ashr, 073 br i1 %cmp, label %return, label %bb74 75bb:76 tail call void @foo(i32 %ashr)77 br label %return78 79return:80 ret void81}82 83define void @shl(i32 %x) nounwind {84; CHECK-LABEL: shl:85; CHECK: # %bb.0:86; CHECK-NEXT: addl %edi, %edi87; CHECK-NEXT: jne foo # TAILCALL88; CHECK-NEXT: # %bb.1: # %return89; CHECK-NEXT: retq90 %shl = shl i32 %x, 191 %cmp = icmp eq i32 %shl, 092 br i1 %cmp, label %return, label %bb93 94bb:95 tail call void @foo(i32 %shl)96 br label %return97 98return:99 ret void100}101 102define void @shli(i32 %x) nounwind {103; CHECK-LABEL: shli:104; CHECK: # %bb.0:105; CHECK-NEXT: shll $4, %edi106; CHECK-NEXT: jne foo # TAILCALL107; CHECK-NEXT: # %bb.1: # %return108; CHECK-NEXT: retq109 %shl = shl i32 %x, 4110 %cmp = icmp eq i32 %shl, 0111 br i1 %cmp, label %return, label %bb112 113bb:114 tail call void @foo(i32 %shl)115 br label %return116 117return:118 ret void119}120 121define zeroext i1 @adc(i128 %x) nounwind {122; CHECK-LABEL: adc:123; CHECK: # %bb.0:124; CHECK-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000125; CHECK-NEXT: addq %rdi, %rax126; CHECK-NEXT: adcq $0, %rsi127; CHECK-NEXT: sete %al128; CHECK-NEXT: retq129 %add = add i128 %x, 9223372036854775808130 %cmp = icmp ult i128 %add, 18446744073709551616131 ret i1 %cmp132}133 134define zeroext i1 @sbb(i128 %x, i128 %y) nounwind {135; CHECK-LABEL: sbb:136; CHECK: # %bb.0:137; CHECK-NEXT: cmpq %rdx, %rdi138; CHECK-NEXT: sbbq %rcx, %rsi139; CHECK-NEXT: setns %al140; CHECK-NEXT: retq141 %sub = sub i128 %x, %y142 %cmp = icmp sge i128 %sub, 0143 ret i1 %cmp144}145 146define void @andn(i32 %x, i32 %y) nounwind {147; CHECK-LABEL: andn:148; CHECK: # %bb.0:149; CHECK-NEXT: andnl %esi, %edi, %edi150; CHECK-NEXT: jne foo # TAILCALL151; CHECK-NEXT: # %bb.1: # %return152; CHECK-NEXT: retq153 %not = xor i32 %x, -1154 %andn = and i32 %y, %not155 %cmp = icmp eq i32 %andn, 0156 br i1 %cmp, label %return, label %bb157 158bb:159 tail call void @foo(i32 %andn)160 br label %return161 162return:163 ret void164}165 166declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone167define void @bextr(i32 %x, i32 %y) nounwind {168; CHECK-LABEL: bextr:169; CHECK: # %bb.0:170; CHECK-NEXT: bextrl %esi, %edi, %edi171; CHECK-NEXT: jne foo # TAILCALL172; CHECK-NEXT: # %bb.1: # %return173; CHECK-NEXT: retq174 %bextr = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)175 %cmp = icmp eq i32 %bextr, 0176 br i1 %cmp, label %return, label %bb177 178bb:179 tail call void @foo(i32 %bextr)180 br label %return181 182return:183 ret void184}185 186declare i32 @llvm.ctpop.i32(i32) nounwind readnone187define void @popcnt(i32 %x) nounwind {188; CHECK-LABEL: popcnt:189; CHECK: # %bb.0:190; CHECK-NEXT: popcntl %edi, %edi191; CHECK-NEXT: jne foo # TAILCALL192; CHECK-NEXT: # %bb.1: # %return193; CHECK-NEXT: retq194 %popcnt = tail call i32 @llvm.ctpop.i32(i32 %x)195 %cmp = icmp eq i32 %popcnt, 0196 br i1 %cmp, label %return, label %bb197bb:198 tail call void @foo(i32 %popcnt)199 br label %return200return:201 ret void202}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, %rcx209; CHECK-NEXT: movl $255, %eax210; CHECK-NEXT: cmovaeq %rcx, %rax211; CHECK-NEXT: retq212 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)213 %tobool = icmp eq i64 %v, 0214 %cond = select i1 %tobool, i64 255, i64 %cnt215 ret i64 %cond216}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 %rbx223; CHECK-NEXT: tzcntl %edi, %ebx224; CHECK-NEXT: jb .LBB12_2225; CHECK-NEXT: # %bb.1: # %bb226; CHECK-NEXT: movl %ebx, %edi227; CHECK-NEXT: callq foo228; CHECK-NEXT: .LBB12_2: # %return229; CHECK-NEXT: movl %ebx, %edi230; CHECK-NEXT: popq %rbx231; CHECK-NEXT: jmp foo32 # TAILCALL232 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)233 %cmp = icmp eq i32 %v, 0234 br i1 %cmp, label %return, label %bb235 236bb:237 tail call void @foo(i32 %cnt)238 br label %return239 240return:241 tail call void @foo32(i32 %cnt)242 ret void243}244 245define void @testCTZ3(i32 %v) nounwind {246; CHECK-LABEL: testCTZ3:247; CHECK: # %bb.0:248; CHECK-NEXT: pushq %rbx249; CHECK-NEXT: tzcntl %edi, %ebx250; CHECK-NEXT: jae .LBB13_2251; CHECK-NEXT: # %bb.1: # %bb252; CHECK-NEXT: movl %ebx, %edi253; CHECK-NEXT: callq foo254; CHECK-NEXT: .LBB13_2: # %return255; CHECK-NEXT: movl %ebx, %edi256; CHECK-NEXT: popq %rbx257; CHECK-NEXT: jmp foo32 # TAILCALL258 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)259 %cmp = icmp ne i32 %v, 0260 br i1 %cmp, label %return, label %bb261 262bb:263 tail call void @foo(i32 %cnt)264 br label %return265 266return:267 tail call void @foo32(i32 %cnt)268 ret void269}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, %rcx276; CHECK-NEXT: movl $255, %eax277; CHECK-NEXT: cmovaeq %rcx, %rax278; CHECK-NEXT: retq279 %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)280 %tobool = icmp ne i64 %v, 0281 %cond = select i1 %tobool, i64 %cnt, i64 255282 ret i64 %cond283}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, %rcx290; CHECK-NEXT: movl $255, %eax291; CHECK-NEXT: cmovneq %rcx, %rax292; CHECK-NEXT: retq293 %cnt = tail call i64 @llvm.ctpop.i64(i64 %v)294 %tobool = icmp ne i64 %v, 0295 %cond = select i1 %tobool, i64 %cnt, i64 255296 ret i64 %cond297}298