Skip to content

Commit ff2cf8f

Browse files
rotaterighttstellar
authored andcommitted
[InstCombine] avoid creating an extra instruction in zext fold and possible inf-loop
The structure of this fold is suspect vs. most of instcombine because it creates instructions and tries to delete them immediately after. If we don't have the operand types for the icmps, then we are not behaving as assumed. And as shown in PR49475, we can inf-loop. (cherry picked from commit 4224a36)
1 parent 5b34806 commit ff2cf8f

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,7 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
12701270
ICmpInst *LHS = dyn_cast<ICmpInst>(SrcI->getOperand(0));
12711271
ICmpInst *RHS = dyn_cast<ICmpInst>(SrcI->getOperand(1));
12721272
if (LHS && RHS && LHS->hasOneUse() && RHS->hasOneUse() &&
1273+
LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType() &&
12731274
(transformZExtICmp(LHS, CI, false) ||
12741275
transformZExtICmp(RHS, CI, false))) {
12751276
// zext (or icmp, icmp) -> or (zext icmp), (zext icmp)

llvm/test/Transforms/InstCombine/zext-or-icmp.ll

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,16 @@ block2:
107107
ret i32 %conv2
108108
}
109109

110-
; FIXME: This should not end with more instructions than it started from.
110+
; This should not end with more instructions than it started from.
111111

112112
define i32 @PR49475(i32 %x, i16 %y) {
113113
; CHECK-LABEL: @PR49475(
114114
; CHECK-NEXT: [[M:%.*]] = and i16 [[Y:%.*]], 1
115115
; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X:%.*]], 0
116-
; CHECK-NEXT: [[B11:%.*]] = zext i1 [[B1]] to i32
117-
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[M]], 1
118-
; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32
119-
; CHECK-NEXT: [[Z3:%.*]] = or i32 [[B11]], [[TMP2]]
120-
; CHECK-NEXT: ret i32 [[Z3]]
116+
; CHECK-NEXT: [[B2:%.*]] = icmp eq i16 [[M]], 0
117+
; CHECK-NEXT: [[T1:%.*]] = or i1 [[B1]], [[B2]]
118+
; CHECK-NEXT: [[Z:%.*]] = zext i1 [[T1]] to i32
119+
; CHECK-NEXT: ret i32 [[Z]]
121120
;
122121
%m = and i16 %y, 1
123122
%b1 = icmp eq i32 %x, 0
@@ -126,3 +125,50 @@ define i32 @PR49475(i32 %x, i16 %y) {
126125
%z = zext i1 %t1 to i32
127126
ret i32 %z
128127
}
128+
129+
; This would infinite-loop.
130+
131+
define i8 @PR49475_infloop(i32 %t0, i16 %insert, i64 %e, i8 %i162) {
132+
; CHECK-LABEL: @PR49475_infloop(
133+
; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[T0:%.*]], 0
134+
; CHECK-NEXT: [[B2:%.*]] = icmp eq i16 [[INSERT:%.*]], 0
135+
; CHECK-NEXT: [[T1:%.*]] = or i1 [[B]], [[B2]]
136+
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[T1]] to i32
137+
; CHECK-NEXT: [[AND:%.*]] = and i32 [[EXT]], [[T0]]
138+
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[AND]], 140
139+
; CHECK-NEXT: [[XOR1:%.*]] = zext i32 [[TMP1]] to i64
140+
; CHECK-NEXT: [[CONV16:%.*]] = sext i8 [[I162:%.*]] to i64
141+
; CHECK-NEXT: [[SUB17:%.*]] = sub i64 [[CONV16]], [[E:%.*]]
142+
; CHECK-NEXT: [[SEXT:%.*]] = shl i64 [[SUB17]], 32
143+
; CHECK-NEXT: [[CONV18:%.*]] = ashr exact i64 [[SEXT]], 32
144+
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[CONV18]], [[XOR1]]
145+
; CHECK-NEXT: [[CONV19:%.*]] = zext i1 [[CMP]] to i16
146+
; CHECK-NEXT: [[OR21:%.*]] = or i16 [[CONV19]], [[INSERT]]
147+
; CHECK-NEXT: [[TRUNC44:%.*]] = trunc i16 [[OR21]] to i8
148+
; CHECK-NEXT: [[INC:%.*]] = or i8 [[TRUNC44]], [[I162]]
149+
; CHECK-NEXT: [[TOBOOL23_NOT:%.*]] = icmp eq i16 [[OR21]], 0
150+
; CHECK-NEXT: call void @llvm.assume(i1 [[TOBOOL23_NOT]])
151+
; CHECK-NEXT: ret i8 [[INC]]
152+
;
153+
%b = icmp eq i32 %t0, 0
154+
%b2 = icmp eq i16 %insert, 0
155+
%t1 = or i1 %b, %b2
156+
%ext = zext i1 %t1 to i32
157+
%and = and i32 %t0, %ext
158+
%conv13 = zext i32 %and to i64
159+
%xor = xor i64 %conv13, 140
160+
%conv16 = sext i8 %i162 to i64
161+
%sub17 = sub i64 %conv16, %e
162+
%sext = shl i64 %sub17, 32
163+
%conv18 = ashr exact i64 %sext, 32
164+
%cmp = icmp sge i64 %xor, %conv18
165+
%conv19 = zext i1 %cmp to i16
166+
%or21 = or i16 %insert, %conv19
167+
%trunc44 = trunc i16 %or21 to i8
168+
%inc = add i8 %i162, %trunc44
169+
%tobool23.not = icmp eq i16 %or21, 0
170+
call void @llvm.assume(i1 %tobool23.not)
171+
ret i8 %inc
172+
}
173+
174+
declare void @llvm.assume(i1 noundef)

0 commit comments

Comments
 (0)