jyknight created this revision. jyknight added a reviewer: rsmith. Herald added subscribers: cfe-commits, jfb, kristof.beyls. Herald added a project: clang.
It is specified to return a bool in GCC's documentation and implementation, but the clang builtin says it returns an int. This would be pretty much harmless, if it was just the builtin. However, when clang translates the builtin into a libcall, it _also_ generates the libcall with an int return type, while the actual library function in libatomic returns a bool. This mismatch in return types results in an actual ABI mismatch and thus incorrect results (interpreting false return value as true) on at least x86_64. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D67573 Files: clang/include/clang/Basic/Builtins.def clang/test/CodeGen/atomic-ops.c clang/test/CodeGen/big-atomic-ops.c Index: clang/test/CodeGen/big-atomic-ops.c =================================================================== --- clang/test/CodeGen/big-atomic-ops.c +++ clang/test/CodeGen/big-atomic-ops.c @@ -198,20 +198,20 @@ int lock_free(struct Incomplete *incomplete) { // CHECK: @lock_free - // CHECK: call i32 @__atomic_is_lock_free(i64 3, i8* null) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 3, i8* null) __c11_atomic_is_lock_free(3); - // CHECK: call i32 @__atomic_is_lock_free(i64 16, i8* {{.*}}@sixteen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 16, i8* {{.*}}@sixteen{{.*}}) __atomic_is_lock_free(16, &sixteen); - // CHECK: call i32 @__atomic_is_lock_free(i64 17, i8* {{.*}}@seventeen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 17, i8* {{.*}}@seventeen{{.*}}) __atomic_is_lock_free(17, &seventeen); - // CHECK: call i32 @__atomic_is_lock_free(i64 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 4, {{.*}}) __atomic_is_lock_free(4, incomplete); char cs[20]; - // CHECK: call i32 @__atomic_is_lock_free(i64 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 4, {{.*}}) __atomic_is_lock_free(4, cs+1); // CHECK-NOT: call Index: clang/test/CodeGen/atomic-ops.c =================================================================== --- clang/test/CodeGen/atomic-ops.c +++ clang/test/CodeGen/atomic-ops.c @@ -343,20 +343,20 @@ int lock_free(struct Incomplete *incomplete) { // CHECK-LABEL: @lock_free - // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 3, i8* null) __c11_atomic_is_lock_free(3); - // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) __atomic_is_lock_free(16, &sixteen); - // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) __atomic_is_lock_free(17, &seventeen); - // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 4, {{.*}}) __atomic_is_lock_free(4, incomplete); char cs[20]; - // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 4, {{.*}}) __atomic_is_lock_free(4, cs+1); // CHECK-NOT: call Index: clang/include/clang/Basic/Builtins.def =================================================================== --- clang/include/clang/Basic/Builtins.def +++ clang/include/clang/Basic/Builtins.def @@ -720,7 +720,7 @@ ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t") BUILTIN(__c11_atomic_thread_fence, "vi", "n") BUILTIN(__c11_atomic_signal_fence, "vi", "n") -BUILTIN(__c11_atomic_is_lock_free, "iz", "n") +BUILTIN(__c11_atomic_is_lock_free, "bz", "n") // GNU atomic builtins. ATOMIC_BUILTIN(__atomic_load, "v.", "t") @@ -748,7 +748,7 @@ BUILTIN(__atomic_thread_fence, "vi", "n") BUILTIN(__atomic_signal_fence, "vi", "n") BUILTIN(__atomic_always_lock_free, "izvCD*", "n") -BUILTIN(__atomic_is_lock_free, "izvCD*", "n") +BUILTIN(__atomic_is_lock_free, "bzvCD*", "n") // OpenCL 2.0 atomic builtins. ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
Index: clang/test/CodeGen/big-atomic-ops.c =================================================================== --- clang/test/CodeGen/big-atomic-ops.c +++ clang/test/CodeGen/big-atomic-ops.c @@ -198,20 +198,20 @@ int lock_free(struct Incomplete *incomplete) { // CHECK: @lock_free - // CHECK: call i32 @__atomic_is_lock_free(i64 3, i8* null) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 3, i8* null) __c11_atomic_is_lock_free(3); - // CHECK: call i32 @__atomic_is_lock_free(i64 16, i8* {{.*}}@sixteen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 16, i8* {{.*}}@sixteen{{.*}}) __atomic_is_lock_free(16, &sixteen); - // CHECK: call i32 @__atomic_is_lock_free(i64 17, i8* {{.*}}@seventeen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 17, i8* {{.*}}@seventeen{{.*}}) __atomic_is_lock_free(17, &seventeen); - // CHECK: call i32 @__atomic_is_lock_free(i64 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 4, {{.*}}) __atomic_is_lock_free(4, incomplete); char cs[20]; - // CHECK: call i32 @__atomic_is_lock_free(i64 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 4, {{.*}}) __atomic_is_lock_free(4, cs+1); // CHECK-NOT: call Index: clang/test/CodeGen/atomic-ops.c =================================================================== --- clang/test/CodeGen/atomic-ops.c +++ clang/test/CodeGen/atomic-ops.c @@ -343,20 +343,20 @@ int lock_free(struct Incomplete *incomplete) { // CHECK-LABEL: @lock_free - // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 3, i8* null) __c11_atomic_is_lock_free(3); - // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) __atomic_is_lock_free(16, &sixteen); - // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) __atomic_is_lock_free(17, &seventeen); - // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 4, {{.*}}) __atomic_is_lock_free(4, incomplete); char cs[20]; - // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + // CHECK: call zeroext i1 @__atomic_is_lock_free(i32 4, {{.*}}) __atomic_is_lock_free(4, cs+1); // CHECK-NOT: call Index: clang/include/clang/Basic/Builtins.def =================================================================== --- clang/include/clang/Basic/Builtins.def +++ clang/include/clang/Basic/Builtins.def @@ -720,7 +720,7 @@ ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t") BUILTIN(__c11_atomic_thread_fence, "vi", "n") BUILTIN(__c11_atomic_signal_fence, "vi", "n") -BUILTIN(__c11_atomic_is_lock_free, "iz", "n") +BUILTIN(__c11_atomic_is_lock_free, "bz", "n") // GNU atomic builtins. ATOMIC_BUILTIN(__atomic_load, "v.", "t") @@ -748,7 +748,7 @@ BUILTIN(__atomic_thread_fence, "vi", "n") BUILTIN(__atomic_signal_fence, "vi", "n") BUILTIN(__atomic_always_lock_free, "izvCD*", "n") -BUILTIN(__atomic_is_lock_free, "izvCD*", "n") +BUILTIN(__atomic_is_lock_free, "bzvCD*", "n") // OpenCL 2.0 atomic builtins. ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits