Noah Goldstein 4fd3401e76 [KnownBits] Improve implementation of KnownBits::abs
`abs` preserves the lowest set bit, so if we know the lowest set bit,
set it in the output.

As well, implement the case where the operand is known negative.

Reviewed By: foad, RKSimon

Differential Revision: https://reviews.llvm.org/D150100
2023-05-23 13:52:39 -05:00

69 lines
1.8 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
declare i8 @llvm.abs.i8(i8, i1)
define i1 @abs_low_bit_set(i8 %x) {
; CHECK-LABEL: @abs_low_bit_set(
; CHECK-NEXT: ret i1 false
;
%xx = and i8 %x, 240
%v = or i8 %xx, 4
%abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
%and = and i8 %abs, 4
%r = icmp eq i8 %and, 0
ret i1 %r
}
define i1 @abs_unknown_low_bit_set_fail(i8 %x) {
; CHECK-LABEL: @abs_unknown_low_bit_set_fail(
; CHECK-NEXT: [[V:%.*]] = or i8 [[X:%.*]], 2
; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[V]], i1 true)
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ABS]], 2
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%v = or i8 %x, 2
%abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
%and = and i8 %abs, 2
%r = icmp eq i8 %and, 0
ret i1 %r
}
define i1 @abs_negative(i8 %x) {
; CHECK-LABEL: @abs_negative(
; CHECK-NEXT: ret i1 false
;
%xx = and i8 %x, 240
%v = or i8 %xx, 132
%abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
%and = and i8 %abs, 8
%r = icmp eq i8 %and, 0
ret i1 %r
}
define i1 @abs_negative2(i8 %x) {
; CHECK-LABEL: @abs_negative2(
; CHECK-NEXT: ret i1 false
;
%v = or i8 %x, 131
%abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
%and = and i8 %abs, 2
%r = icmp eq i8 %and, 2
ret i1 %r
}
define i1 @abs_negative_no_carry_info_fail(i8 %x) {
; CHECK-LABEL: @abs_negative_no_carry_info_fail(
; CHECK-NEXT: [[V:%.*]] = or i8 [[X:%.*]], -126
; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[V]], i1 true)
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ABS]], 2
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%v = or i8 %x, 130
%abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
%and = and i8 %abs, 2
%r = icmp eq i8 %and, 0
ret i1 %r
}