[ConstraintElimination] Add function arguments to constraint system before solving
authorZain Jaffal <z_jaffal@apple.com>
Mon, 3 Apr 2023 13:16:46 +0000 (14:16 +0100)
committerZain Jaffal <z_jaffal@apple.com>
Mon, 3 Apr 2023 13:16:49 +0000 (14:16 +0100)
If there is an optimisation opportunity and the function argument hasn’t been added to constraint
system through previous facts we fail to optimise it.

It might be a good idea to start the constraint system with all the function arguments added to the system

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D144879

llvm/include/llvm/Analysis/ConstraintSystem.h
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/transfer-signed-facts-to-unsigned.ll

index 05785d1..29ba99b 100644 (file)
@@ -19,7 +19,6 @@
 namespace llvm {
 
 class Value;
-
 class ConstraintSystem {
   struct Entry {
     int64_t Coefficient;
@@ -68,8 +67,14 @@ class ConstraintSystem {
 
 public:
   ConstraintSystem() {}
+  ConstraintSystem(ArrayRef<Value *> FunctionArgs) {
+    NumVariables += FunctionArgs.size();
+    for (auto *Arg : FunctionArgs) {
+      Value2Index.insert({Arg, Value2Index.size() + 1});
+    }
+  }
   ConstraintSystem(const DenseMap<Value *, unsigned> &Value2Index)
-      : Value2Index(Value2Index) {}
+      : NumVariables(Value2Index.size()), Value2Index(Value2Index) {}
 
   bool addVariableRow(ArrayRef<int64_t> R) {
     assert(Constraints.empty() || R.size() == NumVariables);
index d0b59d6..762061b 100644 (file)
@@ -139,7 +139,8 @@ class ConstraintInfo {
   const DataLayout &DL;
 
 public:
-  ConstraintInfo(const DataLayout &DL) : DL(DL) {}
+  ConstraintInfo(const DataLayout &DL, ArrayRef<Value *> FunctionArgs)
+      : UnsignedCS(FunctionArgs), SignedCS(FunctionArgs), DL(DL) {}
 
   DenseMap<Value *, unsigned> &getValue2Index(bool Signed) {
     return Signed ? SignedCS.getValue2Index() : UnsignedCS.getValue2Index();
@@ -1087,8 +1088,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT,
                                  OptimizationRemarkEmitter &ORE) {
   bool Changed = false;
   DT.updateDFSNumbers();
-
-  ConstraintInfo Info(F.getParent()->getDataLayout());
+  SmallVector<Value *> FunctionArgs;
+  for (Value &Arg : F.args())
+    FunctionArgs.push_back(&Arg);
+  ConstraintInfo Info(F.getParent()->getDataLayout(), FunctionArgs);
   State S(DT);
   std::unique_ptr<Module> ReproducerModule(
       DumpReproducers ? new Module(F.getName(), F.getContext()) : nullptr);
index 2baa6b0..cc22ea7 100644 (file)
@@ -295,8 +295,6 @@ else:
   ret i1 1
 }
 
-; TODO: Even though %cnt is not known signed positive %cmp can be simplified
-; because %add.ptr uses it zero-extended.
 define i1 @cnt_not_known_positive_sgt_against_base_with_zext(ptr %p, i32 %cnt) {
 ; CHECK-LABEL: @cnt_not_known_positive_sgt_against_base_with_zext(
 ; CHECK-NEXT:  entry:
@@ -305,7 +303,7 @@ define i1 @cnt_not_known_positive_sgt_against_base_with_zext(ptr %p, i32 %cnt) {
 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp uge ptr [[ADD_PTR]], [[P]]
-; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
 ; CHECK:       then:
 ; CHECK-NEXT:    ret i1 false
 ; CHECK:       else:
@@ -326,8 +324,6 @@ else:
   ret i1 1
 }
 
-; TODO: Even though %cnt is not known signed positive %cmp can be simplified
-; because %add.ptr uses it zero-extended.
 define i1 @cnt_not_known_positive_sge_against_base_with_zext(ptr %p, i32 %cnt) {
 ; CHECK-LABEL: @cnt_not_known_positive_sge_against_base_with_zext(
 ; CHECK-NEXT:  entry:
@@ -336,7 +332,7 @@ define i1 @cnt_not_known_positive_sge_against_base_with_zext(ptr %p, i32 %cnt) {
 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp uge ptr [[ADD_PTR]], [[P]]
-; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
 ; CHECK:       then:
 ; CHECK-NEXT:    ret i1 false
 ; CHECK:       else:
@@ -453,7 +449,6 @@ else:
   ret i1 1
 }
 
-; TODO: Even though %cnt is not known signed positive %cmp can be simplified
 ; because %add.ptr uses it zero-extended.
 define i1 @cnt_not_known_positive_from_branch_check_against_base_struct_ugt_with_zext(ptr %p, i32 %cnt) {
 ; CHECK-LABEL: @cnt_not_known_positive_from_branch_check_against_base_struct_ugt_with_zext(
@@ -464,7 +459,7 @@ define i1 @cnt_not_known_positive_from_branch_check_against_base_struct_ugt_with
 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
 ; CHECK-NEXT:    [[GEP_EXT:%.*]] = getelementptr inbounds [[T:%.*]], ptr [[P:%.*]], i64 0, i32 1, i64 [[EXT]]
 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ugt ptr [[GEP_EXT]], [[P]]
-; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE]]
+; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE]]
 ; CHECK:       then:
 ; CHECK-NEXT:    ret i1 false
 ; CHECK:       else: