The _ExtInt type allows custom width integers, but the atomic memory access's operand must have a power-of-two size. _ExtInts with non-power-of-two size should not be allowed for atomic intrinsic.
Before this change:
$ cat test.c typedef unsigned _ExtInt(42) dtype; void verify_binary_op_nand(dtype* pval1, dtype val2) { __sync_nand_and_fetch(pval1, val2); } $ clang test.c clang-11: /home/ubuntu/llvm_workspace/llvm/clang/lib/CodeGen/CGBuiltin.cpp:117: llvm::Value* EmitToInt(clang::CodeGen::CodeGenFunction&, llvm::Value*, clang::QualType, llvm::IntegerType*): Assertion `V->getType() == IntType' failed. PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
After this change:
$ clang test.c test.c:3:30: error: Atomic memory operand must have a power-of-two size { __sync_nand_and_fetch(pval1, val2); } ^
List of the atomic intrinsics that have this problem:
- __sync_fetch_and_add
- __sync_fetch_and_sub
- __sync_fetch_and_or
- __sync_fetch_and_and
- __sync_fetch_and_xor
- __sync_fetch_and_nand
- __sync_nand_and_fetch
- __sync_and_and_fetch
- __sync_add_and_fetch
- __sync_sub_and_fetch
- __sync_or_and_fetch
- __sync_xor_and_fetch
- __sync_fetch_and_min
- __sync_fetch_and_max
- __sync_fetch_and_umin
- __sync_fetch_and_umax
- __sync_val_compare_and_swap
- __sync_bool_compare_and_swap
const auto *.