Index: lib/Target/ARM/ARMInstrFormats.td =================================================================== --- lib/Target/ARM/ARMInstrFormats.td +++ lib/Target/ARM/ARMInstrFormats.td @@ -1005,6 +1005,9 @@ class Thumb2DSPMulPat : Pat { list Predicates = [IsThumb2, UseMulOps, HasDSP]; } +class Thumb2ExtractPat : Pat { + list Predicates = [IsThumb2, HasT2ExtractPack]; +} //===----------------------------------------------------------------------===// // Thumb Instruction Format Definitions. // Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -1984,12 +1984,16 @@ // A simple right-shift can also be used in most cases (the exception is the // SXTH operations with a rotate of 24: there the non-contiguous bits are // relevant). -def : Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, rot_imm:$rot), i8)), - (t2SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>, - Requires<[HasT2ExtractPack, IsThumb2]>; -def : Pat<(add rGPR:$Rn, (sext_inreg (srl rGPR:$Rm, imm8_or_16:$rot), i16)), - (t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>, - Requires<[HasT2ExtractPack, IsThumb2]>; +def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg + (srl rGPR:$Rm, rot_imm:$rot), i8)), + (t2SXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; +def : Thumb2ExtractPat<(add rGPR:$Rn, (sext_inreg + (srl rGPR:$Rm, imm8_or_16:$rot), i16)), + (t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; +def : Thumb2ExtractPat<(add rGPR:$Rn, (sra (shl (srl rGPR:$Rm, rot_imm:$rot), + (i32 16)), + (i32 16))), + (t2SXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; // Zero extenders @@ -2018,12 +2022,12 @@ BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; def t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">; -def : Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), 0xFF)), - (t2UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>, - Requires<[HasT2ExtractPack, IsThumb2]>; -def : Pat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), 0xFFFF)), - (t2UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>, - Requires<[HasT2ExtractPack, IsThumb2]>; +def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, rot_imm:$rot), + 0xFF)), + (t2UXTAB rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; +def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), + 0xFFFF)), + (t2UXTAH rGPR:$Rn, rGPR:$Rm, rot_imm:$rot)>; } Index: test/CodeGen/Thumb2/thumb2-sxt-uxt.ll =================================================================== --- test/CodeGen/Thumb2/thumb2-sxt-uxt.ll +++ test/CodeGen/Thumb2/thumb2-sxt-uxt.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m3 %s -o - | FileCheck %s +; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m4 %s -o - | FileCheck %s --check-prefix=CHECK-M4 define i32 @test1(i16 zeroext %z) nounwind { ; CHECK-LABEL: test1: @@ -27,3 +28,78 @@ %r = zext i8 %z to i32 ret i32 %r } + +define i32 @test5(i32 %a, i8 %b) { +; CHECK-LABEL: test5: +; CHECK-NOT: sxtab +; CHECK-M4: sxtab r0, r0, r1 + %sext = sext i8 %b to i32 + %add = add i32 %a, %sext + ret i32 %add +} + +define i32 @test6(i32 %a, i32 %b) { +; CHECK-LABEL: test6: +; CHECK-NOT: sxtab +; CHECK-M4: sxtab r0, r0, r1 + %shl = shl i32 %b, 24 + %ashr = ashr i32 %shl, 24 + %add = add i32 %a, %ashr + ret i32 %add +} + +define i32 @test7(i32 %a, i16 %b) { +; CHECK-LABEL: test7: +; CHECK-NOT: sxtah +; CHECK-M4: sxtah r0, r0, r1 + %sext = sext i16 %b to i32 + %add = add i32 %a, %sext + ret i32 %add +} + +define i32 @test8(i32 %a, i32 %b) { +; CHECK-LABEL: test8: +; CHECK-NOT: sxtah +; CHECK-M4: sxtah r0, r0, r1 + %shl = shl i32 %b, 16 + %ashr = ashr i32 %shl, 16 + %add = add i32 %a, %ashr + ret i32 %add +} + +define i32 @test9(i32 %a, i8 %b) { +; CHECK-LABEL: test9: +; CHECK-NOT: uxtab +; CHECK-M4: uxtab r0, r0, r1 + %zext = zext i8 %b to i32 + %add = add i32 %a, %zext + ret i32 %add +} + +define i32 @test10(i32 %a, i32 %b) { +;CHECK-LABEL: test10: +;CHECK-NOT: uxtab +;CHECK-M4: uxtab r0, r0, r1 + %and = and i32 %b, 255 + %add = add i32 %a, %and + ret i32 %add +} + +define i32 @test11(i32 %a, i16 %b) { +; CHECK-LABEL: test11: +; CHECK-NOT: uxtah +; CHECK-M4: uxtah r0, r0, r1 + %zext = zext i16 %b to i32 + %add = add i32 %a, %zext + ret i32 %add +} + +define i32 @test12(i32 %a, i32 %b) { +;CHECK-LABEL: test12: +;CHECK-NOT: uxtah +;CHECK-M4: uxtah r0, r0, r1 + %and = and i32 %b, 65535 + %add = add i32 %a, %and + ret i32 %add +} +