Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Analysis] Attribute Range should not prevent tail call optimization #91122

Merged
merged 11 commits into from
May 8, 2024

Conversation

jsji
Copy link
Member

@jsji jsji commented May 5, 2024

  • Remove Range attr when comparing for tailcall
  • Add test for testcall with range

@jsji jsji self-assigned this May 5, 2024
@jsji jsji requested a review from davidbolvansky May 5, 2024 13:53
@llvmbot
Copy link
Collaborator

llvmbot commented May 5, 2024

@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-backend-x86

Author: Jinsong Ji (jsji)

Changes
  • Remove Range attr when comparing for tailcall
  • Add test for testcall with range

Full diff: https://github.com/llvm/llvm-project/pull/91122.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/Analysis.cpp (+4-3)
  • (added) llvm/test/CodeGen/X86/tailcall-range.ll (+23)
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index af7643d93591f7..e693cdbd0ccc1c 100644
--- a/llvm/lib/CodeGen/Analysis.cpp
+++ b/llvm/lib/CodeGen/Analysis.cpp
@@ -593,9 +593,10 @@ bool llvm::attributesPermitTailCall(const Function *F, const Instruction *I,
 
   // Following attributes are completely benign as far as calling convention
   // goes, they shouldn't affect whether the call is a tail call.
-  for (const auto &Attr : {Attribute::Alignment, Attribute::Dereferenceable,
-                           Attribute::DereferenceableOrNull, Attribute::NoAlias,
-                           Attribute::NonNull, Attribute::NoUndef}) {
+  for (const auto &Attr :
+       {Attribute::Alignment, Attribute::Dereferenceable,
+        Attribute::DereferenceableOrNull, Attribute::NoAlias,
+        Attribute::NonNull, Attribute::NoUndef, Attribute::Range}) {
     CallerAttrs.removeAttribute(Attr);
     CalleeAttrs.removeAttribute(Attr);
   }
diff --git a/llvm/test/CodeGen/X86/tailcall-range.ll b/llvm/test/CodeGen/X86/tailcall-range.ll
new file mode 100644
index 00000000000000..1f7712d2494326
--- /dev/null
+++ b/llvm/test/CodeGen/X86/tailcall-range.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -passes=ipsccp -S -mtriple=x86_64-linux < %s | llc -mtriple=x86_64-linux | FileCheck %s
+
+define i32 @foo(ptr %this, ...) {
+; CHECK-LABEL: foo:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movzbl 0, %eax
+; CHECK-NEXT:    retq
+entry:
+  %call = load volatile i1, ptr null, align 1
+  %spec.select = zext i1 %call to i32
+  ret i32 %spec.select
+}
+
+define i32 @bar(ptr %this, ...) {
+; CHECK-LABEL: bar:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    jmp foo@PLT # TAILCALL
+entry:
+  %4 = musttail call i32 (ptr, ...) @foo(ptr null, ...)
+  ret i32 %4
+}

@andjo403
Copy link
Contributor

andjo403 commented May 5, 2024

Do not know so mush about how this works (new contributor to llvm) but it sounds on the comment as this attribute also shall be in the list. There also is the same list of attributes in

for (const auto &Attr : {Attribute::Alignment, Attribute::Dereferenceable,
so think that it shall be fixed there also.

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label May 6, 2024
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code change looks fine, but the test should not be calling ipsccp. Adjust the input IR to have the range attribute instead.

@andjo403
Copy link
Contributor

andjo403 commented May 6, 2024

shall there not be a update of some test for the TargetLowering.cpp update now that it is added to this PR

@jsji
Copy link
Member Author

jsji commented May 7, 2024

shall there not be a update of some test for the TargetLowering.cpp update now that it is added to this PR

Remove the changes from this PR first for now. Will follow up with another PR once I get the test for it ready.

@nikic
Copy link
Contributor

nikic commented May 7, 2024

shall there not be a update of some test for the TargetLowering.cpp update now that it is added to this PR

Remove the changes from this PR first for now. Will follow up with another PR once I get the test for it ready.

I'd rather not have these two pieces of code go out of sync.

@jsji
Copy link
Member Author

jsji commented May 7, 2024

shall there not be a update of some test for the TargetLowering.cpp update now that it is added to this PR

Remove the changes from this PR first for now. Will follow up with another PR once I get the test for it ready.

I'd rather not have these two pieces of code go out of sync.

I am not able to come up with a reasonable testcase for now.

  1. Most of the tests that hit this logic are floating point libcalls.
  2. For some libcall returning int, adding range attr won't cause problem
declare range(i64 0, 2) i64 @llvm.llround.f32(float) nounwind readnone
define i64 @testmsxs(float %x) {
  entry:
    %0 = musttail call i64 @llvm.llround.f32(float %x)
      ret i64 %0
}

Let me know if you can find some testcase that shows problems .

@arsenm
Copy link
Contributor

arsenm commented May 7, 2024

declare range(i64 0, 2) i64 @llvm.llround.f32(float) nounwind readnone
define i64 @testmsxs(float %x) {
entry:
%0 = musttail call i64 @llvm.llround.f32(float %x)
ret i64 %0
}

I'm surprised we allow musttail on intrinsic calls, which aren't really supposed to have ABI

@jsji
Copy link
Member Author

jsji commented May 7, 2024

declare range(i64 0, 2) i64 @llvm.llround.f32(float) nounwind readnone
define i64 @testmsxs(float %x) {
entry:
%0 = musttail call i64 @llvm.llround.f32(float %x)
ret i64 %0
}

I'm surprised we allow musttail on intrinsic calls, which aren't really supposed to have ABI

#91347 Opened to track follow up. Thanks.

@jsji
Copy link
Member Author

jsji commented May 7, 2024

@nikic @andjo403 Please have a look again. Thanks.

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with some test nits

llvm/test/CodeGen/X86/tailcall-range.ll Outdated Show resolved Hide resolved
llvm/test/CodeGen/X86/tailcall-range.ll Outdated Show resolved Hide resolved
@andjo403
Copy link
Contributor

andjo403 commented May 7, 2024

hmm did a comment on the thread of comments on the test but had not noticed that it was marked as resolved do not know if it was removed
I suggested

declare i32 @callee()

define range(i32 0, 2) i32 @func_with_range_attr() {
  %1 = musttail call i32 @callee()
  ret i32 %1
}

define i32 @call_with_range_attr() {
  %1 = musttail call range(i32 0, 2) i32 @callee()
  ret i32 %1
}

@jsji jsji requested a review from andjo403 May 7, 2024 18:18
llvm/test/CodeGen/X86/tailcall-range.ll Outdated Show resolved Hide resolved
llvm/test/CodeGen/X86/tailcall-range.ll Outdated Show resolved Hide resolved
llvm/test/CodeGen/X86/tailcall-range.ll Outdated Show resolved Hide resolved
@jsji jsji requested a review from arsenm May 7, 2024 18:24
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

; CHECK-NEXT: movzbl 0, %eax
; CHECK-NEXT: retq
entry:
%call = load volatile i1, ptr null, align 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%call = load volatile i1, ptr null, align 1
%call = load volatile i1, ptr %this, align 1

was possibly intended here? Best to avoid "obviously UB" inputs when we can...

@jsji jsji merged commit 2dade00 into llvm:main May 8, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants