diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 91aa03c0740..2c0662aeadc 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -176,6 +176,14 @@ private: } bool translateUnreachable(const User &U) { return true; } + bool translateSExt(const User &U) { + return translateCast(TargetOpcode::G_SEXT, U); + } + + bool translateZExt(const User &U) { + return translateCast(TargetOpcode::G_ZEXT, U); + } + /// Translate return (ret) instruction. /// The target needs to implement CallLowering::lowerReturn for /// this to succeed. @@ -207,8 +215,6 @@ private: bool translateFence(const User &U) { return false; } bool translateAtomicCmpXchg(const User &U) { return false; } bool translateAtomicRMW(const User &U) { return false; } - bool translateSExt(const User &U) { return false; } - bool translateZExt(const User &U) { return false; } bool translateFPToUI(const User &U) { return false; } bool translateFPToSI(const User &U) { return false; } bool translateUIToFP(const User &U) { return false; } diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index 6f023012221..d963f62efa0 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +//------------------------------------------------------------------------------ // Unary ops. //------------------------------------------------------------------------------ @@ -23,6 +24,23 @@ def G_ANYEXTEND : Instruction { let hasSideEffects = 0; } +// Sign extend the underlying scalar type of an operation, copying the sign bit +// into the newly-created space. +def G_SEXT : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + +// Zero extend the underlying scalar type of an operation, putting zero bits +// into the newly-created space. +def G_ZEXT : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + + // Truncate the underlying scalar type of an operation. This is equivalent to // G_EXTRACT for scalar types, but acts elementwise on vectors. def G_TRUNC : Instruction { @@ -31,10 +49,6 @@ def G_TRUNC : Instruction { let hasSideEffects = 0; } -//------------------------------------------------------------------------------ -// Unary ops. -//------------------------------------------------------------------------------ - def G_FRAME_INDEX : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins unknown:$src2); diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 02077c5972a..c8997f65d3c 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -232,6 +232,12 @@ HANDLE_TARGET_OPCODE(G_TRUNC) /// Generic integer constant. HANDLE_TARGET_OPCODE(G_CONSTANT) +// Generic sign extend +HANDLE_TARGET_OPCODE(G_SEXT) + +// Generic zero extend +HANDLE_TARGET_OPCODE(G_ZEXT) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index ad1e01fc5ac..ef1f6fd444e 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -406,3 +406,21 @@ define i8* @test_constant_inttoptr() { define i64 @test_reused_constant() { ret i64 1 } + +; CHECK-LABEL: name: test_sext +; CHECK: [[IN:%[0-9]+]](32) = COPY %w0 +; CHECK: [[RES:%[0-9]+]](64) = G_SEXT { s64, s32 } [[IN]] +; CHECK: %x0 = COPY [[RES]] +define i64 @test_sext(i32 %in) { + %res = sext i32 %in to i64 + ret i64 %res +} + +; CHECK-LABEL: name: test_zext +; CHECK: [[IN:%[0-9]+]](32) = COPY %w0 +; CHECK: [[RES:%[0-9]+]](64) = G_ZEXT { s64, s32 } [[IN]] +; CHECK: %x0 = COPY [[RES]] +define i64 @test_zext(i32 %in) { + %res = zext i32 %in to i64 + ret i64 %res +}