-; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+bmi2,+popcnt | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+bmi2,+popcnt,+lzcnt | FileCheck %s
declare void @foo(i32)
+declare void @foo32(i32)
declare void @foo64(i64)
-; CHECK: neg:
+; CHECK-LABEL: neg:
; CHECK: negl %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: sar:
+; CHECK-LABEL: sar:
; CHECK: sarl %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: shr:
+; CHECK-LABEL: shr:
; CHECK: shrl %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: shri:
+; CHECK-LABEL: shri:
; CHECK: shrl $3, %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: shl:
+; CHECK-LABEL: shl:
; CHECK: addl %edi, %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: shli:
+; CHECK-LABEL: shli:
; CHECK: shll $4, %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: adc:
+; CHECK-LABEL: adc:
; CHECK: movabsq $-9223372036854775808, %rax
; CHECK-NEXT: addq %rdi, %rax
; CHECK-NEXT: adcq $0, %rsi
ret i1 %cmp
}
-; CHECK: sbb:
+; CHECK-LABEL: sbb:
; CHECK: cmpq %rdx, %rdi
; CHECK-NEXT: sbbq %rcx, %rsi
; CHECK-NEXT: setns %al
ret i1 %cmp
}
-; CHECK: andn:
+; CHECK-LABEL: andn:
; CHECK: andnl %esi, %edi, %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: bextr:
+; CHECK-LABEL: bextr:
; CHECK: bextrl %esi, %edi, %edi
; CHECK-NEXT: je
; CHECK: jmp foo
ret void
}
-; CHECK: popcnt:
+; CHECK-LABEL: popcnt:
; CHECK: popcntl
; CHECK-NEXT: je
; CHECK: jmp foo
return:
ret void
}
+
+; CHECK-LABEL: testCTZ
+; CHECK: tzcntq
+; CHECK-NOT: test
+; CHECK: cmovaeq
+declare i64 @llvm.cttz.i64(i64, i1)
+define i64 @testCTZ(i64 %v) nounwind {
+ %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true)
+ %tobool = icmp eq i64 %v, 0
+ %cond = select i1 %tobool, i64 255, i64 %cnt
+ ret i64 %cond
+}
+
+; CHECK-LABEL: testCTZ2
+; CHECK: tzcntl
+; CHECK-NEXT: jb
+; CHECK: jmp foo
+declare i32 @llvm.cttz.i32(i32, i1)
+define void @testCTZ2(i32 %v) nounwind {
+ %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
+ %cmp = icmp eq i32 %v, 0
+ br i1 %cmp, label %return, label %bb
+
+bb:
+ tail call void @foo(i32 %cnt)
+ br label %return
+
+return:
+ tail call void @foo32(i32 %cnt)
+ ret void
+}
+
+; CHECK-LABEL: testCTZ3
+; CHECK: tzcntl
+; CHECK-NEXT: jae
+; CHECK: jmp foo
+define void @testCTZ3(i32 %v) nounwind {
+ %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
+ %cmp = icmp ne i32 %v, 0
+ br i1 %cmp, label %return, label %bb
+
+bb:
+ tail call void @foo(i32 %cnt)
+ br label %return
+
+return:
+ tail call void @foo32(i32 %cnt)
+ ret void
+}
+
+; CHECK-LABEL: testCLZ
+; CHECK: lzcntq
+; CHECK-NOT: test
+; CHECK: cmovaeq
+declare i64 @llvm.ctlz.i64(i64, i1)
+define i64 @testCLZ(i64 %v) nounwind {
+ %cnt = tail call i64 @llvm.ctlz.i64(i64 %v, i1 true)
+ %tobool = icmp ne i64 %v, 0
+ %cond = select i1 %tobool, i64 %cnt, i64 255
+ ret i64 %cond
+}
+
+; CHECK-LABEL: testPOPCNT
+; CHECK: popcntq
+; CHECK-NOT: test
+; CHECK: cmovneq
+declare i64 @llvm.ctpop.i64(i64)
+define i64 @testPOPCNT(i64 %v) nounwind {
+ %cnt = tail call i64 @llvm.ctpop.i64(i64 %v)
+ %tobool = icmp ne i64 %v, 0
+ %cond = select i1 %tobool, i64 %cnt, i64 255
+ ret i64 %cond
+}