pmatos created this revision. pmatos added reviewers: dschuff, tlively. Herald added subscribers: asb, wingo, ecnelises, sunfish, hiraditya, jgravelle-google, sbc100. Herald added a project: All. pmatos requested review of this revision. Herald added subscribers: llvm-commits, cfe-commits, aheejin. Herald added projects: clang, LLVM.
This commits overrides the default lowering of rotates to fshl/fshr. It lowers the rotate straight to a target dependent rotate intrinsic. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D150670 Files: clang/lib/CodeGen/CGBuiltin.cpp llvm/include/llvm/IR/IntrinsicsWebAssembly.td llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -107,6 +107,12 @@ def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>; def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>; +// Lower the rotate intrinsic to a rotate instruction +def : Pat<(int_wasm_rotl_i32 I32:$lhs, I32:$rhs), + (ROTL_I32 I32:$lhs, I32:$rhs)>; +def : Pat<(int_wasm_rotr_i32 I32:$lhs, I32:$rhs), + (ROTR_I32 I32:$lhs, I32:$rhs)>; + defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond), (outs), (ins), [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))], Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -341,4 +341,16 @@ [], [IntrReadMem]>; +//===----------------------------------------------------------------------===// +// Rotate Intrinsics +// These are lowered from the target independent intrinsics to avoid +// funnel shift optimizations +//===----------------------------------------------------------------------===// + +def int_wasm_rotl_i32 : + DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + +def int_wasm_rotr_i32 : + DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + } // TargetPrefix = "wasm" Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -2120,6 +2120,15 @@ llvm::Type *Ty = Src->getType(); ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false); + // For WebAssembly we want to generate the target-specific rotate builtin, + // rather than generating fshl/fshr intrinsics. + if (getTarget().getTriple().isWasm()) { + unsigned IID = IsRotateRight ? Intrinsic::wasm_rotr_i32 + : Intrinsic::wasm_rotl_i32; + llvm::Function *F = CGM.getIntrinsic(IID); + return RValue::get(Builder.CreateCall(F, { Src, ShiftAmt })); + } + // Rotate is a special case of LLVM funnel shift - 1st 2 args are the same. unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl; Function *F = CGM.getIntrinsic(IID, Ty);
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -107,6 +107,12 @@ def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>; def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>; +// Lower the rotate intrinsic to a rotate instruction +def : Pat<(int_wasm_rotl_i32 I32:$lhs, I32:$rhs), + (ROTL_I32 I32:$lhs, I32:$rhs)>; +def : Pat<(int_wasm_rotr_i32 I32:$lhs, I32:$rhs), + (ROTR_I32 I32:$lhs, I32:$rhs)>; + defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond), (outs), (ins), [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))], Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -341,4 +341,16 @@ [], [IntrReadMem]>; +//===----------------------------------------------------------------------===// +// Rotate Intrinsics +// These are lowered from the target independent intrinsics to avoid +// funnel shift optimizations +//===----------------------------------------------------------------------===// + +def int_wasm_rotl_i32 : + DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + +def int_wasm_rotr_i32 : + DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + } // TargetPrefix = "wasm" Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -2120,6 +2120,15 @@ llvm::Type *Ty = Src->getType(); ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false); + // For WebAssembly we want to generate the target-specific rotate builtin, + // rather than generating fshl/fshr intrinsics. + if (getTarget().getTriple().isWasm()) { + unsigned IID = IsRotateRight ? Intrinsic::wasm_rotr_i32 + : Intrinsic::wasm_rotl_i32; + llvm::Function *F = CGM.getIntrinsic(IID); + return RValue::get(Builder.CreateCall(F, { Src, ShiftAmt })); + } + // Rotate is a special case of LLVM funnel shift - 1st 2 args are the same. unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl; Function *F = CGM.getIntrinsic(IID, Ty);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits