| ; 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-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_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 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_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 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 |
| } |