Skip to content

Commit f7aec25

Browse files
committed
[NFC][InstCombine] conditional sign-extend of high-bit-extract: 'and' pat. can be 'or' pattern.
In this pattern, all the "magic" bits that we'd add are all high sign bits, and in the value we'd be adding to they are all unset, not unexpectedly, so we can have an `or` there: https://rise4fun.com/Alive/ups llvm-svn: 375377
1 parent b01c077 commit f7aec25

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,37 @@ define i32 @t0_notrunc_add(i32 %data, i32 %nbits) {
4545
ret i32 %signextended
4646
}
4747

48+
define i32 @t0_notrunc_or(i32 %data, i32 %nbits) {
49+
; CHECK-LABEL: @t0_notrunc_or(
50+
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
51+
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
52+
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
53+
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
54+
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
55+
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
56+
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
57+
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
58+
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
59+
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
60+
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
61+
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
62+
;
63+
%low_bits_to_skip = sub i32 32, %nbits
64+
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
65+
%should_signext = icmp slt i32 %data, 0
66+
%all_bits_except_low_nbits = shl i32 -1, %nbits
67+
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
68+
69+
call void @use32(i32 %low_bits_to_skip)
70+
call void @use32(i32 %high_bits_extracted)
71+
call void @use1(i1 %should_signext)
72+
call void @use32(i32 %all_bits_except_low_nbits)
73+
call void @use32(i32 %magic)
74+
75+
%signextended = or i32 %high_bits_extracted, %magic
76+
ret i32 %signextended
77+
}
78+
4879
define i32 @t1_notrunc_sub(i32 %data, i32 %nbits) {
4980
; CHECK-LABEL: @t1_notrunc_sub(
5081
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
@@ -113,6 +144,43 @@ define i32 @t2_trunc_add(i64 %data, i32 %nbits) {
113144
ret i32 %signextended
114145
}
115146

147+
define i32 @t2_trunc_or(i64 %data, i32 %nbits) {
148+
; CHECK-LABEL: @t2_trunc_or(
149+
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
150+
; CHECK-NEXT: [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
151+
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
152+
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
153+
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
154+
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
155+
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
156+
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
157+
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
158+
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
159+
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
160+
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
161+
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
162+
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
163+
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
164+
;
165+
%low_bits_to_skip = sub i32 64, %nbits
166+
%low_bits_to_skip_wide = zext i32 %low_bits_to_skip to i64
167+
%high_bits_extracted_wide = lshr i64 %data, %low_bits_to_skip_wide
168+
%high_bits_extracted = trunc i64 %high_bits_extracted_wide to i32
169+
%should_signext = icmp slt i64 %data, 0
170+
%all_bits_except_low_nbits = shl i32 -1, %nbits
171+
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0 ; one-use
172+
173+
call void @use32(i32 %low_bits_to_skip)
174+
call void @use64(i64 %low_bits_to_skip_wide)
175+
call void @use64(i64 %high_bits_extracted_wide)
176+
call void @use32(i32 %high_bits_extracted)
177+
call void @use1(i1 %should_signext)
178+
call void @use32(i32 %all_bits_except_low_nbits)
179+
180+
%signextended = or i32 %magic, %high_bits_extracted
181+
ret i32 %signextended
182+
}
183+
116184
define i32 @t3_trunc_sub(i64 %data, i32 %nbits) {
117185
; CHECK-LABEL: @t3_trunc_sub(
118186
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 64, [[NBITS:%.*]]
@@ -1038,3 +1106,34 @@ define i32 @n28_sub_sext_of_magic(i32 %data, i8 %nbits) {
10381106
%signextended = sub i32 %high_bits_extracted, %magic_wide
10391107
ret i32 %signextended
10401108
}
1109+
1110+
define i32 @n290_or_with_wrong_magic(i32 %data, i32 %nbits) {
1111+
; CHECK-LABEL: @n290_or_with_wrong_magic(
1112+
; CHECK-NEXT: [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
1113+
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
1114+
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
1115+
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 1, [[NBITS]]
1116+
; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
1117+
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
1118+
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
1119+
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
1120+
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
1121+
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
1122+
; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
1123+
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
1124+
;
1125+
%low_bits_to_skip = sub i32 32, %nbits
1126+
%high_bits_extracted = lshr i32 %data, %low_bits_to_skip
1127+
%should_signext = icmp slt i32 %data, 0
1128+
%all_bits_except_low_nbits = shl i32 1, %nbits ; not -1
1129+
%magic = select i1 %should_signext, i32 %all_bits_except_low_nbits, i32 0
1130+
1131+
call void @use32(i32 %low_bits_to_skip)
1132+
call void @use32(i32 %high_bits_extracted)
1133+
call void @use1(i1 %should_signext)
1134+
call void @use32(i32 %all_bits_except_low_nbits)
1135+
call void @use32(i32 %magic)
1136+
1137+
%signextended = or i32 %high_bits_extracted, %magic
1138+
ret i32 %signextended
1139+
}

0 commit comments

Comments
 (0)