Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ValueTracking] Handle range attributes in isGuaranteedNotToBeUndefOrPoison #88199

Closed
wants to merge 2 commits into from

Conversation

andjo403
Copy link
Contributor

@andjo403 andjo403 commented Apr 9, 2024

No description provided.

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 9, 2024

@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Andreas Jonson (andjo403)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/88199.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/ValueTracking.cpp (+4)
  • (modified) llvm/test/Transforms/InstSimplify/freeze.ll (+39-3)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ca48cfe7738154..33d1855db9519b 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7008,6 +7008,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
     return false;
 
   if (const auto *A = dyn_cast<Argument>(V)) {
+    if (includesPoison(Kind) && A->hasAttribute(Attribute::Range))
+      return false;
     if (A->hasAttribute(Attribute::NoUndef) ||
         A->hasAttribute(Attribute::Dereferenceable) ||
         A->hasAttribute(Attribute::DereferenceableOrNull))
@@ -7055,6 +7057,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
       return true;
 
     if (const auto *CB = dyn_cast<CallBase>(V)) {
+      if (includesPoison(Kind) && CB->hasRetAttr(Attribute::Range))
+        return false;
       if (CB->hasRetAttr(Attribute::NoUndef) ||
           CB->hasRetAttr(Attribute::Dereferenceable) ||
           CB->hasRetAttr(Attribute::DereferenceableOrNull))
diff --git a/llvm/test/Transforms/InstSimplify/freeze.ll b/llvm/test/Transforms/InstSimplify/freeze.ll
index 6c4b16076e724e..6792b6603dfde4 100644
--- a/llvm/test/Transforms/InstSimplify/freeze.ll
+++ b/llvm/test/Transforms/InstSimplify/freeze.ll
@@ -269,12 +269,12 @@ define ptr @call_noundef_ptr(ptr %ptr) {
 define ptr @invoke_noundef_ptr(ptr %ptr) personality i8 1 {
 ; CHECK-LABEL: @invoke_noundef_ptr(
 ; CHECK-NEXT:    invoke void @f3(ptr noundef [[PTR:%.*]])
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[UNWIND:%.*]]
+; CHECK-NEXT:            to label [[NORMAL:%.*]] unwind label [[UNWIND:%.*]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret ptr [[PTR]]
 ; CHECK:       unwind:
 ; CHECK-NEXT:    [[TMP1:%.*]] = landingpad ptr
-; CHECK-NEXT:    cleanup
+; CHECK-NEXT:            cleanup
 ; CHECK-NEXT:    resume ptr [[PTR]]
 ;
   %q = freeze ptr %ptr
@@ -443,7 +443,7 @@ EXIT:
 define i32 @brcond_switch(i32 %x) {
 ; CHECK-LABEL: @brcond_switch(
 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[EXIT:%.*]] [
-; CHECK-NEXT:    i32 0, label [[A:%.*]]
+; CHECK-NEXT:      i32 0, label [[A:%.*]]
 ; CHECK-NEXT:    ]
 ; CHECK:       A:
 ; CHECK-NEXT:    ret i32 [[X]]
@@ -496,6 +496,42 @@ A:
 B:
   ret i1 1
 }
+
+define i8 @range_attr(i8 noundef range(i8 1, 0) %x) {
+; CHECK-LABEL: @range_attr(
+; CHECK-NEXT:    [[X:%.*]] = freeze i8 [[X1:%.*]]
+; CHECK-NEXT:    ret i8 [[X]]
+;
+  %y = freeze i8 %x
+  ret i8 %y
+}
+
+declare noundef range(i8 1, 0) i8 @returns_range_helper()
+
+define i8 @range_return() {
+; CHECK-LABEL: @range_return(
+; CHECK-NEXT:    [[X:%.*]] = call i8 @returns_range_helper()
+; CHECK-NEXT:    [[Y:%.*]] = freeze i8 [[X]]
+; CHECK-NEXT:    ret i8 [[Y]]
+;
+  %x = call i8 @returns_range_helper()
+  %y = freeze i8 %x
+  ret i8 %y
+}
+
+declare noundef i8 @returns_i8_helper()
+
+define i8 @range_call() {
+; CHECK-LABEL: @range_call(
+; CHECK-NEXT:    [[X:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()
+; CHECK-NEXT:    [[Y:%.*]] = freeze i8 [[X]]
+; CHECK-NEXT:    ret i8 [[Y]]
+;
+  %x = call range(i8 1, 0) i8 @returns_i8_helper()
+  %y = freeze i8 %x
+  ret i8 %y
+}
+
 declare void @f1(i1)
 declare void @f2()
 declare void @f3(ptr)

@andjo403
Copy link
Contributor Author

andjo403 commented Apr 9, 2024

there is also the functions Instruction::dropPoisonGeneratingFlags and Operator::hasPoisonGeneratingFlags that I think also shall be updated due to range can generate poison but I do not know how to handle the dropPoisonGeneratingFlags for functions that have the attribute on the return value.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change doesn't make sense. If the argument is noundef range then the argument indeed cannot be poison, as a poison value (including one produced by the range annotation) would result in immediate UB.

@andjo403
Copy link
Contributor Author

ok makes sense thanks for the explanation

@andjo403 andjo403 closed this Apr 10, 2024
@andjo403 andjo403 deleted the isGuaranteedNotToBeUndefOrPoison branch April 10, 2024 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants