[llvm] [LangRef] Clarify invariant.group semantics (PR #224222)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 00:56:25 PDT 2026


================
@@ -8717,24 +8724,42 @@ reference the same uniqued empty node.
 Examples:
 
 ```llvm
- at unknownPtr = external global i8
+ at unknownPtr = external global i32
 ...
-%ptr = alloca i8
-store i8 42, ptr %ptr, !invariant.group !0
+%ptr = alloca i32
+store i32 42, ptr %ptr, !invariant.group !0
 call void @foo(ptr %ptr)
 
-%a = load i8, ptr %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
+; Can assume that value under %ptr didn't change
+%a = load i32, ptr %ptr, !invariant.group !0
+call void @foo(ptr %ptr)
+
+; Can still assume that value under %ptr didn't change.
+; Having !invariant.group on the later load is not required for the invariance
+; property to be used, though it may be used as an optimization heuristic to
+; determine whether finding a dominating !invariant.group access is worthwhile.
----------------
nikic wrote:

There's a possible alternative semantics here where we only have UB if a later `!invariant.group` access observes/writes a different value to the memory. That would make something like
```
store i32 0, ptr %p, !invariant.group !0
store i32 1, ptr %p
```
well-defined, and
```
store i32 0, ptr %p, !invariant.group !0
store i32 1, ptr %p
load i32, ptr %p, !invariant.group !0
```
undefined behavior.

I believe those semantics would be sufficient for current invariant.group based optimizations as well. I'm not sure if one of them is better than the other. I guess the advantage of this version is that only accesses with `!invariant.group` need to be checked by llubi.

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


More information about the llvm-commits mailing list