LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 50270 - [Inliner] noalias metadata incorrectly propagated to caller instructions
Summary: [Inliner] noalias metadata incorrectly propagated to caller instructions
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Interprocedural Optimizations (show other bugs)
Version: trunk
Hardware: PC Linux
: P enhancement
Assignee: Jeroen Dobbelaere
URL:
Keywords:
Depends on:
Blocks: release-12.0.1
  Show dependency tree
 
Reported: 2021-05-08 02:53 PDT by Nikita Popov
Modified: 2021-05-15 05:56 PDT (History)
8 users (show)

See Also:
Fixed By Commit(s): aa9b02ac75350a6c7c949dd24d5c6a931be26ff9 4eb7b15cb447


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nikita Popov 2021-05-08 02:53:51 PDT
declare { i64 } @opaque_callee()
 
define { i64 } @callee(i64 %x) {
  %res = insertvalue { i64 } undef, i64 %x, 0 
  ret { i64 } %res 
} 
 
define i64 @caller(i64* %p) {
  %s = call { i64 } @opaque_callee() 
  %x = extractvalue { i64 } %s, 0 
  call { i64 } @callee(i64 %x), !noalias !2 
  %y = load i64, i64* %p, !alias.scope !2 
  ret i64 %y 
} 
 
!0 = !{!0, !"domain"}
!1 = !{!1, !0, !"scope"}
!2 = !{!1} 

; RUN: opt -S -inline < %s

declare { i64 } @opaque_callee()

define { i64 } @callee(i64 %x) {
  %res = insertvalue { i64 } undef, i64 %x, 0
  ret { i64 } %res
}

define i64 @caller(i64* %p) {
  %s = call { i64 } @opaque_callee(), !noalias !0
  %x = extractvalue { i64 } %s, 0
  %y = load i64, i64* %p, align 4, !alias.scope !0
  ret i64 %y
}

!0 = !{!1}
!1 = distinct !{!1, !2, !"scope"}
!2 = distinct !{!2, !"domain"}

The !noalias metadata on the @callee() call is propagated to the @opaque_callee() call from the caller.

This happens because VMap may map to instructions from the caller if simplification occurred. The existing check in https://github.com/llvm/llvm-project/blob/d4bdeca5765ac2e81e217a5fa873d1ffbf0e95b0/llvm/lib/Transforms/Utils/InlineFunction.cpp#L796-L799 protects against a similar problem, but does not cover this case.

I believe the same basic problem also applies to a few other VMap walks inside the inliner.

This was originally reported at https://github.com/rust-lang/rust/issues/84958.
Comment 1 Nikita Popov 2021-05-08 06:55:46 PDT
I believe this shows the same issue during metadata remapping:

declare { i64* } @opaque_callee()

define { i64* } @self_caller(i1 %c, i64* %a) {
  br i1 %c, label %if, label %else

if:
  %s = call { i64* } @opaque_callee(), !noalias !2
  %x = extractvalue { i64* } %s, 0
  %r = call { i64* } @self_caller(i1 false, i64* %x)
  ret { i64* } %r

else:
  %r2 = insertvalue { i64* } undef, i64* %a, 0
  load volatile i64, i64* %a, !alias.scope !2
  ret { i64* } %r2
}

!0 = !{!0, !"domain"}
!1 = !{!1, !0, !"scope"}
!2 = !{!1}

opt -inline results in:

declare { i64* } @opaque_callee()

define { i64* } @self_caller(i1 %c, i64* %a) {
  br i1 %c, label %if, label %else

if:                                               ; preds = %0
  %s = call { i64* } @opaque_callee(), !noalias !0
  %x = extractvalue { i64* } %s, 0
  %1 = load volatile i64, i64* %x, align 4, !alias.scope !0
  ret { i64* } %s

else:                                             ; preds = %0
  %r2 = insertvalue { i64* } undef, i64* %a, 0
  %2 = load volatile i64, i64* %a, align 4, !alias.scope !3
  ret { i64* } %r2
}

!0 = !{!1}
!1 = distinct !{!1, !2, !"scope"}
!2 = distinct !{!2, !"domain"}
!3 = !{!4}
!4 = distinct !{!4, !5, !"scope"}
!5 = distinct !{!5, !"domain"}

@opaque_callee() here should have retained metadata !3, rather than being assigned !0.

This case is a bit trickier to produce, because we only remap metadata that is used in the callee, so this only happens if the caller and the callee are the same (or share metadata, but I think that's rather ill-defined).
Comment 2 Nikita Popov 2021-05-08 09:28:37 PDT
Candidate patch: https://reviews.llvm.org/D102110
Comment 3 Nikita Popov 2021-05-10 13:06:05 PDT
Fixed by https://github.com/llvm/llvm-project/commit/aa9b02ac75350a6c7c949dd24d5c6a931be26ff9 on main. Keeping this issue open to track 12.0.1 backport.
Comment 4 Tom Stellard 2021-05-10 14:18:28 PDT
Hi Jeroen,

What is your opinion on backporting this?

https://reviews.llvm.org/rGaa9b02ac75350a6c7c949dd24d5c6a931be26ff9
Comment 5 Luke 2021-05-11 08:18:12 PDT Comment hidden (obsolete)
Comment 6 Jeroen Dobbelaere 2021-05-11 09:32:43 PDT
(In reply to Tom Stellard from comment #4)
> Hi Jeroen,
> 
> What is your opinion on backporting this?
> 
> https://reviews.llvm.org/rGaa9b02ac75350a6c7c949dd24d5c6a931be26ff9

Hi Tom,

I do think we should backport this.
I just tried out the cherry-pick and it applies without any problem. The build and tests also went fine.
Comment 7 Tom Stellard 2021-05-11 20:56:52 PDT
Merged: 4eb7b15cb447