Skip to content

Commit 72768d9

Browse files
authored
[ConstraintElim] Teach checkAndReplaceCondition about samesign (#128168)
`samesign upred` is equivalent to `spred`: https://alive2.llvm.org/ce/z/57iaEC
1 parent 0f34b65 commit 72768d9

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,7 @@ static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
14271427
}
14281428

14291429
static bool checkAndReplaceCondition(
1430-
CmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
1430+
ICmpInst *Cmp, ConstraintInfo &Info, unsigned NumIn, unsigned NumOut,
14311431
Instruction *ContextInst, Module *ReproducerModule,
14321432
ArrayRef<ReproducerEntry> ReproducerCondStack, DominatorTree &DT,
14331433
SmallVectorImpl<Instruction *> &ToRemove) {
@@ -1460,6 +1460,15 @@ static bool checkAndReplaceCondition(
14601460
checkCondition(Cmp->getPredicate(), Cmp->getOperand(0),
14611461
Cmp->getOperand(1), Cmp, Info))
14621462
return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
1463+
1464+
// When the predicate is samesign and unsigned, we can also make use of the
1465+
// signed predicate information.
1466+
if (Cmp->hasSameSign() && Cmp->isUnsigned())
1467+
if (auto ImpliedCondition =
1468+
checkCondition(Cmp->getSignedPredicate(), Cmp->getOperand(0),
1469+
Cmp->getOperand(1), Cmp, Info))
1470+
return ReplaceCmpWithConstant(Cmp, *ImpliedCondition);
1471+
14631472
return false;
14641473
}
14651474

llvm/test/Transforms/ConstraintElimination/transfer-samesign-facts.ll

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,64 @@ define i1 @ugt_assumed_positive_values(i8 %a, i8 %b) {
303303

304304
ret i1 %result
305305
}
306+
307+
define i1 @implied_condition_sgt_ugt(i8 %a, i8 %b) {
308+
; CHECK-LABEL: @implied_condition_sgt_ugt(
309+
; CHECK-NEXT: [[CMP_SGT:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
310+
; CHECK-NEXT: br i1 [[CMP_SGT]], label [[GREATER:%.*]], label [[EXIT:%.*]]
311+
; CHECK: greater:
312+
; CHECK-NEXT: ret i1 true
313+
; CHECK: exit:
314+
; CHECK-NEXT: ret i1 false
315+
;
316+
%cmp_sgt = icmp sgt i8 %a, %b
317+
br i1 %cmp_sgt, label %greater, label %exit
318+
319+
greater:
320+
%cmp_ugt = icmp samesign ugt i8 %a, %b
321+
ret i1 %cmp_ugt
322+
323+
exit:
324+
ret i1 false
325+
}
326+
327+
define i1 @implied_condition_sle_ule(i8 %a) {
328+
; CHECK-LABEL: @implied_condition_sle_ule(
329+
; CHECK-NEXT: [[CMP_SLE:%.*]] = icmp sle i8 [[A:%.*]], 42
330+
; CHECK-NEXT: br i1 [[CMP_SLE]], label [[LESS_OR_EQUAL:%.*]], label [[EXIT:%.*]]
331+
; CHECK: less_or_equal:
332+
; CHECK-NEXT: ret i1 true
333+
; CHECK: exit:
334+
; CHECK-NEXT: ret i1 false
335+
;
336+
%cmp_sle = icmp sle i8 %a, 42
337+
br i1 %cmp_sle, label %less_or_equal, label %exit
338+
339+
less_or_equal:
340+
%cmp_ule = icmp samesign ule i8 %a, 42
341+
ret i1 %cmp_ule
342+
343+
exit:
344+
ret i1 false
345+
}
346+
347+
define i1 @implied_condition_cannot_simplify(i8 %a, i8 %b) {
348+
; CHECK-LABEL: @implied_condition_cannot_simplify(
349+
; CHECK-NEXT: [[CMP_SGT:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]]
350+
; CHECK-NEXT: br i1 [[CMP_SGT]], label [[GREATER:%.*]], label [[EXIT:%.*]]
351+
; CHECK: not_equal:
352+
; CHECK-NEXT: [[CMP_UGT:%.*]] = icmp samesign ugt i8 [[A]], [[B]]
353+
; CHECK-NEXT: ret i1 [[CMP_UGT]]
354+
; CHECK: exit:
355+
; CHECK-NEXT: ret i1 false
356+
;
357+
%cmp_ne = icmp ne i8 %a, %b
358+
br i1 %cmp_ne, label %not_equal, label %exit
359+
360+
not_equal:
361+
%cmp_ugt = icmp samesign ugt i8 %a, %b
362+
ret i1 %cmp_ugt
363+
364+
exit:
365+
ret i1 false
366+
}

0 commit comments

Comments
 (0)