Skip to content

[SelectionDAG][X86] Handle llvm.type.test in DAGBuilder #142939

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

abhishek-kaushik22
Copy link
Contributor

Closes #142937

@llvmbot llvmbot added backend:X86 llvm:SelectionDAG SelectionDAGISel as well labels Jun 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-backend-x86

Author: Abhishek Kaushik (abhishek-kaushik22)

Changes

Closes #142937


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

2 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+16)
  • (added) llvm/test/CodeGen/X86/pr142937.ll (+62)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2460c864b0815..6bb8368252537 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7384,6 +7384,22 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     setValue(&I, getValue(I.getOperand(0)));
     return;
 
+  case Intrinsic::type_test:
+  case Intrinsic::public_type_test: {
+    bool AllUsersAreAssume = llvm::all_of(I.users(), [](const User *U) {
+      if (const auto *call = dyn_cast<CallInst>(U)) {
+        return call->getIntrinsicID() == Intrinsic::assume;
+      }
+      return false;
+    });
+
+    if (AllUsersAreAssume)
+      setValue(&I, DAG.getUNDEF(MVT::i1));
+    else
+      setValue(&I, DAG.getConstant(1, sdl, MVT::i1));
+    return;
+  }
+
   case Intrinsic::assume:
   case Intrinsic::experimental_noalias_scope_decl:
   case Intrinsic::var_annotation:
diff --git a/llvm/test/CodeGen/X86/pr142937.ll b/llvm/test/CodeGen/X86/pr142937.ll
new file mode 100644
index 0000000000000..269433d86ba7d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr142937.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=i686-- -opt-bisect-limit=0   | FileCheck %s --check-prefix=X86
+; RUN: llc < %s -mtriple=x86_64-- -opt-bisect-limit=0 | FileCheck %s --check-prefix=X64
+
+define void @public_type_test() {
+; X86-LABEL: public_type_test:
+; X86:       # %bb.0: # %bb
+; X86-NEXT:  # %bb.1: # %bb1
+; X86-NEXT:    retl
+;
+; X64-LABEL: public_type_test:
+; X64:       # %bb.0: # %bb
+; X64-NEXT:  # %bb.1: # %bb1
+; X64-NEXT:    retq
+bb:
+  %call = call i1 @llvm.public.type.test(ptr null, metadata !"typeinfo")
+  br label %bb1
+
+bb1:
+  call void @llvm.assume(i1 %call)
+  ret void
+}
+
+define void @type_test() {
+; X86-LABEL: type_test:
+; X86:       # %bb.0: # %bb
+; X86-NEXT:    movb $1, %al
+; X86-NEXT:    testb $1, %al
+; X86-NEXT:    jne .LBB1_2
+; X86-NEXT:  # %bb.1: # %bb1
+; X86-NEXT:    ud1l 2(%eax), %eax
+; X86-NEXT:  .LBB1_2: # %bb2
+; X86-NEXT:    retl
+;
+; X64-LABEL: type_test:
+; X64:       # %bb.0: # %bb
+; X64-NEXT:    movb $1, %al
+; X64-NEXT:    testb $1, %al
+; X64-NEXT:    jne .LBB1_2
+; X64-NEXT:  # %bb.1: # %bb1
+; X64-NEXT:    ud1l 2(%eax), %eax
+; X64-NEXT:  .LBB1_2: # %bb2
+; X64-NEXT:    retq
+bb:
+  %call = tail call i1 @llvm.type.test(ptr null, metadata !"typeinfo")
+  br i1 %call, label %bb2, label %bb1
+
+bb1:
+  tail call void @llvm.ubsantrap(i8 2)
+  unreachable
+
+bb2:
+  ret void
+}
+
+declare i1 @llvm.public.type.test(ptr, metadata)
+
+declare void @llvm.assume(i1 noundef)
+
+declare i1 @llvm.type.test(ptr, metadata)
+
+declare void @llvm.ubsantrap(i8 immarg)

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-llvm-selectiondag

Author: Abhishek Kaushik (abhishek-kaushik22)

Changes

Closes #142937


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

2 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+16)
  • (added) llvm/test/CodeGen/X86/pr142937.ll (+62)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2460c864b0815..6bb8368252537 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7384,6 +7384,22 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     setValue(&I, getValue(I.getOperand(0)));
     return;
 
+  case Intrinsic::type_test:
+  case Intrinsic::public_type_test: {
+    bool AllUsersAreAssume = llvm::all_of(I.users(), [](const User *U) {
+      if (const auto *call = dyn_cast<CallInst>(U)) {
+        return call->getIntrinsicID() == Intrinsic::assume;
+      }
+      return false;
+    });
+
+    if (AllUsersAreAssume)
+      setValue(&I, DAG.getUNDEF(MVT::i1));
+    else
+      setValue(&I, DAG.getConstant(1, sdl, MVT::i1));
+    return;
+  }
+
   case Intrinsic::assume:
   case Intrinsic::experimental_noalias_scope_decl:
   case Intrinsic::var_annotation:
diff --git a/llvm/test/CodeGen/X86/pr142937.ll b/llvm/test/CodeGen/X86/pr142937.ll
new file mode 100644
index 0000000000000..269433d86ba7d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr142937.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=i686-- -opt-bisect-limit=0   | FileCheck %s --check-prefix=X86
+; RUN: llc < %s -mtriple=x86_64-- -opt-bisect-limit=0 | FileCheck %s --check-prefix=X64
+
+define void @public_type_test() {
+; X86-LABEL: public_type_test:
+; X86:       # %bb.0: # %bb
+; X86-NEXT:  # %bb.1: # %bb1
+; X86-NEXT:    retl
+;
+; X64-LABEL: public_type_test:
+; X64:       # %bb.0: # %bb
+; X64-NEXT:  # %bb.1: # %bb1
+; X64-NEXT:    retq
+bb:
+  %call = call i1 @llvm.public.type.test(ptr null, metadata !"typeinfo")
+  br label %bb1
+
+bb1:
+  call void @llvm.assume(i1 %call)
+  ret void
+}
+
+define void @type_test() {
+; X86-LABEL: type_test:
+; X86:       # %bb.0: # %bb
+; X86-NEXT:    movb $1, %al
+; X86-NEXT:    testb $1, %al
+; X86-NEXT:    jne .LBB1_2
+; X86-NEXT:  # %bb.1: # %bb1
+; X86-NEXT:    ud1l 2(%eax), %eax
+; X86-NEXT:  .LBB1_2: # %bb2
+; X86-NEXT:    retl
+;
+; X64-LABEL: type_test:
+; X64:       # %bb.0: # %bb
+; X64-NEXT:    movb $1, %al
+; X64-NEXT:    testb $1, %al
+; X64-NEXT:    jne .LBB1_2
+; X64-NEXT:  # %bb.1: # %bb1
+; X64-NEXT:    ud1l 2(%eax), %eax
+; X64-NEXT:  .LBB1_2: # %bb2
+; X64-NEXT:    retq
+bb:
+  %call = tail call i1 @llvm.type.test(ptr null, metadata !"typeinfo")
+  br i1 %call, label %bb2, label %bb1
+
+bb1:
+  tail call void @llvm.ubsantrap(i8 2)
+  unreachable
+
+bb2:
+  ret void
+}
+
+declare i1 @llvm.public.type.test(ptr, metadata)
+
+declare void @llvm.assume(i1 noundef)
+
+declare i1 @llvm.type.test(ptr, metadata)
+
+declare void @llvm.ubsantrap(i8 immarg)

Comment on lines 2 to 3
; RUN: llc < %s -mtriple=i686-- -opt-bisect-limit=0 | FileCheck %s --check-prefix=X86
; RUN: llc < %s -mtriple=x86_64-- -opt-bisect-limit=0 | FileCheck %s --check-prefix=X64
Copy link
Contributor

Choose a reason for hiding this comment

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

Do not use -opt-bisect-limit in tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use -O0 instead

Comment on lines 7390 to 7399
if (const auto *call = dyn_cast<CallInst>(U)) {
return call->getIntrinsicID() == Intrinsic::assume;
}
return false;
});

if (AllUsersAreAssume)
setValue(&I, DAG.getUNDEF(MVT::i1));
else
setValue(&I, DAG.getConstant(1, sdl, MVT::i1));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need to specifically look at the uses? Why can't you just unconditionally lower it to undef?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wouldn't there be a problem when the value is used in branches?

%call = tail call i1 @llvm.type.test(ptr null, metadata !"typeinfo")
br i1 %call, label %bb2, label %bb1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed it to always have a true value, so that we don't have false alarms when bisecting.

Copy link
Contributor

@e-kud e-kud left a comment

Choose a reason for hiding this comment

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

LGTM

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.

[SelectionDAG][X86] Compiler crash when using -opt-bisect-limit=0 because of llvm.type.test intrinsic
4 participants