Index: include/llvm/IR/IntrinsicsAArch64.td =================================================================== --- include/llvm/IR/IntrinsicsAArch64.td +++ include/llvm/IR/IntrinsicsAArch64.td @@ -653,3 +653,8 @@ def int_aarch64_crc32cx : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; } + +// Rotate Right (ROR) +def int_aarch64_ror : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem]>; Index: include/llvm/IR/IntrinsicsARM.td =================================================================== --- include/llvm/IR/IntrinsicsARM.td +++ include/llvm/IR/IntrinsicsARM.td @@ -531,4 +531,10 @@ def int_arm_neon_sha256h2: SHA_3Arg_v4i32_Intrinsic; def int_arm_neon_sha256su1: SHA_3Arg_v4i32_Intrinsic; + +// Rotate Right (ROR) +def int_arm_ror : Intrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + } // end TargetPrefix Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -716,6 +716,10 @@ def : ShiftAlias<"rorv", RORVWr, GPR32>; def : ShiftAlias<"rorv", RORVXr, GPR64>; +// Rotate Right (ROR) +def : Pat<(int_aarch64_ror GPR32:$Rn, GPR32:$Rm), (RORVWr $Rn, $Rm)>; +def : Pat<(int_aarch64_ror GPR64:$Rn, GPR64:$Rm), (RORVXr $Rn, $Rm)>; + // Multiply-add let AddedComplexity = 7 in { defm MADD : MulAccum<0, "madd", add>; Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -2943,6 +2943,13 @@ "RBIT intrinsic must have i32 type!"); return DAG.getNode(ISD::BITREVERSE, dl, MVT::i32, Op.getOperand(1)); } + case Intrinsic::arm_ror: { + assert(Op.getOperand(1).getValueType() == MVT::i32 && + Op.getOperand(2).getValueType() == MVT::i32 && + "ROR intrinsic must have both operands of i32 type!"); + return DAG.getNode(ISD::ROTR, dl, MVT::i32, + Op.getOperand(1), Op.getOperand(2)); + } case Intrinsic::thread_pointer: { EVT PtrVT = getPointerTy(DAG.getDataLayout()); return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);