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