[clang] [llvm] [IR] Drop parameter attributes (PR #195516)

via cfe-commits cfe-commits at lists.llvm.org
Sun May 3 05:55:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Yingwei Zheng (dtcxzyw)

<details>
<summary>Changes</summary>

Previously `dropPoisonGeneratingReturnAttributes` only considers poison-generating attributes on return values. However, it is not enough as shown in https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/245/files. 

This patch also drops parameter attributes, as `dropUBImplyingAttrsAndMetadata` does.

IR diff shows this patch doesn't block existing transformations: https://github.com/dtcxzyw/llvm-opt-benchmark-nightly/pull/246
Compile-time impact looks neutral: https://llvm-compile-time-tracker.com/compare.php?from=d184d9ad0e9f7f34f05d88b7245e7a9a248b245b&to=cdc17034e313657bfd87936e01fa21abd55e184a&stat=instructions:u


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


5 Files Affected:

- (modified) clang/test/Headers/__clang_hip_math.hip (+3-2) 
- (modified) llvm/include/llvm/IR/Instruction.h (+7-8) 
- (modified) llvm/lib/IR/Instruction.cpp (+16-8) 
- (modified) llvm/lib/IR/Operator.cpp (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/ispow2.ll (+2-2) 


``````````diff
diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip
index 3c15336584501..600a786a5e5ea 100644
--- a/clang/test/Headers/__clang_hip_math.hip
+++ b/clang/test/Headers/__clang_hip_math.hip
@@ -712,6 +712,7 @@ extern "C" __device__ float test_asinhf(float x) {
   return asinhf(x);
 }
 
+//
 // DEFAULT-LABEL: define dso_local noundef double @test_asinh(
 // DEFAULT-SAME: double noundef [[X:%.*]]) local_unnamed_addr #[[ATTR5]] {
 // DEFAULT-NEXT:  [[ENTRY:.*:]]
@@ -2455,7 +2456,7 @@ extern "C" __device__ double test_fmod(double x, double y) {
 // DEFAULT-NEXT:    [[TMP2:%.*]] = extractvalue { float, i32 } [[TMP0]], 0
 // DEFAULT-NEXT:    ret float [[TMP2]]
 //
-// FINITEONLY-LABEL: define dso_local noundef nofpclass(nan inf) float @test_frexpf(
+// FINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @test_frexpf(
 // FINITEONLY-SAME: float noundef nofpclass(nan inf) [[X:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] {
 // FINITEONLY-NEXT:  [[ENTRY:.*:]]
 // FINITEONLY-NEXT:    [[TMP0:%.*]] = tail call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan inf) [[X]])
@@ -2504,7 +2505,7 @@ extern "C" __device__ float test_frexpf(float x, int* y) {
 // DEFAULT-NEXT:    [[TMP2:%.*]] = extractvalue { double, i32 } [[TMP0]], 0
 // DEFAULT-NEXT:    ret double [[TMP2]]
 //
-// FINITEONLY-LABEL: define dso_local noundef nofpclass(nan inf) double @test_frexp(
+// FINITEONLY-LABEL: define dso_local nofpclass(nan inf) double @test_frexp(
 // FINITEONLY-SAME: double noundef nofpclass(nan inf) [[X:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr #[[ATTR7]] {
 // FINITEONLY-NEXT:  [[ENTRY:.*:]]
 // FINITEONLY-NEXT:    [[TMP0:%.*]] = tail call { double, i32 } @llvm.frexp.f64.i32(double nofpclass(nan inf) [[X]])
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 0b57ad4d0a379..0e6c122a4e2ef 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -588,23 +588,22 @@ class Instruction : public User,
   LLVM_ABI void dropPoisonGeneratingMetadata();
 
   /// Return true if this instruction has poison-generating attribute.
-  LLVM_ABI bool hasPoisonGeneratingReturnAttributes() const LLVM_READONLY;
+  LLVM_ABI bool hasPoisonGeneratingAttributes() const LLVM_READONLY;
 
-  /// Drops return attributes that may generate poison.
-  LLVM_ABI void dropPoisonGeneratingReturnAttributes();
+  /// Drops attributes that may generate poison.
+  LLVM_ABI void dropPoisonGeneratingAttributes();
 
   /// Return true if this instruction has poison-generating flags,
-  /// return attributes or metadata.
+  /// attributes or metadata.
   bool hasPoisonGeneratingAnnotations() const {
-    return hasPoisonGeneratingFlags() ||
-           hasPoisonGeneratingReturnAttributes() ||
+    return hasPoisonGeneratingFlags() || hasPoisonGeneratingAttributes() ||
            hasPoisonGeneratingMetadata();
   }
 
-  /// Drops flags, return attributes and metadata that may generate poison.
+  /// Drops flags, attributes and metadata that may generate poison.
   void dropPoisonGeneratingAnnotations() {
     dropPoisonGeneratingFlags();
-    dropPoisonGeneratingReturnAttributes();
+    dropPoisonGeneratingAttributes();
     dropPoisonGeneratingMetadata();
   }
 
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 1932ff72b0a35..b002832ec0624 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -533,18 +533,24 @@ void Instruction::dropPoisonGeneratingMetadata() {
     eraseMetadata(ID);
 }
 
-bool Instruction::hasPoisonGeneratingReturnAttributes() const {
+bool Instruction::hasPoisonGeneratingAttributes() const {
   if (const auto *CB = dyn_cast<CallBase>(this)) {
-    AttributeSet RetAttrs = CB->getAttributes().getRetAttrs();
-    return RetAttrs.hasAttribute(Attribute::Range) ||
-           RetAttrs.hasAttribute(Attribute::Alignment) ||
-           RetAttrs.hasAttribute(Attribute::NonNull) ||
-           RetAttrs.hasAttribute(Attribute::NoFPClass);
+    auto HasPoisonGeneratingAttributes = [](AttributeSet Attrs) {
+      return Attrs.hasAttribute(Attribute::Range) ||
+             Attrs.hasAttribute(Attribute::Alignment) ||
+             Attrs.hasAttribute(Attribute::NonNull) ||
+             Attrs.hasAttribute(Attribute::NoFPClass);
+    };
+    if (HasPoisonGeneratingAttributes(CB->getRetAttributes()))
+      return true;
+    for (unsigned ArgNo = 0; ArgNo < CB->arg_size(); ArgNo++)
+      if (HasPoisonGeneratingAttributes(CB->getParamAttributes(ArgNo)))
+        return true;
   }
   return false;
 }
 
-void Instruction::dropPoisonGeneratingReturnAttributes() {
+void Instruction::dropPoisonGeneratingAttributes() {
   if (auto *CB = dyn_cast<CallBase>(this)) {
     AttributeMask AM;
     AM.addAttribute(Attribute::Range);
@@ -552,8 +558,10 @@ void Instruction::dropPoisonGeneratingReturnAttributes() {
     AM.addAttribute(Attribute::NonNull);
     AM.addAttribute(Attribute::NoFPClass);
     CB->removeRetAttrs(AM);
+    for (unsigned ArgNo = 0; ArgNo < CB->arg_size(); ArgNo++)
+      CB->removeParamAttrs(ArgNo, AM);
   }
-  assert(!hasPoisonGeneratingReturnAttributes() && "must be kept in sync");
+  assert(!hasPoisonGeneratingAttributes() && "must be kept in sync");
 }
 
 void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index bd92a32142ebc..aa6c739cee665 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -75,7 +75,7 @@ bool Operator::hasPoisonGeneratingAnnotations() const {
   if (hasPoisonGeneratingFlags())
     return true;
   auto *I = dyn_cast<Instruction>(this);
-  return I && (I->hasPoisonGeneratingReturnAttributes() ||
+  return I && (I->hasPoisonGeneratingAttributes() ||
                I->hasPoisonGeneratingMetadata());
 }
 
diff --git a/llvm/test/Transforms/InstCombine/ispow2.ll b/llvm/test/Transforms/InstCombine/ispow2.ll
index df697e686d986..be8d89d246843 100644
--- a/llvm/test/Transforms/InstCombine/ispow2.ll
+++ b/llvm/test/Transforms/InstCombine/ispow2.ll
@@ -1553,7 +1553,7 @@ define i1 @is_power2_or_zero_with_range(i32 %x) {
 ; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ult i32 [[CTPOP]], 2
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
-  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
+  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 range(i32 1, 0) %x)
   %cmp = icmp eq i32 %ctpop, 1
   %notzero = icmp eq i32 %x, 0
   %res = select i1 %notzero, i1 true, i1 %cmp
@@ -1566,7 +1566,7 @@ define i1 @is_power2_or_zero_inv_with_range(i32 %x) {
 ; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ugt i32 [[CTPOP]], 1
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
-  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
+  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 range(i32 1, 0) %x)
   %cmp = icmp ne i32 %ctpop, 1
   %notzero = icmp ne i32 %x, 0
   %res = select i1 %notzero, i1 %cmp, i1 false

``````````

</details>


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


More information about the cfe-commits mailing list