diff --git a/lib/Target/CellSPU/README.txt b/lib/Target/CellSPU/README.txt index 0e7ad3533e9..3e7e0b68e8e 100644 --- a/lib/Target/CellSPU/README.txt +++ b/lib/Target/CellSPU/README.txt @@ -55,7 +55,7 @@ TODO: * i128 support: * zero extension, any extension: done - * sign extension: needed + * sign extension: done * arithmetic operators (add, sub, mul, div): needed * logical operations (and, or, shl, srl, sra, xor, nor, nand): needed diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 36c8bd56846..e218fb92d1c 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -2719,6 +2719,12 @@ static SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) SDValue Op0 = Op.getOperand(0); MVT Op0VT = Op0.getValueType().getSimpleVT(); + // extend i8 & i16 via i32 + if (Op0VT == MVT::i8 || Op0VT == MVT::i16) { + Op0 = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i32, Op0); + Op0VT = MVT::i32; + } + // The type to extend to needs to be a i128 and // the type to extend from needs to be i64 or i32. assert((OpVT == MVT::i128 && (Op0VT == MVT::i64 || Op0VT == MVT::i32)) && diff --git a/test/CodeGen/CellSPU/sext128.ll b/test/CodeGen/CellSPU/sext128.ll index 027c1c58afb..6ae9aa51202 100644 --- a/test/CodeGen/CellSPU/sext128.ll +++ b/test/CodeGen/CellSPU/sext128.ll @@ -48,3 +48,24 @@ entry: } declare i32 @myfunc(float) + +define i128 @func1(i8 %u) { +entry: +; CHECK: xsbh +; CHECK: xshw +; CHECK: rotmai +; CHECK: shufb +; CHECK: bi $lr + %0 = sext i8 %u to i128 + ret i128 %0 +} + +define i128 @func2(i16 %u) { +entry: +; CHECK: xshw +; CHECK: rotmai +; CHECK: shufb +; CHECK: bi $lr + %0 = sext i16 %u to i128 + ret i128 %0 +}