[NFC][InstCombine] Tests for bit test via highest sign-bit extract (w/ trunc) (PR43564)
authorRoman Lebedev <lebedev.ri@gmail.com>
Fri, 4 Oct 2019 22:15:41 +0000 (22:15 +0000)
committerRoman Lebedev <lebedev.ri@gmail.com>
Fri, 4 Oct 2019 22:15:41 +0000 (22:15 +0000)
https://rise4fun.com/Alive/x5IS

llvm-svn: 373798

llvm/test/Transforms/InstCombine/sign-bit-test-via-right-shifting-all-other-bits.ll [new file with mode: 0644]

diff --git a/llvm/test/Transforms/InstCombine/sign-bit-test-via-right-shifting-all-other-bits.ll b/llvm/test/Transforms/InstCombine/sign-bit-test-via-right-shifting-all-other-bits.ll
new file mode 100644 (file)
index 0000000..da744eb
--- /dev/null
@@ -0,0 +1,182 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define i1 @highest_bit_test_via_lshr(i32 %data, i32 %nbits) {
+; CHECK-LABEL: @highest_bit_test_via_lshr(
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[DATA:%.*]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %num_low_bits_to_skip = sub i32 32, %nbits
+  %high_bits_extracted = lshr i32 %data, %num_low_bits_to_skip
+  %skip_all_bits_till_signbit = sub i32 %nbits, 1
+  %signbit = lshr i32 %high_bits_extracted, %skip_all_bits_till_signbit
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+
+define i1 @highest_bit_test_via_lshr_with_truncation(i64 %data, i32 %nbits) {
+; CHECK-LABEL: @highest_bit_test_via_lshr_with_truncation(
+; CHECK-NEXT:    [[NUM_LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
+; CHECK-NEXT:    [[NUM_LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[NUM_LOW_BITS_TO_SKIP]] to i64
+; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i64 [[DATA:%.*]], [[NUM_LOW_BITS_TO_SKIP_WIDE]]
+; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_NARROW:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED]] to i32
+; CHECK-NEXT:    [[SKIP_ALL_BITS_TILL_SIGNBIT:%.*]] = add i32 [[NBITS]], -1
+; CHECK-NEXT:    [[SIGNBIT:%.*]] = lshr i32 [[HIGH_BITS_EXTRACTED_NARROW]], [[SKIP_ALL_BITS_TILL_SIGNBIT]]
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNBIT]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %num_low_bits_to_skip = sub i32 64, %nbits
+  %num_low_bits_to_skip_wide = zext i32 %num_low_bits_to_skip to i64
+  %high_bits_extracted = lshr i64 %data, %num_low_bits_to_skip_wide
+  %high_bits_extracted_narrow = trunc i64 %high_bits_extracted to i32
+  %skip_all_bits_till_signbit = sub i32 %nbits, 1
+  %signbit = lshr i32 %high_bits_extracted_narrow, %skip_all_bits_till_signbit
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+
+define i1 @highest_bit_test_via_ashr(i32 %data, i32 %nbits) {
+; CHECK-LABEL: @highest_bit_test_via_ashr(
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[DATA:%.*]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %num_low_bits_to_skip = sub i32 32, %nbits
+  %high_bits_extracted = ashr i32 %data, %num_low_bits_to_skip
+  %skip_all_bits_till_signbit = sub i32 %nbits, 1
+  %signbit = ashr i32 %high_bits_extracted, %skip_all_bits_till_signbit
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+
+define i1 @highest_bit_test_via_ashr_with_truncation(i64 %data, i32 %nbits) {
+; CHECK-LABEL: @highest_bit_test_via_ashr_with_truncation(
+; CHECK-NEXT:    [[NUM_LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
+; CHECK-NEXT:    [[NUM_LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[NUM_LOW_BITS_TO_SKIP]] to i64
+; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = ashr i64 [[DATA:%.*]], [[NUM_LOW_BITS_TO_SKIP_WIDE]]
+; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_NARROW:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED]] to i32
+; CHECK-NEXT:    [[SKIP_ALL_BITS_TILL_SIGNBIT:%.*]] = add i32 [[NBITS]], -1
+; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i32 [[HIGH_BITS_EXTRACTED_NARROW]], [[SKIP_ALL_BITS_TILL_SIGNBIT]]
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNBIT]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %num_low_bits_to_skip = sub i32 64, %nbits
+  %num_low_bits_to_skip_wide = zext i32 %num_low_bits_to_skip to i64
+  %high_bits_extracted = ashr i64 %data, %num_low_bits_to_skip_wide
+  %high_bits_extracted_narrow = trunc i64 %high_bits_extracted to i32
+  %skip_all_bits_till_signbit = sub i32 %nbits, 1
+  %signbit = ashr i32 %high_bits_extracted_narrow, %skip_all_bits_till_signbit
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+
+declare void @use32(i32)
+declare void @use64(i64)
+
+define i1 @unsigned_sign_bit_extract(i32 %x) {
+; CHECK-LABEL: @unsigned_sign_bit_extract(
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signbit = lshr i32 %x, 31
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+define i1 @unsigned_sign_bit_extract_extrause(i32 %x) {
+; CHECK-LABEL: @unsigned_sign_bit_extract_extrause(
+; CHECK-NEXT:    [[SIGNBIT:%.*]] = lshr i32 [[X:%.*]], 31
+; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT]])
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNBIT]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signbit = lshr i32 %x, 31
+  call void @use32(i32 %signbit)
+  %isneg = icmp ne i32 %signbit, 0
+  ret i1 %isneg
+}
+define i1 @unsigned_sign_bit_extract_extrause__ispositive(i32 %x) {
+; CHECK-LABEL: @unsigned_sign_bit_extract_extrause__ispositive(
+; CHECK-NEXT:    [[SIGNBIT:%.*]] = lshr i32 [[X:%.*]], 31
+; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT]])
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp eq i32 [[SIGNBIT]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signbit = lshr i32 %x, 31
+  call void @use32(i32 %signbit)
+  %isneg = icmp eq i32 %signbit, 0
+  ret i1 %isneg
+}
+define i1 @signed_sign_bit_extract(i32 %x) {
+; CHECK-LABEL: @signed_sign_bit_extract(
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signsmear = ashr i32 %x, 31
+  %isneg = icmp ne i32 %signsmear, 0
+  ret i1 %isneg
+}
+define i1 @signed_sign_bit_extract_extrause(i32 %x) {
+; CHECK-LABEL: @signed_sign_bit_extract_extrause(
+; CHECK-NEXT:    [[SIGNSMEAR:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:    call void @use32(i32 [[SIGNSMEAR]])
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNSMEAR]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signsmear = ashr i32 %x, 31
+  call void @use32(i32 %signsmear)
+  %isneg = icmp ne i32 %signsmear, 0
+  ret i1 %isneg
+}
+define i1 @unsigned_sign_bit_extract_with_trunc(i64 %x) {
+; CHECK-LABEL: @unsigned_sign_bit_extract_with_trunc(
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i64 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signbit = lshr i64 %x, 63
+  %signbit_narrow = trunc i64 %signbit to i32
+  %isneg = icmp ne i32 %signbit_narrow, 0
+  ret i1 %isneg
+}
+define i1 @unsigned_sign_bit_extract_with_trunc_extrause(i64 %x) {
+; CHECK-LABEL: @unsigned_sign_bit_extract_with_trunc_extrause(
+; CHECK-NEXT:    [[SIGNBIT:%.*]] = lshr i64 [[X:%.*]], 63
+; CHECK-NEXT:    call void @use64(i64 [[SIGNBIT]])
+; CHECK-NEXT:    [[SIGNBIT_NARROW:%.*]] = trunc i64 [[SIGNBIT]] to i32
+; CHECK-NEXT:    call void @use32(i32 [[SIGNBIT_NARROW]])
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNBIT_NARROW]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signbit = lshr i64 %x, 63
+  call void @use64(i64 %signbit)
+  %signbit_narrow = trunc i64 %signbit to i32
+  call void @use32(i32 %signbit_narrow)
+  %isneg = icmp ne i32 %signbit_narrow, 0
+  ret i1 %isneg
+}
+define i1 @signed_sign_bit_extract_trunc(i64 %x) {
+; CHECK-LABEL: @signed_sign_bit_extract_trunc(
+; CHECK-NEXT:    [[SIGNSMEAR:%.*]] = ashr i64 [[X:%.*]], 63
+; CHECK-NEXT:    [[SIGNSMEAR_NARROW:%.*]] = trunc i64 [[SIGNSMEAR]] to i32
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNSMEAR_NARROW]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signsmear = ashr i64 %x, 63
+  %signsmear_narrow = trunc i64 %signsmear to i32
+  %isneg = icmp ne i32 %signsmear_narrow, 0
+  ret i1 %isneg
+}
+define i1 @signed_sign_bit_extract_trunc_extrause(i64 %x) {
+; CHECK-LABEL: @signed_sign_bit_extract_trunc_extrause(
+; CHECK-NEXT:    [[SIGNSMEAR:%.*]] = ashr i64 [[X:%.*]], 63
+; CHECK-NEXT:    call void @use64(i64 [[SIGNSMEAR]])
+; CHECK-NEXT:    [[SIGNSMEAR_NARROW:%.*]] = trunc i64 [[SIGNSMEAR]] to i32
+; CHECK-NEXT:    call void @use32(i32 [[SIGNSMEAR_NARROW]])
+; CHECK-NEXT:    [[ISNEG:%.*]] = icmp ne i32 [[SIGNSMEAR_NARROW]], 0
+; CHECK-NEXT:    ret i1 [[ISNEG]]
+;
+  %signsmear = ashr i64 %x, 63
+  call void @use64(i64 %signsmear)
+  %signsmear_narrow = trunc i64 %signsmear to i32
+  call void @use32(i32 %signsmear_narrow)
+  %isneg = icmp ne i32 %signsmear_narrow, 0
+  ret i1 %isneg
+}