| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s | |
| ; InstCombine canonicalizes boundary range comparisons to eq/ne (e.g. | |
| ; x <u 1 becomes x == 0). Such lanes are interchangeable with the rest of | |
| ; the bundle by adjusting the compared constant. | |
| define <8 x i1> @eq_ult(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @eq_ult( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <8 x i16> [[TMP2]], <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp eq i16 %x, 0 | |
| %c2 = icmp ult i16 %x, 2 | |
| %c3 = icmp ult i16 %x, 3 | |
| %c4 = icmp ult i16 %x, 4 | |
| %c5 = icmp ult i16 %x, 5 | |
| %c6 = icmp ult i16 %x, 6 | |
| %c7 = icmp ult i16 %x, 7 | |
| %c8 = icmp ult i16 %x, 8 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <8 x i1> @ne_ugt(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @ne_ugt( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt <8 x i16> [[TMP2]], <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp ne i16 %x, 0 | |
| %c2 = icmp ugt i16 %x, 1 | |
| %c3 = icmp ugt i16 %x, 2 | |
| %c4 = icmp ugt i16 %x, 3 | |
| %c5 = icmp ugt i16 %x, 4 | |
| %c6 = icmp ugt i16 %x, 5 | |
| %c7 = icmp ugt i16 %x, 6 | |
| %c8 = icmp ugt i16 %x, 7 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <8 x i1> @eq_slt_signed_mins(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @eq_slt_signed_mins( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <8 x i16> [[TMP2]], <i16 -32767, i16 -32766, i16 -32765, i16 -32764, i16 -32763, i16 -32762, i16 -32761, i16 -32760> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp eq i16 %x, -32768 | |
| %c2 = icmp slt i16 %x, -32766 | |
| %c3 = icmp slt i16 %x, -32765 | |
| %c4 = icmp slt i16 %x, -32764 | |
| %c5 = icmp slt i16 %x, -32763 | |
| %c6 = icmp slt i16 %x, -32762 | |
| %c7 = icmp slt i16 %x, -32761 | |
| %c8 = icmp slt i16 %x, -32760 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <8 x i1> @ne_sle_signed_maxs(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @ne_sle_signed_maxs( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp sle <8 x i16> [[TMP2]], <i16 32766, i16 32765, i16 32764, i16 32763, i16 32762, i16 32761, i16 32760, i16 32759> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp ne i16 %x, 32767 | |
| %c2 = icmp sle i16 %x, 32765 | |
| %c3 = icmp sle i16 %x, 32764 | |
| %c4 = icmp sle i16 %x, 32763 | |
| %c5 = icmp sle i16 %x, 32762 | |
| %c6 = icmp sle i16 %x, 32761 | |
| %c7 = icmp sle i16 %x, 32760 | |
| %c8 = icmp sle i16 %x, 32759 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <8 x i1> @ule_ult(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @ule_ult( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <8 x i16> [[TMP2]], <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp ule i16 %x, 0 | |
| %c2 = icmp ult i16 %x, 2 | |
| %c3 = icmp ult i16 %x, 3 | |
| %c4 = icmp ult i16 %x, 4 | |
| %c5 = icmp ult i16 %x, 5 | |
| %c6 = icmp ult i16 %x, 6 | |
| %c7 = icmp ult i16 %x, 7 | |
| %c8 = icmp ult i16 %x, 8 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| ; Non-boundary constant: x == 5 is not interchangeable with x <u C. | |
| define <8 x i1> @neg_eq_nonboundary(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @neg_eq_nonboundary( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 5, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> | |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> <i16 poison, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[TMP2]], [[TMP3]] | |
| ; CHECK-NEXT: [[TMP5:%.*]] = icmp ult <8 x i16> [[TMP2]], [[TMP3]] | |
| ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP6]] | |
| ; | |
| %c1 = icmp eq i16 %x, 5 | |
| %c2 = icmp ult i16 %x, 2 | |
| %c3 = icmp ult i16 %x, 3 | |
| %c4 = icmp ult i16 %x, 4 | |
| %c5 = icmp ult i16 %x, 5 | |
| %c6 = icmp ult i16 %x, 6 | |
| %c7 = icmp ult i16 %x, 7 | |
| %c8 = icmp ult i16 %x, 8 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| ; eq and ne are complements, not interchangeable. | |
| define <8 x i1> @neg_eq_ne(i16 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @neg_eq_ne( | |
| ; CHECK-SAME: i16 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <8 x i16> [[TMP2]], <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <8 x i16> [[TMP2]], <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7> | |
| ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <8 x i1> [[TMP3]], <8 x i1> [[TMP4]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP5]] | |
| ; | |
| %c1 = icmp eq i16 %x, 0 | |
| %c2 = icmp ne i16 %x, 1 | |
| %c3 = icmp ne i16 %x, 2 | |
| %c4 = icmp ne i16 %x, 3 | |
| %c5 = icmp ne i16 %x, 4 | |
| %c6 = icmp ne i16 %x, 5 | |
| %c7 = icmp ne i16 %x, 6 | |
| %c8 = icmp ne i16 %x, 7 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| ; samesign is dropped on the vector compare, like for any cmp node; the | |
| ; converted lanes stay correct since the vector lane is defined wherever the | |
| ; original samesign scalar was poison. | |
| define <8 x i1> @samesign_lanes(i8 %x) { | |
| ; CHECK-LABEL: define <8 x i1> @samesign_lanes( | |
| ; CHECK-SAME: i8 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i8> poison, i8 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i8> [[TMP1]], <8 x i8> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp samesign ult <8 x i8> [[TMP2]], <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP3]] | |
| ; | |
| %c1 = icmp samesign eq i8 %x, 0 | |
| %c2 = icmp samesign ult i8 %x, 2 | |
| %c3 = icmp samesign ult i8 %x, 3 | |
| %c4 = icmp samesign ult i8 %x, 4 | |
| %c5 = icmp samesign ult i8 %x, 5 | |
| %c6 = icmp samesign ult i8 %x, 6 | |
| %c7 = icmp samesign ult i8 %x, 7 | |
| %c8 = icmp samesign ult i8 %x, 8 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| ; samesign is dropped: the i1 conversion flips the constant's sign. | |
| define <4 x i1> @samesign_i1_signflip(i1 %x, i1 %y, i1 %z, i1 %w) { | |
| ; CHECK-LABEL: define <4 x i1> @samesign_i1_signflip( | |
| ; CHECK-SAME: i1 [[X:%.*]], i1 [[Y:%.*]], i1 [[Z:%.*]], i1 [[W:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i1> poison, i1 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i1> [[TMP1]], i1 [[Y]], i64 1 | |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x i1> [[TMP2]], i1 [[Z]], i64 2 | |
| ; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i1> [[TMP3]], i1 [[W]], i64 3 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq <4 x i1> [[TMP4]], zeroinitializer | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP5]] | |
| ; | |
| %c1 = icmp samesign eq i1 %x, 0 | |
| %c2 = icmp samesign ult i1 %y, 1 | |
| %c3 = icmp samesign ult i1 %z, 1 | |
| %c4 = icmp samesign ult i1 %w, 1 | |
| %i1 = insertelement <4 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %c4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| ; samesign is dropped: the compared operands are narrowed. | |
| define <4 x i1> @samesign_narrowed(i16 %a, i16 %b, i16 %c, i16 %d) { | |
| ; CHECK-LABEL: define <4 x i1> @samesign_narrowed( | |
| ; CHECK-SAME: i16 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i16 [[D:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i16> poison, i16 [[A]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i16> [[TMP1]], i16 [[C]], i64 1 | |
| ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <2 x i16> [[TMP2]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i16> poison, i16 [[B]], i64 0 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x i16> [[TMP4]], i16 [[D]], i64 1 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <2 x i16> [[TMP5]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 0> | |
| ; CHECK-NEXT: [[TMP7:%.*]] = icmp ult <4 x i16> [[TMP3]], [[TMP6]] | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP7]] | |
| ; | |
| %a32 = zext i16 %a to i32 | |
| %b32 = zext i16 %b to i32 | |
| %c32 = zext i16 %c to i32 | |
| %d32 = zext i16 %d to i32 | |
| %r1 = icmp samesign ult i32 %a32, %b32 | |
| %r2 = icmp samesign ult i32 %c32, %d32 | |
| %r3 = icmp samesign ult i32 %a32, %d32 | |
| %r4 = icmp samesign ult i32 %c32, %b32 | |
| %i1 = insertelement <4 x i1> poison, i1 %r1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %r2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %r3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %r4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| ; The original issue pattern: compares feeding selects and stores. | |
| define void @selects(ptr noalias %out, ptr addrspace(11) %a, ptr addrspace(11) %b, i64 %n) { | |
| ; CHECK-LABEL: define void @selects( | |
| ; CHECK-SAME: ptr noalias [[OUT:%.*]], ptr addrspace(11) [[A:%.*]], ptr addrspace(11) [[B:%.*]], i64 [[N:%.*]]) { | |
| ; CHECK-NEXT: [[X:%.*]] = trunc i64 [[N]] to i16 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i16> [[TMP1]], <4 x i16> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <4 x i16> [[TMP2]], <i16 1, i16 2, i16 3, i16 4> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr addrspace(11) [[A]], align 2 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr addrspace(11) [[B]], align 2 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = select <4 x i1> [[TMP3]], <4 x i16> [[TMP5]], <4 x i16> [[TMP4]] | |
| ; CHECK-NEXT: store <4 x i16> [[TMP6]], ptr [[OUT]], align 2 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %x = trunc i64 %n to i16 | |
| %c1 = icmp eq i16 %x, 0 | |
| %l1a = load i16, ptr addrspace(11) %a, align 2 | |
| %l1b = load i16, ptr addrspace(11) %b, align 2 | |
| %s1 = select i1 %c1, i16 %l1b, i16 %l1a | |
| %c2 = icmp ult i16 %x, 2 | |
| %p2a = getelementptr i8, ptr addrspace(11) %a, i64 2 | |
| %p2b = getelementptr i8, ptr addrspace(11) %b, i64 2 | |
| %l2a = load i16, ptr addrspace(11) %p2a, align 2 | |
| %l2b = load i16, ptr addrspace(11) %p2b, align 2 | |
| %s2 = select i1 %c2, i16 %l2b, i16 %l2a | |
| %c3 = icmp ult i16 %x, 3 | |
| %p3a = getelementptr i8, ptr addrspace(11) %a, i64 4 | |
| %p3b = getelementptr i8, ptr addrspace(11) %b, i64 4 | |
| %l3a = load i16, ptr addrspace(11) %p3a, align 2 | |
| %l3b = load i16, ptr addrspace(11) %p3b, align 2 | |
| %s3 = select i1 %c3, i16 %l3b, i16 %l3a | |
| %c4 = icmp ult i16 %x, 4 | |
| %p4a = getelementptr i8, ptr addrspace(11) %a, i64 6 | |
| %p4b = getelementptr i8, ptr addrspace(11) %b, i64 6 | |
| %l4a = load i16, ptr addrspace(11) %p4a, align 2 | |
| %l4b = load i16, ptr addrspace(11) %p4b, align 2 | |
| %s4 = select i1 %c4, i16 %l4b, i16 %l4a | |
| store i16 %s1, ptr %out, align 2 | |
| %o2 = getelementptr i8, ptr %out, i64 2 | |
| store i16 %s2, ptr %o2, align 2 | |
| %o3 = getelementptr i8, ptr %out, i64 4 | |
| store i16 %s3, ptr %o3, align 2 | |
| %o4 = getelementptr i8, ptr %out, i64 6 | |
| store i16 %s4, ptr %o4, align 2 | |
| ret void | |
| } | |
| define <2 x i1> @trunc_as_icmp_ne_and(i8 %x) { | |
| ; CHECK-LABEL: define <2 x i1> @trunc_as_icmp_ne_and( | |
| ; CHECK-SAME: i8 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> poison, i8 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <2 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i8> [[TMP2]], <i8 1, i8 2> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i8> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: ret <2 x i1> [[TMP4]] | |
| ; | |
| %c1 = trunc i8 %x to i1 | |
| %m2 = and i8 %x, 2 | |
| %c2 = icmp ne i8 %m2, 0 | |
| %i1 = insertelement <2 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <2 x i1> %i1, i1 %c2, i32 1 | |
| ret <2 x i1> %i2 | |
| } | |
| define <4 x i1> @trunc_as_icmp_ne_and_mixed_preds(i8 %x) { | |
| ; CHECK-LABEL: define <4 x i1> @trunc_as_icmp_ne_and_mixed_preds( | |
| ; CHECK-SAME: i8 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i8> [[TMP2]], <i8 1, i8 2, i8 12, i8 48> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <4 x i8> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP4]] | |
| ; | |
| %c1 = trunc i8 %x to i1 | |
| %m2 = and i8 %x, 2 | |
| %c2 = icmp ne i8 %m2, 0 | |
| %m3 = and i8 %x, 12 | |
| %c3 = icmp ugt i8 %m3, 0 | |
| %m4 = and i8 %x, 48 | |
| %c4 = icmp uge i8 %m4, 1 | |
| %i1 = insertelement <4 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %c4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| define void @trunc_as_icmp_ne_and_reused_operand(i16 %x, ptr %out) { | |
| ; CHECK-LABEL: define void @trunc_as_icmp_ne_and_reused_operand( | |
| ; CHECK-SAME: i16 [[X:%.*]], ptr [[OUT:%.*]]) { | |
| ; CHECK-NEXT: [[C1:%.*]] = trunc i16 [[X]] to i1 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i16> poison, i16 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <2 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i16> [[TMP2]], <i16 2, i16 4> | |
| ; CHECK-NEXT: [[M4:%.*]] = and i16 [[X]], 8 | |
| ; CHECK-NEXT: [[C4:%.*]] = icmp ne i16 [[M4]], 0 | |
| ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i16 [[X]], i16 7 | |
| ; CHECK-NEXT: [[S4:%.*]] = select i1 [[C4]], i16 [[M4]], i16 13 | |
| ; CHECK-NEXT: store i16 [[S1]], ptr [[OUT]], align 2 | |
| ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i16, ptr [[OUT]], i64 1 | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i16> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP5:%.*]] = select <2 x i1> [[TMP4]], <2 x i16> [[TMP3]], <2 x i16> <i16 9, i16 11> | |
| ; CHECK-NEXT: store <2 x i16> [[TMP5]], ptr [[P2]], align 2 | |
| ; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds i16, ptr [[OUT]], i64 3 | |
| ; CHECK-NEXT: store i16 [[S4]], ptr [[P4]], align 2 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| %c1 = trunc i16 %x to i1 | |
| %m2 = and i16 %x, 2 | |
| %c2 = icmp ne i16 %m2, 0 | |
| %m3 = and i16 %x, 4 | |
| %c3 = icmp ne i16 %m3, 0 | |
| %m4 = and i16 %x, 8 | |
| %c4 = icmp ne i16 %m4, 0 | |
| %s1 = select i1 %c1, i16 %x, i16 7 | |
| %s2 = select i1 %c2, i16 %m2, i16 9 | |
| %s3 = select i1 %c3, i16 %m3, i16 11 | |
| %s4 = select i1 %c4, i16 %m4, i16 13 | |
| store i16 %s1, ptr %out, align 2 | |
| %p2 = getelementptr inbounds i16, ptr %out, i64 1 | |
| store i16 %s2, ptr %p2, align 2 | |
| %p3 = getelementptr inbounds i16, ptr %out, i64 2 | |
| store i16 %s3, ptr %p3, align 2 | |
| %p4 = getelementptr inbounds i16, ptr %out, i64 3 | |
| store i16 %s4, ptr %p4, align 2 | |
| ret void | |
| } | |
| define <4 x i1> @trunc_as_icmp_ne_and_commuted_operands(i8 %x, i1 %a, i1 %b, i1 %c, i1 %d) { | |
| ; CHECK-LABEL: define <4 x i1> @trunc_as_icmp_ne_and_commuted_operands( | |
| ; CHECK-SAME: i8 [[X:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], i1 [[C:%.*]], i1 [[D:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i8> [[TMP2]], <i8 1, i8 2, i8 4, i8 8> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <4 x i8> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i1> poison, i1 [[A]], i64 0 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x i1> [[TMP5]], i1 [[B]], i64 1 | |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x i1> [[TMP6]], i1 [[C]], i64 2 | |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x i1> [[TMP7]], i1 [[D]], i64 3 | |
| ; CHECK-NEXT: [[TMP9:%.*]] = or <4 x i1> [[TMP4]], [[TMP8]] | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP9]] | |
| ; | |
| %c1 = trunc i8 %x to i1 | |
| %o1 = or i1 %c1, %a | |
| %m2 = and i8 %x, 2 | |
| %c2 = icmp ne i8 %m2, 0 | |
| %o2 = or i1 %b, %c2 | |
| %m3 = and i8 %x, 4 | |
| %c3 = icmp ne i8 %m3, 0 | |
| %o3 = or i1 %c, %c3 | |
| %m4 = and i8 %x, 8 | |
| %c4 = icmp ne i8 %m4, 0 | |
| %o4 = or i1 %d, %c4 | |
| %i1 = insertelement <4 x i1> poison, i1 %o1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %o2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %o3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %o4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| define <8 x i1> @trunc_as_icmp_ne_and_non_const_rhs(i16 %x, i16 %y, i16 %z) { | |
| ; CHECK-LABEL: define <8 x i1> @trunc_as_icmp_ne_and_non_const_rhs( | |
| ; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) { | |
| ; CHECK-NEXT: [[C1:%.*]] = trunc i16 [[X]] to i1 | |
| ; CHECK-NEXT: [[M2:%.*]] = and i16 [[Y]], 2 | |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i16 [[M2]], [[X]] | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i16> poison, i16 [[Z]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> poison, <2 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i16> [[TMP2]], <i16 4, i16 8> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i16> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i16> poison, i16 [[Z]], i64 0 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i16> [[TMP5]], <4 x i16> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP11:%.*]] = and <4 x i16> [[TMP6]], <i16 16, i16 32, i16 64, i16 128> | |
| ; CHECK-NEXT: [[TMP8:%.*]] = icmp ne <4 x i16> [[TMP11]], zeroinitializer | |
| ; CHECK-NEXT: [[I1:%.*]] = insertelement <8 x i1> poison, i1 [[C1]], i32 0 | |
| ; CHECK-NEXT: [[I2:%.*]] = insertelement <8 x i1> [[I1]], i1 [[C2]], i32 1 | |
| ; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i1> [[TMP4]], <2 x i1> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> | |
| ; CHECK-NEXT: [[I42:%.*]] = shufflevector <8 x i1> [[I2]], <8 x i1> [[TMP9]], <8 x i32> <i32 0, i32 1, i32 8, i32 9, i32 poison, i32 poison, i32 poison, i32 poison> | |
| ; CHECK-NEXT: [[TMP10:%.*]] = shufflevector <4 x i1> [[TMP8]], <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison> | |
| ; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <8 x i1> [[I42]], <8 x i1> [[TMP10]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> | |
| ; CHECK-NEXT: ret <8 x i1> [[TMP7]] | |
| ; | |
| %c1 = trunc i16 %x to i1 | |
| %m2 = and i16 %y, 2 | |
| %c2 = icmp ne i16 %m2, %x | |
| %m3 = and i16 %z, 4 | |
| %c3 = icmp ne i16 %m3, 0 | |
| %m4 = and i16 %z, 8 | |
| %c4 = icmp ne i16 %m4, 0 | |
| %m5 = and i16 %z, 16 | |
| %c5 = icmp ne i16 %m5, 0 | |
| %m6 = and i16 %z, 32 | |
| %c6 = icmp ne i16 %m6, 0 | |
| %m7 = and i16 %z, 64 | |
| %c7 = icmp ne i16 %m7, 0 | |
| %m8 = and i16 %z, 128 | |
| %c8 = icmp ne i16 %m8, 0 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <8 x i1> @trunc_as_icmp_ne_and_split_preds(i8 %x, i8 %y, i8 %z) { | |
| ; CHECK-LABEL: define <8 x i1> @trunc_as_icmp_ne_and_split_preds( | |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) { | |
| ; CHECK-NEXT: [[C1:%.*]] = trunc i8 [[X]] to i1 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[Y]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i8> [[TMP2]], <i8 64, i8 16, i8 8, i8 2> | |
| ; CHECK-NEXT: [[M3:%.*]] = and i8 [[Z]], 7 | |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ugt i8 [[M3]], 4 | |
| ; CHECK-NEXT: [[M6:%.*]] = and i8 [[Z]], 56 | |
| ; CHECK-NEXT: [[C6:%.*]] = icmp ugt i8 [[M6]], 40 | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <4 x i8> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: [[C8:%.*]] = trunc i8 [[Z]] to i1 | |
| ; CHECK-NEXT: [[I1:%.*]] = insertelement <8 x i1> poison, i1 [[C1]], i32 0 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x i1> [[TMP4]], <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison> | |
| ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <8 x i1> [[I1]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 11, i32 poison, i32 10, i32 9, i32 poison, i32 8, i32 poison> | |
| ; CHECK-NEXT: [[I3:%.*]] = insertelement <8 x i1> [[TMP6]], i1 [[C3]], i32 2 | |
| ; CHECK-NEXT: [[I6:%.*]] = insertelement <8 x i1> [[I3]], i1 [[C6]], i32 5 | |
| ; CHECK-NEXT: [[I8:%.*]] = insertelement <8 x i1> [[I6]], i1 [[C8]], i32 7 | |
| ; CHECK-NEXT: ret <8 x i1> [[I8]] | |
| ; | |
| %c1 = trunc i8 %x to i1 | |
| %m2 = and i8 %y, 2 | |
| %c2 = icmp ne i8 %m2, 0 | |
| %m3 = and i8 %z, 7 | |
| %c3 = icmp ugt i8 %m3, 4 | |
| %m4 = and i8 %y, 8 | |
| %c4 = icmp ne i8 %m4, 0 | |
| %m5 = and i8 %y, 16 | |
| %c5 = icmp ne i8 %m5, 0 | |
| %m6 = and i8 %z, 56 | |
| %c6 = icmp ugt i8 %m6, 40 | |
| %m7 = and i8 %y, 64 | |
| %c7 = icmp ne i8 %m7, 0 | |
| %c8 = trunc i8 %z to i1 | |
| %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3 | |
| %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4 | |
| %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5 | |
| %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6 | |
| %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7 | |
| ret <8 x i1> %i8 | |
| } | |
| define <4 x i1> @trunc_as_icmp_ne_and_inst_operand(i8 %x, i8 %y) { | |
| ; CHECK-LABEL: define <4 x i1> @trunc_as_icmp_ne_and_inst_operand( | |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { | |
| ; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], [[Y]] | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[A]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i8> [[TMP2]], <i8 1, i8 2, i8 4, i8 8> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <4 x i8> [[TMP3]], zeroinitializer | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP4]] | |
| ; | |
| %a = add i8 %x, %y | |
| %c1 = trunc i8 %a to i1 | |
| %m2 = and i8 %a, 2 | |
| %c2 = icmp ne i8 %m2, 0 | |
| %m3 = and i8 %a, 4 | |
| %c3 = icmp ne i8 %m3, 0 | |
| %m4 = and i8 %a, 8 | |
| %c4 = icmp ne i8 %m4, 0 | |
| %i1 = insertelement <4 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %c4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| define <4 x i1> @trunc_as_icmp_eq_and(i8 %x) { | |
| ; CHECK-LABEL: define <4 x i1> @trunc_as_icmp_eq_and( | |
| ; CHECK-SAME: i8 [[X:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[X]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i8> [[TMP2]], <i8 1, i8 2, i8 4, i8 8> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <4 x i8> [[TMP3]], <i8 1, i8 0, i8 0, i8 0> | |
| ; CHECK-NEXT: ret <4 x i1> [[TMP4]] | |
| ; | |
| %c1 = trunc i8 %x to i1 | |
| %m2 = and i8 %x, 2 | |
| %c2 = icmp eq i8 %m2, 0 | |
| %m3 = and i8 %x, 4 | |
| %c3 = icmp eq i8 %m3, 0 | |
| %m4 = and i8 %x, 8 | |
| %c4 = icmp ult i8 %m4, 1 | |
| %i1 = insertelement <4 x i1> poison, i1 %c1, i32 0 | |
| %i2 = insertelement <4 x i1> %i1, i1 %c2, i32 1 | |
| %i3 = insertelement <4 x i1> %i2, i1 %c3, i32 2 | |
| %i4 = insertelement <4 x i1> %i3, i1 %c4, i32 3 | |
| ret <4 x i1> %i4 | |
| } | |
| define <2 x float> @select_trunc_as_icmp_eq_and_swapped_arms(i32 %flags, float %a, float %b) { | |
| ; CHECK-LABEL: define <2 x float> @select_trunc_as_icmp_eq_and_swapped_arms( | |
| ; CHECK-SAME: i32 [[FLAGS:%.*]], float [[A:%.*]], float [[B:%.*]]) { | |
| ; CHECK-NEXT: [[C0:%.*]] = trunc i32 [[FLAGS]] to i1 | |
| ; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0]], float 0.000000e+00, float [[A]] | |
| ; CHECK-NEXT: [[M1:%.*]] = and i32 [[FLAGS]], 2 | |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[M1]], 0 | |
| ; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], float [[B]], float 0.000000e+00 | |
| ; CHECK-NEXT: [[V0:%.*]] = insertelement <2 x float> poison, float [[S0]], i64 0 | |
| ; CHECK-NEXT: [[V1:%.*]] = insertelement <2 x float> [[V0]], float [[S1]], i64 1 | |
| ; CHECK-NEXT: ret <2 x float> [[V1]] | |
| ; | |
| %c0 = trunc i32 %flags to i1 | |
| %s0 = select i1 %c0, float 0.0, float %a | |
| %m1 = and i32 %flags, 2 | |
| %c1 = icmp eq i32 %m1, 0 | |
| %s1 = select i1 %c1, float %b, float 0.0 | |
| %v0 = insertelement <2 x float> poison, float %s0, i64 0 | |
| %v1 = insertelement <2 x float> %v0, float %s1, i64 1 | |
| ret <2 x float> %v1 | |
| } | |
| define <4 x float> @select_trunc_as_icmp_eq_and_multi_use(i32 %flags, float %a, float %b, float %c, float %d, ptr %p) { | |
| ; CHECK-LABEL: define <4 x float> @select_trunc_as_icmp_eq_and_multi_use( | |
| ; CHECK-SAME: i32 [[FLAGS:%.*]], float [[A:%.*]], float [[B:%.*]], float [[C:%.*]], float [[D:%.*]], ptr [[P:%.*]]) { | |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[FLAGS]], i64 0 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = and <4 x i32> [[TMP2]], <i32 1, i32 2, i32 4, i32 8> | |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <4 x i32> [[TMP3]], <i32 1, i32 0, i32 0, i32 0> | |
| ; CHECK-NEXT: [[C0:%.*]] = trunc i32 [[FLAGS]] to i1 | |
| ; CHECK-NEXT: store i1 [[C0]], ptr [[P]], align 1 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> <float 0.000000e+00, float poison, float poison, float poison>, float [[B]], i64 1 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[C]], i64 2 | |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x float> [[TMP6]], float [[D]], i64 3 | |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x float> <float poison, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, float [[A]], i64 0 | |
| ; CHECK-NEXT: [[TMP9:%.*]] = select <4 x i1> [[TMP4]], <4 x float> [[TMP7]], <4 x float> [[TMP8]] | |
| ; CHECK-NEXT: ret <4 x float> [[TMP9]] | |
| ; | |
| %c0 = trunc i32 %flags to i1 | |
| store i1 %c0, ptr %p | |
| %s0 = select i1 %c0, float 0.0, float %a | |
| %m1 = and i32 %flags, 2 | |
| %c1 = icmp eq i32 %m1, 0 | |
| %s1 = select i1 %c1, float %b, float 0.0 | |
| %m2 = and i32 %flags, 4 | |
| %c2 = icmp eq i32 %m2, 0 | |
| %s2 = select i1 %c2, float %c, float 0.0 | |
| %m3 = and i32 %flags, 8 | |
| %c3 = icmp eq i32 %m3, 0 | |
| %s3 = select i1 %c3, float %d, float 0.0 | |
| %v0 = insertelement <4 x float> poison, float %s0, i64 0 | |
| %v1 = insertelement <4 x float> %v0, float %s1, i64 1 | |
| %v2 = insertelement <4 x float> %v1, float %s2, i64 2 | |
| %v3 = insertelement <4 x float> %v2, float %s3, i64 3 | |
| ret <4 x float> %v3 | |
| } |