cxx-throws.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Test instrumentation of C++ exception handling constructs.
  2. // FIXME: Don't seek bb labels, like "if.else"
  3. // REQUIRES: asserts
  4. // RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -fexceptions -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN %s
  5. // RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -fexceptions -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN-EXC %s
  6. // RUN: llvm-profdata merge %S/Inputs/cxx-throws.proftext -o %t.profdata
  7. // RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%t.profdata -fcxx-exceptions -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s
  8. // RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%t.profdata -fcxx-exceptions -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s
  9. // PGOGEN: @[[THC:__llvm_profile_counters__Z6throwsv]] = private global [9 x i64] zeroinitializer
  10. // PGOGEN-EXC: @[[THC:__llvm_profile_counters__Z6throwsv]] = private global [9 x i64] zeroinitializer
  11. // PGOGEN: @[[UNC:__llvm_profile_counters__Z11unreachablei]] = private global [3 x i64] zeroinitializer
  12. // PGOGEN-LABEL: @_Z6throwsv()
  13. // PGOUSE-LABEL: @_Z6throwsv()
  14. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 0
  15. void throws() {
  16. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 1
  17. // PGOUSE: br {{.*}} !prof ![[TH1:[0-9]+]]
  18. for (int i = 0; i < 100; ++i) {
  19. try {
  20. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 3
  21. // PGOUSE: br {{.*}} !prof ![[TH2:[0-9]+]]
  22. if (i % 3) {
  23. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 4
  24. // PGOUSE: br {{.*}} !prof ![[TH3:[0-9]+]]
  25. if (i < 50)
  26. throw 1;
  27. } else {
  28. // The catch block may be emitted after the throw above, we can skip it
  29. // by looking for an else block, but this will break if anyone puts an
  30. // else in the catch
  31. // PGOUSE: if.else{{.*}}:
  32. // PGOGEN: if.else{{.*}}:
  33. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 5
  34. // PGOUSE: br {{.*}} !prof ![[TH4:[0-9]+]]
  35. if (i >= 50)
  36. throw 0;
  37. }
  38. } catch (int e) {
  39. // PGOUSE-EXC: catch{{.*}}:
  40. // PGOGEN-EXC: catch{{.*}}:
  41. // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 6
  42. // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 7
  43. // PGOUSE-EXC: br {{.*}} !prof ![[TH5:[0-9]+]]
  44. if (e) {}
  45. }
  46. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 2
  47. // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 8
  48. // PGOUSE: br {{.*}} !prof ![[TH6:[0-9]+]]
  49. if (i < 100) {}
  50. }
  51. // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
  52. // PGOUSE: ret void
  53. }
  54. // PGOGEN-LABEL: @_Z11unreachablei(i32
  55. // PGOUSE-LABEL: @_Z11unreachablei(i32
  56. // PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 0
  57. void unreachable(int i) {
  58. // PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 1
  59. // PGOUSE: br {{.*}} !prof ![[UN1:[0-9]+]]
  60. if (i)
  61. throw i;
  62. // PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 2
  63. // Since we never reach here, the weights should all be zero (and skipped)
  64. // PGOUSE-NOT: br {{.*}} !prof !{{.*}}
  65. if (i) {}
  66. }
  67. // PGOUSE-DAG: ![[TH1]] = !{!"branch_weights", i32 101, i32 2}
  68. // PGOUSE-DAG: ![[TH2]] = !{!"branch_weights", i32 67, i32 35}
  69. // PGOUSE-DAG: ![[TH3]] = !{!"branch_weights", i32 34, i32 34}
  70. // PGOUSE-DAG: ![[TH4]] = !{!"branch_weights", i32 18, i32 18}
  71. // PGOUSE-EXC: ![[TH5]] = !{!"branch_weights", i32 34, i32 18}
  72. // PGOUSE-DAG: ![[TH6]] = !{!"branch_weights", i32 101, i32 1}
  73. // PGOUSE-DAG: ![[UN1]] = !{!"branch_weights", i32 2, i32 1}
  74. int main(int argc, const char *argv[]) {
  75. throws();
  76. try {
  77. unreachable(1);
  78. } catch (int) {}
  79. return 0;
  80. }