This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Folding `(inttoptr (and (ptrtoint Ptr), Mask))` -> `@llvm.ptrmask(Ptr, Mask)`
AbandonedPublic

Authored by goldstein.w.n on Jun 28 2023, 2:17 PM.

Details

Reviewers
nikic
RKSimon
Summary

This works if Ptr has noundef: https://alive2.llvm.org/ce/z/S6yEwr

Alive2 does not support @llvm.ptrmask, but @llvm.ptrmask is
documented as equivilent to:
(getelementptr i8 Ptr, (sub (and (ptrtoint Ptr), Mask), (ptrtoint Ptr)))

See: https://llvm.org/docs/LangRef.html#llvm-ptrmask-intrinsic

Alive2 also doesn't handle inttoptr, so the proof compares:

define i64 @src_ptrtoint(ptr noundef %p, i64 %m) {
  %pi = ptrtoint ptr %p to i64
  %pi_masked = and i64 %pi, %m
  ret i64 %pi_masked
}

define i64 @tgt_ptrtoint(ptr noundef %p, i64 %m) {
  %pi = ptrtoint ptr %p to i64
  %pi_m = and i64 %pi, %m
  %pi_off = sub i64 %pi_m, %pi
  %pm = getelementptr i8, ptr %p, i64 %pi_off
  %pi_masked = ptrtoint ptr %pm to i64
  ret i64 %pi_masked
}

Which verifies

Diff Detail

Event Timeline

goldstein.w.n created this revision.Jun 28 2023, 2:17 PM
goldstein.w.n requested review of this revision.Jun 28 2023, 2:17 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 28 2023, 2:17 PM
nikic requested changes to this revision.Jun 28 2023, 2:26 PM

This is not legal -- the fact that this is not legal is pretty much the whole reason why the ptrmask intrinsic exists in the first place. ptrmask preserves the provenance of the base object, while the ptrtoint/inttoptr sequence does not. The result of the inttoptr can have different provenance than the ptrtoint operand.

This revision now requires changes to proceed.Jun 28 2023, 2:26 PM

This is not legal -- the fact that this is not legal is pretty much the whole reason why the ptrmask intrinsic exists in the first place. ptrmask preserves the provenance of the base object, while the ptrtoint/inttoptr sequence does not. The result of the inttoptr can have different provenance than the ptrtoint operand.

IC. Okay will abandon (likewise the rest of the series). Is there any way to get @llvm.ptrmask to generate in C code? Was having trouble doing that hence this patch.

nikic added a comment.Jun 28 2023, 2:45 PM

This is not legal -- the fact that this is not legal is pretty much the whole reason why the ptrmask intrinsic exists in the first place. ptrmask preserves the provenance of the base object, while the ptrtoint/inttoptr sequence does not. The result of the inttoptr can have different provenance than the ptrtoint operand.

IC. Okay will abandon (likewise the rest of the series). Is there any way to get @llvm.ptrmask to generate in C code? Was having trouble doing that hence this patch.

__builtin_align_down() ought to generate it, but doesn't due to insufficient optimization support for ptrmask, see https://github.com/llvm/llvm-project/blob/75a1797044fc049438bdfd1edaf16afa90fcfe24/clang/lib/CodeGen/CGBuiltin.cpp#L19174.

Apart from that, I believe it's only used for some vaargs lowering code.