[clang] [llvm] [AArch64][clang][llvm] Add ACLE `stshh` atomic store builtin (PR #181386)

Kerry McLaughlin via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 3 03:04:32 PST 2026


================
@@ -5274,6 +5274,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(F, Args);
   }
 
+  if (BuiltinID == clang::AArch64::BI__builtin_arm_atomic_store_with_stshh) {
+    Value *StoreAddr = EmitScalarExpr(E->getArg(0));
+    Value *StoreValue = EmitScalarExpr(E->getArg(1));
+    Value *Order = EmitScalarExpr(E->getArg(2));
+    Value *Policy = EmitScalarExpr(E->getArg(3));
+
+    auto *OrderC = cast<llvm::ConstantInt>(Order);
+    auto *PolicyC = cast<llvm::ConstantInt>(Policy);
+
+    // Compute pointee bit-width from arg0 and create as i32 constant
+    QualType ValQT =
+        E->getArg(0)->getType()->castAs<PointerType>()->getPointeeType();
+    unsigned SizeBits = getContext().getTypeSize(ValQT);
+    auto *SizeC = llvm::ConstantInt::get(Int32Ty, SizeBits);
+
+    const bool IsSignedValType = ValQT->isSignedIntegerType();
+    Value *StoreValue64 =
+        Builder.CreateIntCast(StoreValue, Int64Ty, IsSignedValType);
+
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_stshh_atomic_store,
+                                   {StoreAddr->getType()});
+
+    // Intrinsic imm args are i32 regardless of source integer width
+    auto *OrderI32 = llvm::ConstantInt::get(Int32Ty, OrderC->getZExtValue());
+    auto *PolicyI32 = llvm::ConstantInt::get(Int32Ty, PolicyC->getZExtValue());
+
+    // Emit a single intrinsic so backend can expand to STSHH followed by
+    // atomic store, to guarantee STSHH immediately precedes STR insn
+    return Builder.CreateCall(
+        F, {StoreAddr, StoreValue64, OrderI32, PolicyI32, SizeC});
+  }
----------------
kmclaughlin-arm wrote:

Do these arguments need to be changed to i32? We are already checking that the value is in the expected range, and using the Clang tests it looks like the order and policy args are already i32.

If it is needed, I think we can just do this when creating the call below, i.e.

```suggestion
    return Builder.CreateCall(
        F, {StoreAddr, StoreValue64,
            ConstantInt::get(Int32Ty, Order->getZExtValue()),
            ConstantInt::get(Int32Ty, Policy->getZExtValue()), SizeC});
```

https://github.com/llvm/llvm-project/pull/181386


More information about the cfe-commits mailing list