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
502 lines
23 KiB
LLVM
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
|
|
}
|