[llvm] [Attr] Add `noipa` function attribute (PR #203304)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 08:48:23 PDT 2026


nikic wrote:

AI-generated test cases that apparently still optimize under noipa + noinline.
```
; Test: IPSCCP constant-propagating through arguments of a noipa function.
; If noipa is working, IPSCCP should NOT propagate the constant 42 into @foo,
; because analyzing calls to @foo to determine argument values is IPA.
;
; RUN: opt -passes=ipsccp -S < %s

define internal i32 @foo(i32 %x) noipa noinline {
  ret i32 %x
}

define i32 @bar() {
  %r = call i32 @foo(i32 42)
  ret i32 %r
}
```
```
; Test: DeadArgumentElimination removing unused args of a noipa function.
; If noipa is working, DAE should NOT remove the unused argument %y from @foo,
; because determining which arguments are dead requires inspecting the definition.
;
; RUN: opt -passes=deadargelim -S < %s

define internal i32 @foo(i32 %x, i32 %y) noipa noinline {
  ret i32 %x
}

define i32 @bar() {
  %r = call i32 @foo(i32 1, i32 2)
  ret i32 %r
}
```
```
; Test: ArgumentPromotion promoting a by-ref argument of a noipa function.
; If noipa is working, argpromotion should NOT promote the pointer argument,
; because it requires inspecting the function body to determine load patterns.
;
; RUN: opt -passes=argpromotion -S < %s

define internal i32 @foo(ptr %p) noipa noinline {
  %v = load i32, ptr %p
  ret i32 %v
}

define i32 @bar() {
  %a = alloca i32
  store i32 7, ptr %a
  %r = call i32 @foo(ptr %a)
  ret i32 %r
}
```
```
; Test: GlobalOpt changing calling convention of a noipa function.
; If noipa is working, GlobalOpt should NOT change the CC of @foo,
; because it requires analyzing callers/callees interprocedurally.
;
; RUN: opt -passes=globalopt -S < %s

define internal i32 @foo(i32 %x) noipa noinline {
  ret i32 %x
}

define i32 @bar() {
  %r = call i32 @foo(i32 5)
  ret i32 %r
}
```
```
; Test: MergeFunctions merging a noipa function with an identical one.
; If noipa is working, MergeFunctions should NOT merge @foo into @baz
; (or vice versa), because it inspects the function definitions.
;
; RUN: opt -passes=mergefunc -S < %s

define internal i32 @foo(i32 %x, i32 %y) noipa noinline {
  %sum = add i32 %x, %y
  %mul = mul i32 %sum, %x
  %sub = sub i32 %mul, %y
  ret i32 %sub
}

define internal i32 @baz(i32 %x, i32 %y) noinline {
  %sum = add i32 %x, %y
  %mul = mul i32 %sum, %x
  %sub = sub i32 %mul, %y
  ret i32 %sub
}

define i32 @bar() {
  %r1 = call i32 @foo(i32 1, i32 2)
  %r2 = call i32 @baz(i32 3, i32 4)
  %r = add i32 %r1, %r2
  ret i32 %r
}
```

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


More information about the llvm-commits mailing list