Skip to content

Commit 229f631

Browse files
authored
Merge pull request swiftlang#7925 from fhahn/ce-sub-fix
[ConstraintElim] Pick NUWSub fix.
2 parents d0c3489 + 188249f commit 229f631

File tree

2 files changed

+130
-7
lines changed

2 files changed

+130
-7
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,13 @@ struct Decomposition {
358358
append_range(Vars, Other.Vars);
359359
}
360360

361+
void sub(const Decomposition &Other) {
362+
Decomposition Tmp = Other;
363+
Tmp.mul(-1);
364+
add(Tmp.Offset);
365+
append_range(Vars, Tmp.Vars);
366+
}
367+
361368
void mul(int64_t Factor) {
362369
Offset = multiplyWithOverflow(Offset, Factor);
363370
for (auto &Var : Vars)
@@ -542,10 +549,12 @@ static Decomposition decompose(Value *V,
542549
return Result;
543550
}
544551

545-
if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI))
546-
return {-1 * CI->getSExtValue(), {{1, Op0}}};
547-
if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1))))
548-
return {0, {{1, Op0}, {-1, Op1}}};
552+
if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) {
553+
auto ResA = decompose(Op0, Preconditions, IsSigned, DL);
554+
auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
555+
ResA.sub(ResB);
556+
return ResA;
557+
}
549558

550559
return {V, IsKnownNonNegative};
551560
}

llvm/test/Transforms/ConstraintElimination/sub-nuw.ll

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,10 @@ define i1 @sub_nuw_neg_i16(i16 %a) {
319319
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 0, [[NEG2]]
320320
; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
321321
; CHECK: exit.1:
322-
; CHECK-NEXT: ret i1 false
322+
; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i16 [[A]], 0
323+
; CHECK-NEXT: ret i1 [[C_2]]
323324
; CHECK: exit.2:
324-
; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i16 [[A]], 0
325-
; CHECK-NEXT: ret i1 [[C_3]]
325+
; CHECK-NEXT: ret i1 true
326326
;
327327
entry:
328328
%neg2 = sub nuw i16 %a, -305
@@ -380,3 +380,117 @@ entry:
380380
%c = icmp ugt i64 %neg2, 0
381381
ret i1 %c
382382
}
383+
384+
define i1 @pr76713(i16 %i1, i16 %i3) {
385+
; CHECK-LABEL: @pr76713(
386+
; CHECK-NEXT: entry:
387+
; CHECK-NEXT: [[C1:%.*]] = icmp ult i16 [[I1:%.*]], -1
388+
; CHECK-NEXT: [[C2:%.*]] = icmp uge i16 [[I1]], -3
389+
; CHECK-NEXT: [[C3:%.*]] = icmp ult i16 [[I3:%.*]], 2
390+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]
391+
; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[AND]], [[C3]]
392+
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
393+
; CHECK: then:
394+
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i16 [[I1]], -3
395+
; CHECK-NEXT: [[ARRAYIDX_IDX:%.*]] = mul nuw nsw i16 [[I3]], 4
396+
; CHECK-NEXT: [[I6:%.*]] = add nuw nsw i16 [[ARRAYIDX_IDX]], [[SUB]]
397+
; CHECK-NEXT: [[C4:%.*]] = icmp ult i16 12, [[I6]]
398+
; CHECK-NEXT: ret i1 [[C4]]
399+
; CHECK: else:
400+
; CHECK-NEXT: ret i1 false
401+
;
402+
entry:
403+
%c1 = icmp ult i16 %i1, -1
404+
%c2 = icmp uge i16 %i1, -3
405+
%c3 = icmp ult i16 %i3, 2
406+
%and = and i1 %c1, %c2
407+
%and.2 = and i1 %and, %c3
408+
br i1 %and, label %then, label %else
409+
410+
then:
411+
%sub = sub nuw nsw i16 %i1, -3
412+
%arrayidx.idx = mul nuw nsw i16 %i3, 4
413+
%i6 = add nuw nsw i16 %arrayidx.idx, %sub
414+
%c4 = icmp ult i16 12, %i6
415+
ret i1 %c4
416+
417+
else:
418+
ret i1 0
419+
}
420+
421+
define void @sub_nuw_chained_positive_constants(i16 %a) {
422+
; CHECK-LABEL: @sub_nuw_chained_positive_constants(
423+
; CHECK-NEXT: entry:
424+
; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[A:%.*]], 10
425+
; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i16 [[SUB1]], 20
426+
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i16 [[SUB2]], 90
427+
; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
428+
; CHECK: exit.1:
429+
; CHECK-NEXT: call void @use(i1 true)
430+
; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i16 [[A]], 121
431+
; CHECK-NEXT: call void @use(i1 [[C_3]])
432+
; CHECK-NEXT: ret void
433+
; CHECK: exit.2:
434+
; CHECK-NEXT: call void @use(i1 false)
435+
; CHECK-NEXT: call void @use(i1 false)
436+
; CHECK-NEXT: ret void
437+
;
438+
entry:
439+
%sub1 = sub nuw i16 %a, 10
440+
%sub2 = sub nuw i16 %sub1, 20
441+
%c.1 = icmp ugt i16 %sub2, 90
442+
br i1 %c.1, label %exit.1, label %exit.2
443+
444+
exit.1:
445+
%c.2 = icmp ugt i16 %a, 120
446+
call void @use(i1 %c.2)
447+
%c.3 = icmp ugt i16 %a, 121
448+
call void @use(i1 %c.3)
449+
ret void
450+
451+
exit.2:
452+
%c.4 = icmp ugt i16 %a, 120
453+
call void @use(i1 %c.4)
454+
%c.5 = icmp ugt i16 %a, 121
455+
call void @use(i1 %c.5)
456+
ret void
457+
}
458+
459+
define void @sub_nuw_chained_negative_constants(i8 %a) {
460+
; CHECK-LABEL: @sub_nuw_chained_negative_constants(
461+
; CHECK-NEXT: entry:
462+
; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i8 [[A:%.*]], 10
463+
; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i8 [[SUB1]], -126
464+
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[SUB2]], 20
465+
; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]]
466+
; CHECK: exit.1:
467+
; CHECK-NEXT: call void @use(i1 true)
468+
; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i8 [[A]], -95
469+
; CHECK-NEXT: call void @use(i1 [[C_3]])
470+
; CHECK-NEXT: ret void
471+
; CHECK: exit.2:
472+
; CHECK-NEXT: call void @use(i1 false)
473+
; CHECK-NEXT: call void @use(i1 false)
474+
; CHECK-NEXT: ret void
475+
;
476+
entry:
477+
%sub1 = sub nuw i8 %a, 10
478+
%sub2 = sub nuw i8 %sub1, 130
479+
%c.1 = icmp ugt i8 %sub2, 20
480+
br i1 %c.1, label %exit.1, label %exit.2
481+
482+
exit.1:
483+
%c.2 = icmp ugt i8 %a, 160
484+
call void @use(i1 %c.2)
485+
%c.3 = icmp ugt i8 %a, 161
486+
call void @use(i1 %c.3)
487+
ret void
488+
489+
490+
exit.2:
491+
%c.4 = icmp ugt i8 %a, 160
492+
call void @use(i1 %c.4)
493+
%c.5 = icmp ugt i8 %a, 161
494+
call void @use(i1 %c.5)
495+
ret void
496+
}

0 commit comments

Comments
 (0)