mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
bf8ef9fdc3
This is a repeat of 1880092722 from 2009. We should have less risk of hitting bugs at this point because we auto-generate positive CHECK lines only, but this makes things consistent. Copying the original commit msg: "Change tests from "opt %s" to "opt < %s" so that opt doesn't see the input filename so that opt doesn't print the input filename in the output so that grep lines in the tests don't unintentionally match strings in the input filename."
1140 lines
55 KiB
LLVM
1140 lines
55 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
; If we extract (via lshr) some high bits, and then perform their sign-extension
|
|
; conditionally depending on whether the extracted value is negative or not
|
|
; (i.e. interpreting the highest extracted bit, which was the original signbit
|
|
; of the value from which we extracted as a signbit), then we should just
|
|
; perform extraction via `ashr`.
|
|
|
|
; Base patterns.
|
|
|
|
declare void @use1(i1)
|
|
declare void @use16(i16)
|
|
declare void @use32(i32)
|
|
declare void @use64(i64)
|
|
|
|
define i32 @t0_notrunc_add(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t0_notrunc_add(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t0_notrunc_or(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t0_notrunc_or(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = or i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t1_notrunc_sub(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t1_notrunc_sub(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%higher_bit_after_signbit = shl i32 1, %nbits
|
|
%magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %higher_bit_after_signbit)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t2_trunc_add(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t2_trunc_add(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t2_trunc_or(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t2_trunc_or(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
|
|
%signextended = or i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t3_trunc_sub(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t3_trunc_sub(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%higher_bit_after_signbit = shl i32 1, %nbits
|
|
%magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0 ; one-use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %higher_bit_after_signbit)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
; Commutativity
|
|
|
|
define i32 @t4_commutativity0(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t4_commutativity0(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
define i32 @t5_commutativity1(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t5_commutativity1(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], -1
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp sgt i32 %data, -1 ; swapped
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; swapped
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
define i32 @t6_commutativity2(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t6_commutativity2(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted ; swapped
|
|
ret i32 %signextended
|
|
}
|
|
|
|
; Extra uses
|
|
|
|
define i32 @t7_trunc_extrause0(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t7_trunc_extrause0(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
define i32 @t8_trunc_extrause1(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t8_trunc_extrause1(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; one-use
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
define i32 @n9_trunc_extrause2(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n9_trunc_extrause2(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 64, %nbits
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32 ; has extra use
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; has extra use
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t10_preserve_exact(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @t10_preserve_exact(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr exact i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr exact i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr exact i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t11_different_zext_of_shamt(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @t11_different_zext_of_shamt(
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS:%.*]] to i16
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i16 32, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_32:%.*]] = zext i16 [[LOW_BITS_TO_SKIP]] to i32
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_32]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS]] to i32
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP_32]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP_32]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%low_bits_to_skip = sub i16 32, %nbits_16bit
|
|
%low_bits_to_skip_32 = zext i16 %low_bits_to_skip to i32
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip_32
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits_32bit
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %low_bits_to_skip)
|
|
call void @use32(i32 %low_bits_to_skip_32)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t12_add_sext_of_magic(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @t12_add_sext_of_magic(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
|
|
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
|
|
%magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
|
|
%magic_wide = sext i16 %magic to i32
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use16(i16 %magic)
|
|
call void @use32(i32 %magic_wide)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic_wide
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t13_sub_zext_of_magic(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @t13_sub_zext_of_magic(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
|
|
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 1, %nbits_16bit
|
|
%magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
|
|
%magic_wide = zext i16 %magic to i32
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use16(i16 %magic)
|
|
call void @use32(i32 %magic_wide)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic_wide
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t14_add_sext_of_shl(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @t14_add_sext_of_shl(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = sext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
|
|
%all_bits_except_low_nbits_wide = sext i16 %all_bits_except_low_nbits to i32
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %all_bits_except_low_nbits_wide)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @t15_sub_zext_of_shl(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @t15_sub_zext_of_shl(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = zext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 1, %nbits_16bit
|
|
%all_bits_except_low_nbits_wide = zext i16 %all_bits_except_low_nbits to i32
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits_wide, i32 0
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %all_bits_except_low_nbits_wide)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
; Negative tests.
|
|
|
|
define i32 @n16(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n16(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 31, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 31, %nbits ; not 32
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n17_add(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n17_add(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 1, %nbits ; not -1
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n18(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n18(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 0, i32 %all_bits_except_low_nbits ; wrong order
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n19(i32 %data1, i32 %data2, i32 %nbits) {
|
|
; CHECK-LABEL: @n19(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA1:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA2:%.*]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data1, %low_bits_to_skip ; not %data2
|
|
%should_signext = icmp slt i32 %data2, 0 ; not %data1
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n20(i32 %data, i32 %nbits1, i32 %nbits2) {
|
|
; CHECK-LABEL: @n20(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS1:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS2:%.*]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits1 ; not %nbits2
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits2 ; not %nbits1
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n21(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n21(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp sgt i32 %data, 0 ; this isn't a sign bit test
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n22(i64 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n22(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 63, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
|
|
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 63, %nbits ; not 64
|
|
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
|
|
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
|
|
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
|
|
%should_signext = icmp slt i64 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use64(i64 %low_bits_to_skip_wide)
|
|
call void @use64(i64 %high_bits_extracted_wide)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %magic, %high_bits_extracted
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n23(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n23(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = ashr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = ashr i32 %data, %low_bits_to_skip ; not `lshr`
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n24(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n24(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%higher_bit_after_signbit = shl i32 1, %nbits
|
|
%magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %higher_bit_after_signbit)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = sub i32 %magic, %high_bits_extracted ; wrong order; `sub` is not commutative
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n25_sub(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n25_sub(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGHER_BIT_AFTER_SIGNBIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%higher_bit_after_signbit = shl i32 -1, %nbits ; not 1
|
|
%magic = select i1 %should_signext, i32 %higher_bit_after_signbit, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %higher_bit_after_signbit)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n26(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n26(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 -1
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 -1, %nbits
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 -1 ; not 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n27_add_zext_of_magic(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @n27_add_zext_of_magic(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
|
|
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = add i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 -1, %nbits_16bit
|
|
%magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
|
|
%magic_wide = zext i16 %magic to i32 ; not sext
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use16(i16 %magic)
|
|
call void @use32(i32 %magic_wide)
|
|
|
|
%signextended = add i32 %high_bits_extracted, %magic_wide
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n28_sub_sext_of_magic(i32 %data, i8 %nbits) {
|
|
; CHECK-LABEL: @n28_sub_sext_of_magic(
|
|
; CHECK-NEXT: [[NBITS_32BIT:%.*]] = zext i8 [[NBITS:%.*]] to i32
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub nsw i32 32, [[NBITS_32BIT]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 1, [[NBITS_16BIT]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
|
|
; CHECK-NEXT: [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
|
|
; CHECK-NEXT: call void @use32(i32 [[NBITS_32BIT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[NBITS_16BIT]])
|
|
; CHECK-NEXT: call void @use16(i16 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use16(i16 [[MAGIC]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC_WIDE]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = sub i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC_WIDE]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%nbits_32bit = zext i8 %nbits to i32
|
|
%low_bits_to_skip = sub i32 32, %nbits_32bit
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%nbits_16bit = zext i8 %nbits to i16
|
|
%all_bits_except_low_nbits = shl i16 1, %nbits_16bit
|
|
%magic = select i1 %should_signext, i16 %all_bits_except_low_nbits, i16 0
|
|
%magic_wide = sext i16 %magic to i32 ; not zext
|
|
|
|
call void @use32(i32 %nbits_32bit)
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use16(i16 %nbits_16bit)
|
|
call void @use16(i16 %all_bits_except_low_nbits)
|
|
call void @use16(i16 %magic)
|
|
call void @use32(i32 %magic_wide)
|
|
|
|
%signextended = sub i32 %high_bits_extracted, %magic_wide
|
|
ret i32 %signextended
|
|
}
|
|
|
|
define i32 @n290_or_with_wrong_magic(i32 %data, i32 %nbits) {
|
|
; CHECK-LABEL: @n290_or_with_wrong_magic(
|
|
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
|
|
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
|
|
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
|
|
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 1, [[NBITS]]
|
|
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
|
|
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
|
|
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
|
|
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
|
|
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
|
|
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
|
|
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
|
|
;
|
|
%low_bits_to_skip = sub i32 32, %nbits
|
|
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
|
|
%should_signext = icmp slt i32 %data, 0
|
|
%all_bits_except_low_nbits = shl i32 1, %nbits ; not -1
|
|
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
|
|
|
|
call void @use32(i32 %low_bits_to_skip)
|
|
call void @use32(i32 %high_bits_extracted)
|
|
call void @use1(i1 %should_signext)
|
|
call void @use32(i32 %all_bits_except_low_nbits)
|
|
call void @use32(i32 %magic)
|
|
|
|
%signextended = or i32 %high_bits_extracted, %magic
|
|
ret i32 %signextended
|
|
}
|