[llvm] [ValueTracking] isNonZero sub of ptr2int's with recursive GEP (PR #68680)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 25 06:54:24 PDT 2023


================
@@ -424,3 +424,330 @@ T:
 F:
   br label %T
 }
+
+define i1 @phi_sub_recursiveGEP_knownNonZero1(ptr noundef %val1) {
+; CHECK-LABEL: @phi_sub_recursiveGEP_knownNonZero1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[VAL1:%.*]], null
+; CHECK-NEXT:    br i1 [[CMP_I]], label [[_Z9STRINGLENPKS_EXIT:%.*]], label [[WHILE_COND_I:%.*]]
+; CHECK:       while.cond.i:
+; CHECK-NEXT:    [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 1
+; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2
+; CHECK-NEXT:    [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0
+; CHECK-NEXT:    br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]]
+; CHECK:       while.end.i:
+; CHECK-NEXT:    br label [[_Z9STRINGLENPKS_EXIT]]
+; CHECK:       _Z9stringlenPKs.exit:
+; CHECK-NEXT:    ret i1 [[CMP_I]]
+;
+entry:
+  %cmp.i = icmp eq ptr %val1, null
+  br i1 %cmp.i, label %_Z9stringlenPKs.exit, label %while.cond.i
+
+while.cond.i:
+  %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ]
+  %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1
+  %0 = load i8, ptr %test.0.i, align 2
+  %cmp3.not.i = icmp eq i8 %0, 0
+  br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i
+
+while.end.i:
+  %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64
+  %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64
+  %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i
+  br label %_Z9stringlenPKs.exit
+
+_Z9stringlenPKs.exit:
+  %retval.0.i = phi i64 [ %sub.ptr.sub.i, %while.end.i ], [ 0, %entry ]
+  %bool = icmp eq i64 %retval.0.i, 0
----------------
bipmis wrote:

Thanks for the review. 
For the given example code visitPHINode() should be invoked first and the code then identifies it as a knownNonZero() scenario and does the transformation. Exclusively this can be a check done in visitIcmp() too before we fold the icmp(sub) which could help fold additional scenarios.
Additionally since we are identifying it is a isNonZeroSub() this can be applied beyond scenarios where the only use of phi is a icmp. This can also be applied to 
1. Multiple uses of phi with or, icmp
2. Single use of phi with or(icmp)
Some of these examples can be added for the patch.

https://github.com/llvm/llvm-project/pull/68680


More information about the llvm-commits mailing list