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