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

Reply via email to