llvm.org GIT mirror llvm / b3f2f90
[ValueTracking] Improve isKnowNonZero for Ints Improve isKnownNonZero for integers in order to improve cttz optimizations. Differential Revision: https://reviews.llvm.org/D60846 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360222 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Robertson 4 months ago
4 changed file(s) with 19 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
18921892 return false;
18931893 }
18941894
1895 static bool isKnownNonNullFromDominatingCondition(const Value *V,
1895 static bool isKnownNonZeroFromDominatingCondition(const Value *V,
18961896 const Instruction *CtxI,
18971897 const DominatorTree *DT) {
1898 assert(V->getType()->isPointerTy() && "V must be pointer type");
18991898 assert(!isa(V) && "Did not expect ConstantPointerNull");
19001899
19011900 if (!CtxI || !DT)
19081907 break;
19091908 NumUsesExplored++;
19101909
1911 // If the value is used as an argument to a call or invoke, then argument
1912 // attributes may provide an answer about null-ness.
1913 if (auto CS = ImmutableCallSite(U))
1914 if (auto *CalledFunc = CS.getCalledFunction())
1915 for (const Argument &Arg : CalledFunc->args())
1916 if (CS.getArgOperand(Arg.getArgNo()) == V &&
1917 Arg.hasNonNullAttr() && DT->dominates(CS.getInstruction(), CtxI))
1918 return true;
1910 // If the value is a pointer and used as an argument to a call or invoke,
1911 // then argument attributes may provide an answer about null-ness.
1912 if (V->getType()->isPointerTy())
1913 if (auto CS = ImmutableCallSite(U))
1914 if (auto *CalledFunc = CS.getCalledFunction())
1915 for (const Argument &Arg : CalledFunc->args())
1916 if (CS.getArgOperand(Arg.getArgNo()) == V &&
1917 Arg.hasNonNullAttr() && DT->dominates(CS.getInstruction(), CtxI))
1918 return true;
19191919
19201920 // Consider only compare instructions uniquely controlling a branch
19211921 CmpInst::Predicate Pred;
20632063 }
20642064
20652065
2066 if (isKnownNonZeroFromDominatingCondition(V, Q.CxtI, Q.DT))
2067 return true;
2068
20662069 // Check for recursive pointer simplifications.
20672070 if (V->getType()->isPointerTy()) {
2068 if (isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
2069 return true;
2070
20712071 // Look through bitcast operations, GEPs, and int2ptr instructions as they
20722072 // do not alter the value, or at least not the nullness property of the
20732073 // value, e.g., int2ptr is allowed to zero/sign extend the value.
1212 ; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[X:%.*]], 0
1313 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
1414 ; CHECK: non_zero:
15 ; CHECK-NEXT: [[CTZ:%.*]] = call i64 @llvm.cttz.i64(i64 [[X]], i1 false), !range !0
15 ; CHECK-NEXT: [[CTZ:%.*]] = call i64 @llvm.cttz.i64(i64 [[X]], i1 true), !range !0
1616 ; CHECK-NEXT: [[CTZ32:%.*]] = trunc i64 [[CTZ]] to i32
1717 ; CHECK-NEXT: br label [[EXIT]]
1818 ; CHECK: exit:
3939 ; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[X:%.*]], 0
4040 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
4141 ; CHECK: non_zero:
42 ; CHECK-NEXT: [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 false), !range !0
42 ; CHECK-NEXT: [[CTZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[X]], i1 true), !range !0
4343 ; CHECK-NEXT: [[CTZ32:%.*]] = trunc i64 [[CTZ]] to i32
4444 ; CHECK-NEXT: br label [[EXIT]]
4545 ; CHECK: exit:
66 ; CHECK-NEXT: [[A:%.*]] = icmp eq i64 [[X:%.*]], 0
77 ; CHECK-NEXT: br i1 [[A]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
88 ; CHECK: non_zero:
9 ; CHECK-NEXT: [[B:%.*]] = icmp eq i64 [[X]], 0
10 ; CHECK-NEXT: br i1 [[B]], label [[UNREACHABLE:%.*]], label [[EXIT]]
9 ; CHECK-NEXT: br i1 false, label [[UNREACHABLE:%.*]], label [[EXIT]]
1110 ; CHECK: unreachable:
1211 ; CHECK-NEXT: br label [[EXIT]]
1312 ; CHECK: exit:
3635 ; CHECK-NEXT: [[A:%.*]] = icmp eq i64 [[X:%.*]], 0
3736 ; CHECK-NEXT: br i1 [[A]], label [[EXIT:%.*]], label [[NON_ZERO:%.*]]
3837 ; CHECK: non_zero:
39 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i64 [[X]], 0
40 ; CHECK-NEXT: br i1 [[B]], label [[EXIT]], label [[UNREACHABLE:%.*]]
38 ; CHECK-NEXT: br i1 true, label [[EXIT]], label [[UNREACHABLE:%.*]]
4139 ; CHECK: unreachable:
4240 ; CHECK-NEXT: br label [[EXIT]]
4341 ; CHECK: exit:
7270 ; CHECK: two:
7371 ; CHECK-NEXT: br label [[MAINBLOCK]]
7472 ; CHECK: mainblock:
75 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[X]], [[ONE]] ], [ 42, [[TWO]] ]
76 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[P]], 0
7773 ; CHECK-NEXT: br label [[EXIT]]
7874 ; CHECK: exit:
79 ; CHECK-NEXT: [[RES:%.*]] = phi i1 [ [[CMP]], [[MAINBLOCK]] ], [ true, [[START:%.*]] ]
75 ; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[MAINBLOCK]] ], [ true, [[START:%.*]] ]
8076 ; CHECK-NEXT: ret i1 [[RES]]
8177 ;
8278 start:
128128 }
129129
130130 ; requires fact length is non-zero
131 ; TODO: IsKnownNonNullFromDominatingConditions is currently only be done for
132 ; pointers; should handle integers too
133131 define i32 @test4(i32* noalias nocapture readonly %a) nounwind uwtable {
134132 ; CHECK-LABEL: @test4(
135133 ; CHECK-NEXT: entry:
137135 ; CHECK-NEXT: [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
138136 ; CHECK-NEXT: br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
139137 ; CHECK: preheader:
138 ; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[A]], align 4
140139 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
141140 ; CHECK: for.body:
142141 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
144143 ; CHECK-NEXT: [[R_CHK:%.*]] = icmp ult i32 [[IV]], [[LEN]]
145144 ; CHECK-NEXT: br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
146145 ; CHECK: continue:
147 ; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[A]], align 4
148146 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[I1]], [[ACC]]
149147 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[IV]], 1
150148 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000