Author: Jan Górski Date: 2025-04-14T14:26:10-07:00 New Revision: ff687af04f5b0e85305250587b524cb0b3849aa0
URL: https://github.com/llvm/llvm-project/commit/ff687af04f5b0e85305250587b524cb0b3849aa0 DIFF: https://github.com/llvm/llvm-project/commit/ff687af04f5b0e85305250587b524cb0b3849aa0.diff LOG: [clang][CodeGen] Add range metadata for atomic load of boolean type. #131476 (#133546) Fixes #131476. For `x86_64` it folds ``` movzbl t1(%rip), %eax andb $1, %al ``` into ``` movzbl t1(%rip), %eax ``` when run: `clang -S atomic-ops-load.c -o atomic-ops-load.s -O1 --target=x86_64`. But for riscv replaces: ``` lb a0, %lo(t1)(a0) andi a0, a0, 1 ``` with ``` lb a0, %lo(t1)(a0) zext.b a0, a0 ``` when run: `clang -S atomic-ops-load.c -o atomic-ops-load.s -O1 --target=riscv64`. Added: clang/test/CodeGen/atomic-ops-load.c Modified: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CodeGenFunction.h Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 672e82f8dcc3e..0af3cd07b13a0 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -590,6 +590,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); Load->setAtomic(Order, Scope); Load->setVolatile(E->isVolatile()); + CGF.maybeAttachRangeForLoad(Load, E->getValueType(), E->getExprLoc()); CGF.Builder.CreateStore(Load, Dest); return; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5f028f6d8c6ac..3da21cebd9d68 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1919,6 +1919,20 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { return MDHelper.createRange(Min, End); } +void CodeGenFunction::maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, + SourceLocation Loc) { + if (EmitScalarRangeCheck(Load, Ty, Loc)) { + // In order to prevent the optimizer from throwing away the check, don't + // attach range metadata to the load. + } else if (CGM.getCodeGenOpts().OptimizationLevel > 0) { + if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) { + Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); + Load->setMetadata(llvm::LLVMContext::MD_noundef, + llvm::MDNode::get(CGM.getLLVMContext(), {})); + } + } +} + bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc) { bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool); @@ -2037,15 +2051,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); - if (EmitScalarRangeCheck(Load, Ty, Loc)) { - // In order to prevent the optimizer from throwing away the check, don't - // attach range metadata to the load. - } else if (CGM.getCodeGenOpts().OptimizationLevel > 0) - if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) { - Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); - Load->setMetadata(llvm::LLVMContext::MD_noundef, - llvm::MDNode::get(getLLVMContext(), {})); - } + maybeAttachRangeForLoad(Load, Ty, Loc); return EmitFromMemory(Load, Ty); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index cdddc69effb86..aa07e5d6c8099 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -5309,6 +5309,9 @@ class CodeGenFunction : public CodeGenTypeCache { unsigned NumElementsDst, const llvm::Twine &Name = ""); + void maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, + SourceLocation Loc); + private: // Emits a convergence_loop instruction for the given |BB|, with |ParentToken| // as it's parent convergence instr. diff --git a/clang/test/CodeGen/atomic-ops-load.c b/clang/test/CodeGen/atomic-ops-load.c new file mode 100644 index 0000000000000..778a7ebdc2618 --- /dev/null +++ b/clang/test/CodeGen/atomic-ops-load.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple riscv64 -O1 -emit-llvm %s -o - | FileCheck %s +#include <stdbool.h> + +extern bool t1; +bool test1(void) { +// CHECK-LABEL: define{{.*}} i1 @test1 +// CHECK: load atomic i8, ptr @t1 monotonic, align 1, !range ![[$WS_RANGE:[0-9]*]], !noundef !{{[0-9]+}} +// CHECK-NEXT: trunc nuw i8 %{{.*}} to i1 +// CHECK-NEXT: ret i1 %{{.*}} + return __atomic_load_n(&t1, __ATOMIC_RELAXED); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits