Skip to content

Commit 4e0dd00

Browse files
[InstCombine] Combine trunc (lshr X, BW-1) to i1 --> icmp slt X, 0 (#142593) (#143846)
Fixes #142593, the issue was fixed using the suggestion on the ticket itself. Godbolt: https://godbolt.org/z/oW5b74jc4 alive2 proof: https://alive2.llvm.org/ce/z/QHnD7e
1 parent ee2d7a6 commit 4e0dd00

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,12 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
815815
return new ICmpInst(ICmpInst::ICMP_EQ, X, CmpC);
816816
}
817817

818+
if (match(Src, m_Shr(m_Value(X), m_SpecificInt(SrcWidth - 1)))) {
819+
// trunc (ashr X, BW-1) to i1 --> icmp slt X, 0
820+
// trunc (lshr X, BW-1) to i1 --> icmp slt X, 0
821+
return new ICmpInst(ICmpInst::ICMP_SLT, X, Zero);
822+
}
823+
818824
Constant *C;
819825
if (match(Src, m_OneUse(m_LShr(m_Value(X), m_ImmConstant(C))))) {
820826
// trunc (lshr X, C) to i1 --> icmp ne (and X, C'), 0

llvm/test/Transforms/InstCombine/logical-select.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,9 +807,9 @@ define <2 x i16> @bitcast_vec_cond_commute3(<4 x i8> %cond, <2 x i16> %pc, <2 x
807807
; CHECK-LABEL: @bitcast_vec_cond_commute3(
808808
; CHECK-NEXT: [[C:%.*]] = mul <2 x i16> [[PC:%.*]], [[PC]]
809809
; CHECK-NEXT: [[D:%.*]] = mul <2 x i16> [[PD:%.*]], [[PD]]
810+
; CHECK-NEXT: [[DOTNOT2:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer
810811
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[D]] to <4 x i8>
811812
; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[C]] to <4 x i8>
812-
; CHECK-NEXT: [[DOTNOT2:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer
813813
; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[DOTNOT2]], <4 x i8> [[TMP1]], <4 x i8> [[TMP2]]
814814
; CHECK-NEXT: [[R:%.*]] = bitcast <4 x i8> [[TMP3]] to <2 x i16>
815815
; CHECK-NEXT: ret <2 x i16> [[R]]
@@ -1069,8 +1069,8 @@ define <2 x i1> @not_d_bools_vector_poison(<2 x i1> %c, <2 x i1> %x, <2 x i1> %y
10691069

10701070
define i32 @not_d_allSignBits(i32 %cond, i32 %tval, i32 %fval) {
10711071
; CHECK-LABEL: @not_d_allSignBits(
1072-
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[FVAL:%.*]], -1
10731072
; CHECK-NEXT: [[DOTNOT2:%.*]] = icmp slt i32 [[COND:%.*]], 0
1073+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[FVAL:%.*]], -1
10741074
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[DOTNOT2]], i32 [[TVAL:%.*]], i32 [[TMP1]]
10751075
; CHECK-NEXT: ret i32 [[SEL]]
10761076
;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3+
4+
define i1 @test1(i32 %i, ptr %p) {
5+
; CHECK-LABEL: define i1 @test1(
6+
; CHECK-SAME: i32 [[I:%.*]], ptr [[P:%.*]]) {
7+
; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[I]], 31
8+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
9+
; CHECK-NEXT: ret i1 false
10+
;
11+
%lobit = lshr i32 %i, 31
12+
%t = trunc nuw i32 %lobit to i1
13+
%b = icmp slt i32 %i, 0
14+
%not = xor i1 %t, true
15+
%op = select i1 %not, i1 %b, i1 false
16+
store i32 %lobit, ptr %p, align 1
17+
ret i1 %op
18+
}
19+
20+
define i1 @test2(i32 %i, ptr %p) {
21+
; CHECK-LABEL: define i1 @test2(
22+
; CHECK-SAME: i32 [[I:%.*]], ptr [[P:%.*]]) {
23+
; CHECK-NEXT: [[DOTLOBIT:%.*]] = ashr i32 [[I]], 31
24+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
25+
; CHECK-NEXT: ret i1 false
26+
;
27+
%lobit = ashr i32 %i, 31
28+
%t = trunc nuw i32 %lobit to i1
29+
%b = icmp slt i32 %i, 0
30+
%not = xor i1 %t, true
31+
%op = select i1 %not, i1 %b, i1 false
32+
store i32 %lobit, ptr %p, align 1
33+
ret i1 %op
34+
}
35+
36+
define i1 @test3(i32 %i, ptr %p, ptr %q) {
37+
; CHECK-LABEL: define i1 @test3(
38+
; CHECK-SAME: i32 [[I:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) {
39+
; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[I]], 31
40+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
41+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[Q]], align 1
42+
; CHECK-NEXT: ret i1 false
43+
;
44+
%lobit = lshr i32 %i, 31
45+
%t = trunc nuw i32 %lobit to i1
46+
%b = icmp slt i32 %i, 0
47+
%not = xor i1 %t, true
48+
%op = select i1 %not, i1 %b, i1 false
49+
store i32 %lobit, ptr %p, align 1
50+
store i32 %lobit, ptr %q, align 1
51+
ret i1 %op
52+
}
53+
54+
; Negative Test
55+
define i1 @test4(i32 %i, ptr %p) {
56+
; CHECK-LABEL: define i1 @test4(
57+
; CHECK-SAME: i32 [[I:%.*]], ptr [[P:%.*]]) {
58+
; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[I]], 30
59+
; CHECK-NEXT: [[T:%.*]] = trunc nuw i32 [[DOTLOBIT]] to i1
60+
; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[I]], 0
61+
; CHECK-NEXT: [[NOT_:%.*]] = xor i1 [[T]], true
62+
; CHECK-NEXT: [[COMMON_RET1_OP:%.*]] = select i1 [[NOT_]], i1 [[B]], i1 false
63+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
64+
; CHECK-NEXT: ret i1 [[COMMON_RET1_OP]]
65+
;
66+
%lobit = lshr i32 %i, 30 ; should not fold as no. of bits shifted < BitWidth - 1
67+
%t = trunc nuw i32 %lobit to i1
68+
%b = icmp slt i32 %i, 0
69+
%not = xor i1 %t, true
70+
%op = select i1 %not, i1 %b, i1 false
71+
store i32 %lobit, ptr %p, align 1
72+
ret i1 %op
73+
}
74+
75+
; Negative Test
76+
define i1 @test5(i32 %i, ptr %p) {
77+
; CHECK-LABEL: define i1 @test5(
78+
; CHECK-SAME: i32 [[I:%.*]], ptr [[P:%.*]]) {
79+
; CHECK-NEXT: [[DOTLOBIT:%.*]] = ashr i32 [[I]], 30
80+
; CHECK-NEXT: [[T:%.*]] = trunc nuw i32 [[DOTLOBIT]] to i1
81+
; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[I]], 0
82+
; CHECK-NEXT: [[NOT_:%.*]] = xor i1 [[T]], true
83+
; CHECK-NEXT: [[COMMON_RET1_OP:%.*]] = select i1 [[NOT_]], i1 [[B]], i1 false
84+
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
85+
; CHECK-NEXT: ret i1 [[COMMON_RET1_OP]]
86+
;
87+
%lobit = ashr i32 %i, 30 ; should not fold as no. of bits shifted < BitWidth - 1
88+
%t = trunc nuw i32 %lobit to i1
89+
%b = icmp slt i32 %i, 0
90+
%not = xor i1 %t, true
91+
%op = select i1 %not, i1 %b, i1 false
92+
store i32 %lobit, ptr %p, align 1
93+
ret i1 %op
94+
}
95+

0 commit comments

Comments
 (0)