ZhangKang created this revision.
ZhangKang added reviewers: PowerPC, nemanjai, ahatanak, vitalybuka, dblaikie.
ZhangKang added a project: LLVM.
Herald added subscribers: Sanitizers, cfe-commits, steven.zhang, wuzish, 
dexonsmith, kristof.beyls.
Herald added projects: clang, Sanitizers.
ZhangKang requested review of this revision.

In some backend like ARM, PowerPC, TRAP instrcution is as a terminator. 
But in clang, we didn't as __builtin_trap() and  __builtin_debugtrap()  as 
terminator.
This bug has caused 6 lit cases error on PPC.

For below case,

  void test_builtin_trap() {
    volatile int i = 0;
    __builtin_trap();
    volatile int j = i;
  }

we use `clang sim.c -target powerpc-unknown-unknown  -c` to build it, we will 
get below error:

  *** Bad machine code: Non-terminator instruction after the first terminator 
***
  - function:    test_builtin_trap
  - basic block: %bb.0 entry (0x1002c61f1f8)
  - instruction: %1:gprc = LWZ 0, %stack.0.i :: (volatile dereferenceable load 
4 from %ir.i)
  First terminator was: TRAP
  
  *** Bad machine code: Non-terminator instruction after the first terminator 
***
  - function:    test_builtin_trap
  - basic block: %bb.0 entry (0x1002c61f1f8)
  - instruction: STW killed %1:gprc, 0, %stack.1.j :: (volatile store 4 into 
%ir.j)
  First terminator was: TRAP
  fatal error: error in backend: Found 2 machine code errors.

This patch is to fix above bug.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85599

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/builtins-ppc.c
  compiler-rt/test/profile/gcov-__gcov_flush-terminate.c


Index: compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
===================================================================
--- compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -19,6 +19,6 @@
   __gcov_reset();                  // CHECK-NEXT: 1: [[#@LINE]]:
   i = 42;                          // CHECK-NEXT: 1: [[#@LINE]]:
   __builtin_trap();                // CHECK-NEXT: 1: [[#@LINE]]:
-  i = 84;                          // CHECK-NEXT: 1: [[#@LINE]]:
-  return 0;                        // CHECK-NEXT: 1: [[#@LINE]]:
+  i = 84;                          // CHECK-NEXT: -: [[#@LINE]]:
+  return 0;                        // CHECK-NEXT: -: [[#@LINE]]:
 }
Index: clang/test/CodeGen/builtins-ppc.c
===================================================================
--- clang/test/CodeGen/builtins-ppc.c
+++ clang/test/CodeGen/builtins-ppc.c
@@ -27,3 +27,23 @@
   // CHECK: call double @llvm.ppc.setrnd(i32 %2)
   res = __builtin_setrnd(x);
 }
+
+void test_builtin_trap() {
+  volatile int i = 0;
+  __builtin_trap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_trap
+  // CHECK: call void @llvm.trap()
+  // CHECK: unreachable
+}
+
+void test_builtin_debugtrap() {
+  volatile int i = 0;
+  __builtin_debugtrap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_debugtrap
+  // CHECK: call void @llvm.debugtrap()
+  // CHECK: unreachable
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -2351,8 +2351,24 @@
     Function *F = CGM.getIntrinsic(Intrinsic::clear_cache);
     return RValue::get(Builder.CreateCall(F, {Begin, End}));
   }
-  case Builtin::BI__builtin_trap:
-    return RValue::get(EmitTrapCall(Intrinsic::trap));
+  case Builtin::BI__builtin_trap: {
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::trap));
+    Builder.CreateUnreachable();
+
+    // We do need to preserve an insertion point.
+    EmitBlock(createBasicBlock("trap.cont"));
+
+    return RValue::get(nullptr);
+  }
+  case Builtin::BI__builtin_debugtrap: {
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::debugtrap));
+    Builder.CreateUnreachable();
+
+    // We do need to preserve an insertion point.
+    EmitBlock(createBasicBlock("debugtrap.cont"));
+
+    return RValue::get(nullptr);
+  }
   case Builtin::BI__debugbreak:
     return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
   case Builtin::BI__builtin_unreachable: {


Index: compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
===================================================================
--- compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -19,6 +19,6 @@
   __gcov_reset();                  // CHECK-NEXT: 1: [[#@LINE]]:
   i = 42;                          // CHECK-NEXT: 1: [[#@LINE]]:
   __builtin_trap();                // CHECK-NEXT: 1: [[#@LINE]]:
-  i = 84;                          // CHECK-NEXT: 1: [[#@LINE]]:
-  return 0;                        // CHECK-NEXT: 1: [[#@LINE]]:
+  i = 84;                          // CHECK-NEXT: -: [[#@LINE]]:
+  return 0;                        // CHECK-NEXT: -: [[#@LINE]]:
 }
Index: clang/test/CodeGen/builtins-ppc.c
===================================================================
--- clang/test/CodeGen/builtins-ppc.c
+++ clang/test/CodeGen/builtins-ppc.c
@@ -27,3 +27,23 @@
   // CHECK: call double @llvm.ppc.setrnd(i32 %2)
   res = __builtin_setrnd(x);
 }
+
+void test_builtin_trap() {
+  volatile int i = 0;
+  __builtin_trap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_trap
+  // CHECK: call void @llvm.trap()
+  // CHECK: unreachable
+}
+
+void test_builtin_debugtrap() {
+  volatile int i = 0;
+  __builtin_debugtrap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_debugtrap
+  // CHECK: call void @llvm.debugtrap()
+  // CHECK: unreachable
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -2351,8 +2351,24 @@
     Function *F = CGM.getIntrinsic(Intrinsic::clear_cache);
     return RValue::get(Builder.CreateCall(F, {Begin, End}));
   }
-  case Builtin::BI__builtin_trap:
-    return RValue::get(EmitTrapCall(Intrinsic::trap));
+  case Builtin::BI__builtin_trap: {
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::trap));
+    Builder.CreateUnreachable();
+
+    // We do need to preserve an insertion point.
+    EmitBlock(createBasicBlock("trap.cont"));
+
+    return RValue::get(nullptr);
+  }
+  case Builtin::BI__builtin_debugtrap: {
+    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::debugtrap));
+    Builder.CreateUnreachable();
+
+    // We do need to preserve an insertion point.
+    EmitBlock(createBasicBlock("debugtrap.cont"));
+
+    return RValue::get(nullptr);
+  }
   case Builtin::BI__debugbreak:
     return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
   case Builtin::BI__builtin_unreachable: {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to