149 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_cc1 -O1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck -DLIKELY=2000 -DUNLIKELY=1 %s
 | 
						|
// RUN: %clang_cc1 -O1 -emit-llvm %s -triple=x86_64-linux-gnu -mllvm -likely-branch-weight=99 -mllvm -unlikely-branch-weight=42 -o - | FileCheck -DLIKELY=99 -DUNLIKELY=42 %s
 | 
						|
 | 
						|
extern volatile bool b;
 | 
						|
extern volatile int i;
 | 
						|
extern bool A();
 | 
						|
extern bool B();
 | 
						|
 | 
						|
bool f() {
 | 
						|
  // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1fv
 | 
						|
  // CHECK: br {{.*}} !prof !7
 | 
						|
  if (b)
 | 
						|
    [[likely]] {
 | 
						|
      return A();
 | 
						|
    }
 | 
						|
  return B();
 | 
						|
}
 | 
						|
 | 
						|
bool g() {
 | 
						|
  // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1gv
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] {
 | 
						|
      return A();
 | 
						|
    }
 | 
						|
 | 
						|
  return B();
 | 
						|
}
 | 
						|
 | 
						|
bool h() {
 | 
						|
  // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1hv
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] return A();
 | 
						|
 | 
						|
  return B();
 | 
						|
}
 | 
						|
 | 
						|
void NullStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}NullStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]];
 | 
						|
  else {
 | 
						|
    // Make sure the branches aren't optimized away.
 | 
						|
    b = true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void IfStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}IfStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] if (B()) {}
 | 
						|
 | 
						|
  // CHECK-NOT: br {{.*}} !prof
 | 
						|
  // CHECK: br {{.*}} !prof
 | 
						|
  if (b) {
 | 
						|
    if (B())
 | 
						|
      [[unlikely]] { b = false; }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void WhileStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}WhileStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] while (B()) {}
 | 
						|
 | 
						|
  // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
 | 
						|
  if (b)
 | 
						|
    // CHECK: br {{.*}} !prof !7
 | 
						|
    while (B())
 | 
						|
      [[unlikely]] { b = false; }
 | 
						|
}
 | 
						|
 | 
						|
void DoStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}DoStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] do {}
 | 
						|
    while (B())
 | 
						|
      ;
 | 
						|
 | 
						|
  // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
 | 
						|
  if (b)
 | 
						|
    do
 | 
						|
      [[unlikely]] {}
 | 
						|
    while (B());
 | 
						|
}
 | 
						|
 | 
						|
void ForStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}ForStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] for (; B();) {}
 | 
						|
 | 
						|
  // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
 | 
						|
  if (b)
 | 
						|
    // CHECK: br {{.*}} !prof !7
 | 
						|
    for (; B();)
 | 
						|
      [[unlikely]] {}
 | 
						|
}
 | 
						|
 | 
						|
void GotoStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}GotoStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] goto end;
 | 
						|
  else {
 | 
						|
    // Make sure the branches aren't optimized away.
 | 
						|
    b = true;
 | 
						|
  }
 | 
						|
end:;
 | 
						|
}
 | 
						|
 | 
						|
void ReturnStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}ReturnStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] return;
 | 
						|
  else {
 | 
						|
    // Make sure the branches aren't optimized away.
 | 
						|
    b = true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void SwitchStmt() {
 | 
						|
  // CHECK-LABEL: define{{.*}}SwitchStmt
 | 
						|
  // CHECK: br {{.*}} !prof !8
 | 
						|
  if (b)
 | 
						|
    [[unlikely]] switch (i) {}
 | 
						|
  else {
 | 
						|
    // Make sure the branches aren't optimized away.
 | 
						|
    b = true;
 | 
						|
  }
 | 
						|
  // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
 | 
						|
  if (b)
 | 
						|
    switch (i)
 | 
						|
      [[unlikely]] {}
 | 
						|
  else {
 | 
						|
    // Make sure the branches aren't optimized away.
 | 
						|
    b = true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// CHECK: !7 = !{!"branch_weights", i32 [[UNLIKELY]], i32 [[LIKELY]]}
 | 
						|
// CHECK: !8 = !{!"branch_weights", i32 [[LIKELY]], i32 [[UNLIKELY]]}
 |