Skip to content

Commit 712bdb2

Browse files
committed
[InstCombine] add rotate narrowing tests with odd types; NFC
There's a potential miscompile here. It's unlikely in the real world because this transform is guarded with shouldChangeType(), but this test file doesn't include a standard data-layout for some reason (despite including a custom 1), so we can see the bug. llvm-svn: 346966
1 parent 5a1b7ce commit 712bdb2

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

llvm/test/Transforms/InstCombine/rotate.ll

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,28 @@ define i8 @rotate8_not_safe(i8 %v, i32 %shamt) {
123123
ret i8 %ret
124124
}
125125

126+
; FIXME: A non-power-of-2 destination type can't be masked as above.
127+
128+
define i9 @rotate9_not_safe(i9 %v, i32 %shamt) {
129+
; CHECK-LABEL: @rotate9_not_safe(
130+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT:%.*]] to i9
131+
; CHECK-NEXT: [[TMP2:%.*]] = sub i9 0, [[TMP1]]
132+
; CHECK-NEXT: [[TMP3:%.*]] = and i9 [[TMP1]], 8
133+
; CHECK-NEXT: [[TMP4:%.*]] = and i9 [[TMP2]], 8
134+
; CHECK-NEXT: [[TMP5:%.*]] = lshr i9 [[V:%.*]], [[TMP4]]
135+
; CHECK-NEXT: [[TMP6:%.*]] = shl i9 [[V]], [[TMP3]]
136+
; CHECK-NEXT: [[RET:%.*]] = or i9 [[TMP5]], [[TMP6]]
137+
; CHECK-NEXT: ret i9 [[RET]]
138+
;
139+
%conv = zext i9 %v to i32
140+
%sub = sub i32 9, %shamt
141+
%shr = lshr i32 %conv, %sub
142+
%shl = shl i32 %conv, %shamt
143+
%or = or i32 %shr, %shl
144+
%ret = trunc i32 %or to i9
145+
ret i9 %ret
146+
}
147+
126148
; We should narrow (v << (s & 15)) | (v >> (-s & 15))
127149
; when both v and s have been promoted.
128150

@@ -309,6 +331,30 @@ define i8 @rotateleft_8_neg_mask_wide_amount_commute(i8 %v, i32 %shamt) {
309331
ret i8 %ret
310332
}
311333

334+
; Non-power-of-2 types. This is transformed correctly, but it's not a typical rotate pattern.
335+
336+
define i9 @rotateleft_9_neg_mask_wide_amount_commute(i9 %v, i33 %shamt) {
337+
; CHECK-LABEL: @rotateleft_9_neg_mask_wide_amount_commute(
338+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i33 [[SHAMT:%.*]] to i9
339+
; CHECK-NEXT: [[TMP2:%.*]] = sub i9 0, [[TMP1]]
340+
; CHECK-NEXT: [[TMP3:%.*]] = and i9 [[TMP1]], 8
341+
; CHECK-NEXT: [[TMP4:%.*]] = and i9 [[TMP2]], 8
342+
; CHECK-NEXT: [[TMP5:%.*]] = shl i9 [[V:%.*]], [[TMP3]]
343+
; CHECK-NEXT: [[TMP6:%.*]] = lshr i9 [[V]], [[TMP4]]
344+
; CHECK-NEXT: [[RET:%.*]] = or i9 [[TMP5]], [[TMP6]]
345+
; CHECK-NEXT: ret i9 [[RET]]
346+
;
347+
%neg = sub i33 0, %shamt
348+
%lshamt = and i33 %shamt, 8
349+
%rshamt = and i33 %neg, 8
350+
%conv = zext i9 %v to i33
351+
%shl = shl i33 %conv, %lshamt
352+
%shr = lshr i33 %conv, %rshamt
353+
%or = or i33 %shl, %shr
354+
%ret = trunc i33 %or to i9
355+
ret i9 %ret
356+
}
357+
312358
; Convert select pattern to masked shift that ends in 'or'.
313359

314360
define i32 @rotr_select(i32 %x, i32 %shamt) {

0 commit comments

Comments
 (0)