Skip to content

Commit ff687af

Browse files
authored
[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`.
1 parent 54b33eb commit ff687af

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

clang/lib/CodeGen/CGAtomic.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
590590
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr);
591591
Load->setAtomic(Order, Scope);
592592
Load->setVolatile(E->isVolatile());
593+
CGF.maybeAttachRangeForLoad(Load, E->getValueType(), E->getExprLoc());
593594
CGF.Builder.CreateStore(Load, Dest);
594595
return;
595596
}

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,20 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
19191919
return MDHelper.createRange(Min, End);
19201920
}
19211921

1922+
void CodeGenFunction::maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty,
1923+
SourceLocation Loc) {
1924+
if (EmitScalarRangeCheck(Load, Ty, Loc)) {
1925+
// In order to prevent the optimizer from throwing away the check, don't
1926+
// attach range metadata to the load.
1927+
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0) {
1928+
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
1929+
Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
1930+
Load->setMetadata(llvm::LLVMContext::MD_noundef,
1931+
llvm::MDNode::get(CGM.getLLVMContext(), {}));
1932+
}
1933+
}
1934+
}
1935+
19221936
bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
19231937
SourceLocation Loc) {
19241938
bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool);
@@ -2037,15 +2051,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
20372051

20382052
CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
20392053

2040-
if (EmitScalarRangeCheck(Load, Ty, Loc)) {
2041-
// In order to prevent the optimizer from throwing away the check, don't
2042-
// attach range metadata to the load.
2043-
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
2044-
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
2045-
Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
2046-
Load->setMetadata(llvm::LLVMContext::MD_noundef,
2047-
llvm::MDNode::get(getLLVMContext(), {}));
2048-
}
2054+
maybeAttachRangeForLoad(Load, Ty, Loc);
20492055

20502056
return EmitFromMemory(Load, Ty);
20512057
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5309,6 +5309,9 @@ class CodeGenFunction : public CodeGenTypeCache {
53095309
unsigned NumElementsDst,
53105310
const llvm::Twine &Name = "");
53115311

5312+
void maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty,
5313+
SourceLocation Loc);
5314+
53125315
private:
53135316
// Emits a convergence_loop instruction for the given |BB|, with |ParentToken|
53145317
// as it's parent convergence instr.

clang/test/CodeGen/atomic-ops-load.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -triple riscv64 -O1 -emit-llvm %s -o - | FileCheck %s
2+
#include <stdbool.h>
3+
4+
extern bool t1;
5+
bool test1(void) {
6+
// CHECK-LABEL: define{{.*}} i1 @test1
7+
// CHECK: load atomic i8, ptr @t1 monotonic, align 1, !range ![[$WS_RANGE:[0-9]*]], !noundef !{{[0-9]+}}
8+
// CHECK-NEXT: trunc nuw i8 %{{.*}} to i1
9+
// CHECK-NEXT: ret i1 %{{.*}}
10+
return __atomic_load_n(&t1, __ATOMIC_RELAXED);
11+
}

0 commit comments

Comments
 (0)