Enabling opaque pointers by default

As a few people have been asking about this recently, I’ve put up ⚙ D140487 [Docs] Clarify typed pointers support timeline to commit to a hard timeline for typed pointer support. The tl;dr is that independent of test migration state, LLVM 16 will retain best-effort support for typed pointers, and LLVM 17 will not support them as a matter of policy (immediately after branching, i.e. from Jan 24th).

Hi everyone!

I have question related to opaque pointers.
Can we get the contained type of an element of an array, when the element is just marked ptr? Shortly saying the underlying type of “ptr” element type of an array.

No, this is not possible (unless we’re talking about a special case, like a global array). If you provide some more context on what you’re trying to do, there’s likely some alternative way to achieve it though.

I have a scenario where I need to know type of an element of an array, and I wonder if there’s an alternative way to achieve it?

For [AArch64] Performance is now affected due to unaligned access · Issue #59912 · llvm/llvm-project · GitHub, we can find the following IR in LoopPeel pass, I wonder whether the first element a[0] in the kernel loop body of function callee is aligned 16-byte? However, as the data type is ‘ptr’, so it cannot be obtained.

define dso_local void @callee(ptr nocapture noundef writeonly %a, i32 noundef %n) local_unnamed_addr #0 {
  %cmp4 = icmp sgt i32 %n, 0
  br i1 %cmp4, label %for.body.preheader, label %for.cond.cleanup

for.body.preheader:                               ; preds = %entry
  %wide.trip.count = zext i32 %n to i64
br label %for.body

for.cond.cleanup.loopexit:                        ; preds = %for.body
  br label %for.cond.cleanup

for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit, %entry
  ret void

for.body: ; preds = %for.body.preheader, %for.body
%Warnings.IV = phi i64 [ 0% for.body.preheader ], [ %warning.iv.next, %for.body ]
%0 = trunc i64% iv two i32
%m = mulnw i32%0, 50
%arrayidx = getelptr in bounds i32, ptr %a, i64%invars.iv
large i32%mul, ptr%arrayidx, align 4!tbaa!6
%WARNING.IV.next = add nuw nsw i64%Warnings.iv, 1
  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count
  br i1 %exitcond, label %for.body, label %for.cond.cleanup.loopexit, !llvm.loop !10

@Allen Pointer element types have no relation to alignment. Alignment is determined either by annotations on the access, or through align attributes. LLVM provides helpers to determine the alignment, the most primitive one is getPointerAlignment(), and the most powerful is getOrEnforceKnownAlignment().

However, if I understand that issue correctly, the idea there is to insert a runtime check on the alignment, rather than make use of known alignment.

Yes, here need a runtime check.Thanks @nikic.

As another update, ⚙ D141912 [AsmParser] Remove typed pointer auto-detection removes auto-detection of typed pointers from the IR parser. This means that explicitly specifying -opaque-pointers=0 is now always necessary to prevent an opaque pointer auto-upgrade.

This is also your final reminder that, as a matter of policy, typed pointers will not be supported once the release/16.x branch has been created on Jan 24th.

As previously announced, typed pointers are no longer supported on the main branch: [Docs] Typed pointers are no longer supported · llvm/llvm-project@5f313c9 · GitHub

For now this is just a policy statement, but expect bits of typed pointer support code to start getting removed in the near future.

All remaining tests that rely on typed pointers are marked with either -no-opaque-pointers or -opaque-pointers=0. Help in migrating these (especially on the clang side), would be greatly appreciated.

1 Like


However, tests are still in the process of being converted to opaque pointers. As such, care must be taken when actively removing typed pointer support, to avoid breaking remaining tests.

Do you have a plan for removing typed pointer support? It doesn’t seem it can be automated.
E.g. mark PointerType::get(Type *EltTy, unsigned AddressSpace) as deprecated, insert an assert and fix places where it triggers, or …
I’d like to help, but it would be nice to see an example patch first.

We’re not yet at a point where core APIs like these can be removed (or deprecated – that requires removing all monorepo callers first).

There is still a substantial amount of remaining tests that use the -no-opaque-pointers or -opaque-pointers=0 options, and these need to be converted before we can remove anything substantial.

If you’d like to help with test migration, the general process is to run the migration script on some test(s), and then fix up the test failure (if you’re lucky by rerunning an update_test_checks script, but for clang tests usually manually).

If you’d like to help with test migration, the general process is to run the migration script on some test(s), and then fix up the test failure (if you’re lucky by rerunning an update_test_checks script, but for clang tests usually manually).

OK, I’ll try to address CodeGen/PowerPC tests.

1 Like

I’ve been able to convert most PPC tests to opaque pointers. The remaining three tests are large and converting them results in significant changes in the generated code. I’ll leave them to someone who is more familiar with the architecture.

@jdoerfert I’m wondering if there’s anyone who could help me get the clang/test/OpenMP tests updated. I’m having a really hard time with these, because they are CHECK-DAG matches on a subset of IR, and removing pointer types makes check lines match the wrong lines, so it’s not easy to update these without understanding what they’re testing.

I wonder whether it would be possible to migrate the OpenMP tests to update_cc_test_checks? Is the reason they don’t use it yet the weird SIMD-ONLY0 check prefix that is only used in SIMD-ONLY0-NOT?

I’ll deal with OpenMP/atomic_*.cpp (4 files)

Some feedback on the script.
It works great (produces the same results as if done by hand), but it misses patterns like
[4 x [[STRUCT_DESCRIPTOR]]]* – does not convert them to ptr.

We have finished migrating all the clang tests, and the -no-opaque-pointers cc1 option has been removed in ⚙ D152447 [Clang] Remove -no-opaque-pointers cc1 flag. Thanks @s-barannikov for helping with this!

Now we’re down to ~150 LLVM tests that still need migration.


Apologies, I didn’t see the ping. We already moved clang tests to update_cc in the past, I am happy to have them all use the script. Though, it seems you finished everything already. Thanks again for that!

As the next major milestone, https://reviews.llvm.org/D155079 removed the -opaque-pointers option, making it impossible to enable typed pointers in any way. This essentially completes the opaque pointers migration.

The only thing left to do now is to remove dead code related to typed pointer handling, and phase out various typed pointer compatibility APIs.


Note that with the removal of the -opaque-pointer option, many llvm/test/CodeGen/SPIRV/ tests fail if -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD contains SPIRV. Hmm, I cannot find a Discourse username for the regular contributors of SPIRV.

% rg -l opaque-pointer llvm/test/CodeGen/SPIRV/

Perhaps @jcranmer can help track them down?