[clang] [clang] Implement __builtin_stdc_rotate_left, __builtin_stdc_rotate_right (PR #160259)

NagaChaitanya Vellanki via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 1 15:00:20 PDT 2025


================
@@ -2492,12 +2492,34 @@ RValue CodeGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) {
   // The builtin's shift arg may have a different type than the source arg and
   // result, but the LLVM intrinsic uses the same type for all values.
   llvm::Type *Ty = Src->getType();
+
+  unsigned BitWidth = Ty->getIntegerBitWidth();
+
+  if (E->getArg(1)->getType()->isSignedIntegerType()) {
+    // converting BitWidth to the type of ShiftAmt
+    llvm::Type *ShiftTy = ShiftAmt->getType();
+    llvm::Value *BitWidthInShiftTy = ConstantInt::get(ShiftTy, BitWidth);
+
+    // if ShiftAmt is negative, normalize ShiftAmt to [0, BitWidth - 1]
+    llvm::Value *RemResult = Builder.CreateSRem(ShiftAmt, BitWidthInShiftTy);
+    llvm::Value *PositiveShift =
+        Builder.CreateAdd(RemResult, BitWidthInShiftTy);
+
+    llvm::Value *Zero = ConstantInt::get(ShiftTy, 0);
+    llvm::Value *IsRemNegative = Builder.CreateICmpSLT(RemResult, Zero);
+
+    ShiftAmt = Builder.CreateSelect(IsRemNegative, PositiveShift, RemResult);
+  }
+
+  llvm::Type *ShiftTy = ShiftAmt->getType();
+  llvm::Value *BitWidthInShiftTy = ConstantInt::get(ShiftTy, BitWidth);
----------------
chaitanyav wrote:

implemented the changes for constant evaluation also.

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


More information about the cfe-commits mailing list