@@ -56,6 +56,23 @@ define i16 @selective_shift_16.range(i32 %mask, i32 %upper, i32 range(i32 0, 655
5656 ret i16 %trunc
5757}
5858
59+ define i16 @selective_shift_16.range.commute (i32 %mask , i32 %upper , i32 range(i32 0 , 65536 ) %lower ) {
60+ ; CHECK-LABEL: define i16 @selective_shift_16.range.commute(
61+ ; CHECK-SAME: i32 [[MASK:%.*]], i32 [[UPPER:%.*]], i32 range(i32 0, 65536) [[LOWER:%.*]]) {
62+ ; CHECK-NEXT: [[MASK_BIT:%.*]] = and i32 [[MASK]], 16
63+ ; CHECK-NEXT: [[MASK_BIT_Z:%.*]] = icmp eq i32 [[MASK_BIT]], 0
64+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[MASK_BIT_Z]], i32 [[LOWER]], i32 [[UPPER]]
65+ ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SEL]] to i16
66+ ; CHECK-NEXT: ret i16 [[TRUNC]]
67+ ;
68+ %upper.shl = shl nuw i32 %upper , 16
69+ %pack = or disjoint i32 %lower , %upper.shl
70+ %mask.bit = and i32 %mask , 16
71+ %sel = lshr i32 %pack , %mask.bit
72+ %trunc = trunc i32 %sel to i16
73+ ret i16 %trunc
74+ }
75+
5976define i32 @selective_shift_16.masked (i32 %mask , i16 %upper , i16 %lower ) {
6077; CHECK-LABEL: define i32 @selective_shift_16.masked(
6178; CHECK-SAME: i32 [[MASK:%.*]], i16 [[UPPER:%.*]], i16 [[LOWER:%.*]]) {
@@ -75,6 +92,25 @@ define i32 @selective_shift_16.masked(i32 %mask, i16 %upper, i16 %lower) {
7592 ret i32 %sel.masked
7693}
7794
95+ define i32 @selective_shift_16.masked.commute (i32 %mask , i16 %upper , i16 %lower ) {
96+ ; CHECK-LABEL: define i32 @selective_shift_16.masked.commute(
97+ ; CHECK-SAME: i32 [[MASK:%.*]], i16 [[UPPER:%.*]], i16 [[LOWER:%.*]]) {
98+ ; CHECK-NEXT: [[MASK_BIT:%.*]] = and i32 [[MASK]], 16
99+ ; CHECK-NEXT: [[MASK_BIT_Z:%.*]] = icmp eq i32 [[MASK_BIT]], 0
100+ ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[MASK_BIT_Z]], i16 [[LOWER]], i16 [[UPPER]]
101+ ; CHECK-NEXT: [[SEL:%.*]] = zext i16 [[SEL_V]] to i32
102+ ; CHECK-NEXT: ret i32 [[SEL]]
103+ ;
104+ %upper.zext = zext i16 %upper to i32
105+ %upper.shl = shl nuw i32 %upper.zext , 16
106+ %lower.zext = zext i16 %lower to i32
107+ %pack = or disjoint i32 %upper.shl , %lower.zext
108+ %mask.bit = and i32 %mask , 16
109+ %sel = lshr i32 %pack , %mask.bit
110+ %sel.masked = and i32 %sel , 65535
111+ ret i32 %sel.masked
112+ }
113+
78114define <2 x i16 > @selective_shift.v16 (<2 x i32 > %mask , <2 x i16 > %upper , <2 x i16 > %lower ) {
79115; CHECK-LABEL: define <2 x i16> @selective_shift.v16(
80116; CHECK-SAME: <2 x i32> [[MASK:%.*]], <2 x i16> [[UPPER:%.*]], <2 x i16> [[LOWER:%.*]]) {
@@ -267,3 +303,21 @@ define i32 @selective_shift_32(i64 %mask, i32 %upper, i32 %lower) {
267303 %trunc = trunc i64 %sel to i32
268304 ret i32 %trunc
269305}
306+
307+ define i32 @selective_shift_32.commute (i64 %mask , i32 %upper , i32 %lower ) {
308+ ; CHECK-LABEL: define i32 @selective_shift_32.commute(
309+ ; CHECK-SAME: i64 [[MASK:%.*]], i32 [[UPPER:%.*]], i32 [[LOWER:%.*]]) {
310+ ; CHECK-NEXT: [[MASK_BIT:%.*]] = and i64 [[MASK]], 32
311+ ; CHECK-NEXT: [[MASK_BIT_Z:%.*]] = icmp eq i64 [[MASK_BIT]], 0
312+ ; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[MASK_BIT_Z]], i32 [[LOWER]], i32 [[UPPER]]
313+ ; CHECK-NEXT: ret i32 [[SEL_V]]
314+ ;
315+ %upper.zext = zext i32 %upper to i64
316+ %upper.shl = shl nuw i64 %upper.zext , 32
317+ %lower.zext = zext i32 %lower to i64
318+ %pack = or disjoint i64 %lower.zext , %upper.shl
319+ %mask.bit = and i64 %mask , 32
320+ %sel = lshr i64 %pack , %mask.bit
321+ %trunc = trunc i64 %sel to i32
322+ ret i32 %trunc
323+ }
0 commit comments