llvm-project/llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll
Jay Foad f82c55fa08 [InstCombine] Change order of canonicalization of ADD and AND
Canonicalize ((x + C1) & C2) --> ((x & C2) + C1) for suitable constants
C1 and C2, instead of the other way round. This should allow more
constant ADDs to be matched as part of addressing modes for loads and
stores.

Differential Revision: https://reviews.llvm.org/D130080
2022-08-22 20:03:53 +01:00

502 lines
23 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
declare void @use.i8(i8)
declare void @use.v2i4(<2 x i4>)
declare void @use.i1(i1)
declare void @llvm.assume(i1)
; Basic pattern
define i8 @t0(i8 %x) {
; CHECK-LABEL: @t0(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED1]], -16
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Another alignment is fine
define i8 @t1(i8 %x) {
; CHECK-LABEL: @t1(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add i8 [[X:%.*]], 31
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED1]], -32
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 31
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 32
%x.biased.highbits = and i8 %x.biased, -32
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Bias can be either the alignment or alignment-1
define i8 @t2(i8 %x) {
; CHECK-LABEL: @t2(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED1]], -16
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 15
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; select is commutative
define i8 @t3_commutative(i8 %x) {
; CHECK-LABEL: @t3_commutative(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_NOT_ZERO:%.*]] = icmp ne i8 [[X_LOWBITS]], 0
; CHECK-NEXT: call void @use.i1(i1 [[X_LOWBITS_ARE_NOT_ZERO]])
; CHECK-NEXT: [[X_BIASED1:%.*]] = add i8 [[X]], 15
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED1]], -16
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.not.zero = icmp ne i8 %x.lowbits, 0
call void @use.i1(i1 %x.lowbits.are.not.zero)
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.not.zero, i8 %x.biased.highbits, i8 %x
ret i8 %x.roundedup
}
; Basic splat vector test
define <2 x i8> @t4_splat(<2 x i8> %x) {
; CHECK-LABEL: @t4_splat(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED1]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 15>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 16>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -16>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
; Splat-with-undef
define <2 x i8> @t5_splat_undef_0b0001(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_undef_0b0001(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED1]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 15>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 16>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 undef>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t5_splat_undef_0b0010(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_undef_0b0010(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED1]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 15>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 undef>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -16>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t5_splat_undef_0b0100(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_undef_0b0100(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED1]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 15>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 undef>
%x.biased = add <2 x i8> %x, <i8 16, i8 16>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -16>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t5_splat_undef_0b1000(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_undef_0b1000(
; CHECK-NEXT: [[X_BIASED1:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED1]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 undef>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 16>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -16>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
; Basic non-splat vector test
define <2 x i8> @t6_nonsplat(<2 x i8> %x) {
; CHECK-LABEL: @t6_nonsplat(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 31>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 16, i8 32>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -32>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 31>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 32>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -32>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
; Even if the alignment (and masks) are splat, the bias could be non-splat
define <2 x i8> @t7_nonsplat_bias(<2 x i8> %x) {
; CHECK-LABEL: @t7_nonsplat_bias(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 15, i8 16>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -16>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 15>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 15, i8 16>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -16>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
; Splat-in-disguise vector tests
define <2 x i8> @t8_nonsplat_masked_by_undef_0b0001(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0001(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 31>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 16, i8 32>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 undef>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 31>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 32>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 undef>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t8_nonsplat_masked_by_undef_0b0010(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0010(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 31>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 16, i8 undef>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -32>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 31>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 undef>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -32>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t8_nonsplat_masked_by_undef_0b0100(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0100(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 31>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], <i8 0, i8 undef>
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 16, i8 32>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -32>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 31>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 undef>
%x.biased = add <2 x i8> %x, <i8 16, i8 32>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -32>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
define <2 x i8> @t8_nonsplat_masked_by_undef_0b1000(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b1000(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 undef>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], <i8 16, i8 32>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -32>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 undef>
%x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, <i8 0, i8 0>
%x.biased = add <2 x i8> %x, <i8 16, i8 32>
%x.biased.highbits = and <2 x i8> %x.biased, <i8 -16, i8 -32>
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits
ret <2 x i8> %x.roundedup
}
; The X are different
define i8 @n9_wrong_x0(i8 %x.0, i8 %x.1) {
; CHECK-LABEL: @n9_wrong_x0(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_0:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X_0]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_1:%.*]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x.0, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x.0, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.1, i8 %x.biased.highbits
ret i8 %x.roundedup
}
define i8 @n9_wrong_x1(i8 %x.0, i8 %x.1) {
; CHECK-LABEL: @n9_wrong_x1(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_0:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X_1:%.*]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_0]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x.0, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x.1, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.0, i8 %x.biased.highbits
ret i8 %x.roundedup
}
define i8 @n9_wrong_x2(i8 %x.0, i8 %x.1) {
; CHECK-LABEL: @n9_wrong_x2(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_1:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X_0:%.*]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_0]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x.1, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x.0, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.0, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Wrong low-bit mask
define i8 @n10_wrong_low_bit_mask(i8 %x) {
; CHECK-LABEL: @n10_wrong_low_bit_mask(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 31
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 31
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Wrong high-bit mask
define i8 @n11_wrong_high_bit_mask(i8 %x) {
; CHECK-LABEL: @n11_wrong_high_bit_mask(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -32
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -32
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Wrong bias
define i8 @n12_wrong_bias(i8 %x) {
; CHECK-LABEL: @n12_wrong_bias(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 32
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 32
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Wrong constants
define i8 @n13_wrong_constants_alignment_is_not_power_of_two(i8 %x) {
; CHECK-LABEL: @n13_wrong_constants_alignment_is_not_power_of_two(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 2
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 3
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -3
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 2
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 3
%x.biased.highbits = and i8 %x.biased, -3
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Comparison is not with zero
define i8 @n14_wrong_comparison_constant(i8 %x) {
; CHECK-LABEL: @n14_wrong_comparison_constant(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 1
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 1
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Wrong comparison
define i8 @n15_wrong_comparison_predicate_and_constant(i8 %x) {
; CHECK-LABEL: @n15_wrong_comparison_predicate_and_constant(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 14
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp ult i8 %x.lowbits, 2
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; %x.biased.highbits must not have other uses
define i8 @n16_oneuse(i8 %x) {
; CHECK-LABEL: @n16_oneuse(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -16
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = add i8 [[TMP1]], 16
; CHECK-NEXT: call void @use.i8(i8 [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 16
%x.biased.highbits = and i8 %x.biased, -16
call void @use.i8(i8 %x.biased.highbits)
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; But if bias is equal to low-bit mask, then we *could* just replace %x.roundedup with %x.biased.highbits
define i8 @t17_oneuse(i8 %x) {
; CHECK-LABEL: @t17_oneuse(
; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16
; CHECK-NEXT: call void @use.i8(i8 [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: ret i8 [[X_BIASED_HIGHBITS]]
;
%x.lowbits = and i8 %x, 15
%x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0
%x.biased = add i8 %x, 15
%x.biased.highbits = and i8 %x.biased, -16
call void @use.i8(i8 %x.biased.highbits)
%x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits
ret i8 %x.roundedup
}
; Bias is equal to the alignment-1 (as opposed to alignment),
; so we can just replace %x.roundedup with %x.biased.highbits
define <2 x i4> @t18_replacement_0b0001(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b0001(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 3>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 undef>
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
;
%x.lowbits = and <2 x i4> %x, <i4 3, i4 3>
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 0>
%x.biased = add <2 x i4> %x, <i4 3, i4 3>
%x.biased.highbits = and <2 x i4> %x.biased, <i4 -4, i4 undef>
call void @use.v2i4(<2 x i4> %x.biased.highbits)
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits
ret <2 x i4> %x.roundedup
}
define <2 x i4> @t18_replacement_0b0010(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b0010(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 undef>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 -4>
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
;
%x.lowbits = and <2 x i4> %x, <i4 3, i4 3>
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 0>
%x.biased = add <2 x i4> %x, <i4 3, i4 undef>
%x.biased.highbits = and <2 x i4> %x.biased, <i4 -4, i4 -4>
call void @use.v2i4(<2 x i4> %x.biased.highbits)
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits
ret <2 x i4> %x.roundedup
}
define <2 x i4> @t18_replacement_0b0100(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b0100(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 3>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 -4>
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
;
%x.lowbits = and <2 x i4> %x, <i4 3, i4 3>
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 undef>
%x.biased = add <2 x i4> %x, <i4 3, i4 3>
%x.biased.highbits = and <2 x i4> %x.biased, <i4 -4, i4 -4>
call void @use.v2i4(<2 x i4> %x.biased.highbits)
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits
ret <2 x i4> %x.roundedup
}
define <2 x i4> @t18_replacement_0b1000(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b1000(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X:%.*]], <i4 3, i4 3>
; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], <i4 -4, i4 -4>
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: ret <2 x i4> [[X_BIASED_HIGHBITS]]
;
%x.lowbits = and <2 x i4> %x, <i4 3, i4 undef>
%x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, <i4 0, i4 0>
%x.biased = add <2 x i4> %x, <i4 3, i4 3>
%x.biased.highbits = and <2 x i4> %x.biased, <i4 -4, i4 -4>
call void @use.v2i4(<2 x i4> %x.biased.highbits)
%x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits
ret <2 x i4> %x.roundedup
}