mirror of
https://github.com/RPCS3/llvm.git
synced 2026-08-27 11:01:30 -04:00
ebc007dabb
Summary: I noticed that passing known bits across these intrinsics isn't great at capturing the information we really know. Turning known bits of the input into known bits of a count output isn't able to convey a lot of what we really know. This patch adds range metadata to these intrinsics based on the known bits. Currently the patch punts if we already have range metadata present. Reviewers: spatel, RKSimon, davide, majnemer Reviewed By: RKSimon Subscribers: sanjoy, hfinkel, llvm-commits Differential Revision: https://reviews.llvm.org/D32582 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305927 91177308-0d34-0410-b5e6-96231b3b80d8
98 lines
2.9 KiB
LLVM
98 lines
2.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -S -instcombine | FileCheck %s
|
|
|
|
declare i32 @llvm.ctpop.i32(i32)
|
|
declare i8 @llvm.ctpop.i8(i8)
|
|
declare i1 @llvm.ctpop.i1(i1)
|
|
declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)
|
|
declare void @llvm.assume(i1)
|
|
|
|
define i1 @test1(i32 %arg) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%and = and i32 %arg, 15
|
|
%cnt = call i32 @llvm.ctpop.i32(i32 %and)
|
|
%res = icmp eq i32 %cnt, 9
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @test2(i32 %arg) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%and = and i32 %arg, 1
|
|
%cnt = call i32 @llvm.ctpop.i32(i32 %and)
|
|
%res = icmp eq i32 %cnt, 2
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @test3(i32 %arg) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: [[ASSUME:%.*]] = icmp eq i32 [[ARG:%.*]], 0
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
;; Use an assume to make all the bits known without triggering constant
|
|
;; folding. This is trying to hit a corner case where we have to avoid
|
|
;; taking the log of 0.
|
|
%assume = icmp eq i32 %arg, 0
|
|
call void @llvm.assume(i1 %assume)
|
|
%cnt = call i32 @llvm.ctpop.i32(i32 %arg)
|
|
%res = icmp eq i32 %cnt, 2
|
|
ret i1 %res
|
|
}
|
|
|
|
; Negative test for when we know nothing
|
|
define i1 @test4(i8 %arg) {
|
|
; CHECK-LABEL: @test4(
|
|
; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctpop.i8(i8 [[ARG:%.*]]), !range ![[RANGE:[0-9]+]]
|
|
; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[CNT]], 2
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
%cnt = call i8 @llvm.ctpop.i8(i8 %arg)
|
|
%res = icmp eq i8 %cnt, 2
|
|
ret i1 %res
|
|
}
|
|
|
|
; Test when the number of possible known bits isn't one less than a power of 2
|
|
; and the compare value is greater but less than the next power of 2.
|
|
define i1 @test5(i32 %arg) {
|
|
; CHECK-LABEL: @test5(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%and = and i32 %arg, 3
|
|
%cnt = call i32 @llvm.ctpop.i32(i32 %and)
|
|
%res = icmp eq i32 %cnt, 3
|
|
ret i1 %res
|
|
}
|
|
|
|
; Test when the number of possible known bits isn't one less than a power of 2
|
|
; and the compare value is greater but less than the next power of 2.
|
|
; TODO: The icmp is unnecessary given the known bits of the input, but range
|
|
; metadata doesn't support vectors
|
|
define <2 x i1> @test5vec(<2 x i32> %arg) {
|
|
; CHECK-LABEL: @test5vec(
|
|
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3>
|
|
; CHECK-NEXT: [[CNT:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[AND]])
|
|
; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i32> [[CNT]], <i32 3, i32 3>
|
|
; CHECK-NEXT: ret <2 x i1> [[RES]]
|
|
;
|
|
%and = and <2 x i32> %arg, <i32 3, i32 3>
|
|
%cnt = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %and)
|
|
%res = icmp eq <2 x i32> %cnt, <i32 3, i32 3>
|
|
ret <2 x i1> %res
|
|
}
|
|
|
|
; Make sure we don't add range metadata to i1 ctpop.
|
|
define i1 @test6(i1 %arg) {
|
|
; CHECK-LABEL: @test6(
|
|
; CHECK-NEXT: [[CNT:%.*]] = call i1 @llvm.ctpop.i1(i1 [[ARG:%.*]])
|
|
; CHECK-NEXT: ret i1 [[CNT]]
|
|
;
|
|
%cnt = call i1 @llvm.ctpop.i1(i1 %arg)
|
|
ret i1 %cnt
|
|
}
|
|
|
|
; CHECK: ![[RANGE]] = !{i8 0, i8 9}
|