Files
clang-p2996/llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll
Nikita Popov 525d00e5ed [InstCombine] Fix poison propagation in round up alignment fold
We can't directly use the high bits value if it is more poisonous
due to poison elements in the masks.

This fixes the issue reported in
https://github.com/llvm/llvm-project/pull/88217#issuecomment-2061034941.
2024-04-18 10:58:15 +09:00

510 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_BIASED:%.*]] = add i8 [[X:%.*]], 15
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED]], -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_BIASED:%.*]] = add i8 [[X:%.*]], 31
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED]], -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_BIASED:%.*]] = add i8 [[X]], 15
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and i8 [[X_BIASED]], -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_BIASED:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED]], <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-poison
define <2 x i8> @t5_splat_poison_0b0001(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_poison_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 poison>
%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_poison_0b0010(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_poison_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 poison>
%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_poison_0b0100(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_poison_0b0100(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED]], <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 poison>
%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_poison_0b1000(<2 x i8> %x) {
; CHECK-LABEL: @t5_splat_poison_0b1000(
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X:%.*]], <i8 15, i8 15>
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = and <2 x i8> [[X_BIASED]], <i8 -16, i8 -16>
; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]]
;
%x.lowbits = and <2 x i8> %x, <i8 15, i8 poison>
%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_poison_0b0001(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_poison_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 poison>
; 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 poison>
%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_poison_0b0010(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_poison_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 poison>
; 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 poison>
%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_poison_0b0100(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_poison_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 poison>
; 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 poison>
%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_poison_0b1000(<2 x i8> %x) {
; CHECK-LABEL: @t8_nonsplat_masked_by_poison_0b1000(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], <i8 15, i8 poison>
; 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 poison>
%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
}
; Negative test: We can't replace with %x.biased.highbits because it is
; more poisonous.
define <2 x i4> @t18_replacement_0b0001(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b0001(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 3>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer
; 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 poison>
; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]])
; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]]
;
%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 poison>
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
}
; Negative test: We can't replace with %x.biased.highbits because it is
; more poisonous.
define <2 x i4> @t18_replacement_0b0010(<2 x i4> %x) {
; CHECK-LABEL: @t18_replacement_0b0010(
; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 3>
; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer
; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], <i4 3, i4 poison>
; 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: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]]
; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]]
;
%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 poison>
%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 poison>
%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 poison>
%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
}