Skip to content

Commit 3771310

Browse files
committed
[ConstraintElimination] Convert to unsigned Pred if possible.
Convert SLE/SLT predicates to unsigned equivalents if both operands are known to be signed-positive. https://alive2.llvm.org/ce/z/tBeiZr
1 parent 1f8ffbd commit 3771310

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/Analysis/ConstraintSystem.h"
2020
#include "llvm/Analysis/GlobalsModRef.h"
2121
#include "llvm/Analysis/ValueTracking.h"
22+
#include "llvm/IR/DataLayout.h"
2223
#include "llvm/IR/Dominators.h"
2324
#include "llvm/IR/Function.h"
2425
#include "llvm/IR/IRBuilder.h"
@@ -110,7 +111,11 @@ class ConstraintInfo {
110111
ConstraintSystem UnsignedCS;
111112
ConstraintSystem SignedCS;
112113

114+
const DataLayout &DL;
115+
113116
public:
117+
ConstraintInfo(const DataLayout &DL) : DL(DL) {}
118+
114119
DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
115120
return Signed ? SignedValue2Index : UnsignedValue2Index;
116121
}
@@ -326,6 +331,14 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
326331
Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
327332
return {};
328333

334+
// If both operands are known to be non-negative, change signed predicates to
335+
// unsigned ones. This increases the reasoning effectiveness in combination
336+
// with the signed <-> unsigned transfer logic.
337+
if (CmpInst::isSigned(Pred) &&
338+
isKnownNonNegative(Op0, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1) &&
339+
isKnownNonNegative(Op1, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
340+
Pred = CmpInst::getUnsignedPredicate(Pred);
341+
329342
SmallVector<PreconditionTy, 4> Preconditions;
330343
bool IsSigned = CmpInst::isSigned(Pred);
331344
auto &Value2Index = getValue2Index(IsSigned);
@@ -646,8 +659,6 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
646659
A->printAsOperand(dbgs(), false); dbgs() << ", ";
647660
B->printAsOperand(dbgs(), false); dbgs() << "'\n");
648661
bool Added = false;
649-
assert(CmpInst::isSigned(Pred) == R.IsSigned &&
650-
"condition and constraint signs must match");
651662
auto &CSToUse = getCS(R.IsSigned);
652663
if (R.Coefficients.empty())
653664
return;
@@ -743,7 +754,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
743754
bool Changed = false;
744755
DT.updateDFSNumbers();
745756

746-
ConstraintInfo Info;
757+
ConstraintInfo Info(F.getParent()->getDataLayout());
747758
State S(DT);
748759

749760
// First, collect conditions implied by branches and blocks with their

llvm/test/Transforms/ConstraintElimination/signed-query-unsigned-system.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ define i1 @sge_0_unsigned_a_ne_0(i8 %a) {
99
; CHECK-NEXT: call void @llvm.assume(i1 [[A_NE_0]])
1010
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
1111
; CHECK-NEXT: [[T:%.*]] = icmp sge i16 [[EXT]], 0
12-
; CHECK-NEXT: ret i1 [[T]]
12+
; CHECK-NEXT: ret i1 true
1313
;
1414
%a.ne.0 = icmp ne i8 %a, 0
1515
call void @llvm.assume(i1 %a.ne.0)
@@ -24,7 +24,7 @@ define i1 @sgt_0_unsigned_a_ne_0(i8 %a) {
2424
; CHECK-NEXT: call void @llvm.assume(i1 [[A_NE_0]])
2525
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
2626
; CHECK-NEXT: [[T:%.*]] = icmp sgt i16 [[EXT]], 0
27-
; CHECK-NEXT: ret i1 [[T]]
27+
; CHECK-NEXT: ret i1 true
2828
;
2929
%a.ne.0 = icmp ne i8 %a, 0
3030
call void @llvm.assume(i1 %a.ne.0)
@@ -54,7 +54,7 @@ define i1 @sge_0_unsigned_a_sge_0(i8 %a) {
5454
; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE_0]])
5555
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
5656
; CHECK-NEXT: [[T:%.*]] = icmp sge i16 [[EXT]], 0
57-
; CHECK-NEXT: ret i1 [[T]]
57+
; CHECK-NEXT: ret i1 true
5858
;
5959
%a.sge.0 = icmp sge i8 %a, 0
6060
call void @llvm.assume(i1 %a.sge.0)
@@ -69,7 +69,7 @@ define i1 @sgt_0_unsigned_a_ugt_0(i8 %a) {
6969
; CHECK-NEXT: call void @llvm.assume(i1 [[A_UGT_0]])
7070
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
7171
; CHECK-NEXT: [[T:%.*]] = icmp sgt i16 [[EXT]], 0
72-
; CHECK-NEXT: ret i1 [[T]]
72+
; CHECK-NEXT: ret i1 true
7373
;
7474
%a.ugt.0 = icmp ugt i8 %a, 0
7575
call void @llvm.assume(i1 %a.ugt.0)
@@ -99,7 +99,7 @@ define i1 @sgt_1_unsigned_a_ugt_1(i8 %a) {
9999
; CHECK-NEXT: call void @llvm.assume(i1 [[A_UGT_1]])
100100
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
101101
; CHECK-NEXT: [[T:%.*]] = icmp sgt i16 [[EXT]], 1
102-
; CHECK-NEXT: ret i1 [[T]]
102+
; CHECK-NEXT: ret i1 true
103103
;
104104
%a.ugt.1 = icmp ugt i8 %a, 1
105105
call void @llvm.assume(i1 %a.ugt.1)
@@ -133,8 +133,8 @@ define i1 @sgt_0_unsigned_a_ugt_neg_10(i8 %a) {
133133
; CHECK-NEXT: [[A_UGT_0:%.*]] = icmp ugt i8 [[A:%.*]], 10
134134
; CHECK-NEXT: call void @llvm.assume(i1 [[A_UGT_0]])
135135
; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[A]] to i16
136-
; CHECK-NEXT: [[T:%.*]] = icmp sgt i16 [[EXT]], 0
137-
; CHECK-NEXT: ret i1 [[T]]
136+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[EXT]], 0
137+
; CHECK-NEXT: ret i1 true
138138
;
139139
%a.ugt.0 = icmp ugt i8 %a, 10
140140
call void @llvm.assume(i1 %a.ugt.0)

0 commit comments

Comments
 (0)