================ @@ -2492,12 +2492,36 @@ 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(); + llvm::Value *BitWidthVal = ConstantInt::get(Ty, BitWidth); + + bool IsShiftAmtSigned = E->getArg(1)->getType()->isSignedIntegerType(); + + if (IsShiftAmtSigned) { + // 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); + } + + // converting ShiftAmt to Src type, ShiftAmt is positive ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false); + ShiftAmt = Builder.CreateURem(ShiftAmt, BitWidthVal); ---------------- chaitanyav wrote:
i am able to reproduce the issue and working on the fix ```bash nagac@macbook-pro ~/scratch/llvm_test ./test_rotate_runtime Static assertions passed - compile-time evaluation works! Runtime: 341 rotate left 1 = 171 (expected 171) Runtime: 341 rotate right 1 = 426 (expected 426) Runtime: 1 rotate left 36 (_BitInt(37)) = 68719476736 (expected 68719476736) All tests passed! Both compile-time and runtime paths work correctly. ``` https://github.com/llvm/llvm-project/pull/160259 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits