Index: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1232,6 +1232,10 @@ def : Pat<(shl i64:$rS, i32:$rB), (SLD $rS, $rB)>; +// SUBFIC +def : Pat<(sub imm64SExt16:$imm, i64:$in), + (SUBFIC8 $in, imm:$imm)>; + // SHL/SRL def : Pat<(shl i64:$in, (i32 imm:$imm)), (RLDICR $in, imm:$imm, (SHL64 imm:$imm))>; Index: llvm/trunk/test/CodeGen/PowerPC/subtract_from_imm.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/subtract_from_imm.ll +++ llvm/trunk/test/CodeGen/PowerPC/subtract_from_imm.ll @@ -0,0 +1,41 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s + +; Make sure that the subfic is generated iff possible + +define i64 @subtract_from_imm1(i64 %v) nounwind readnone { +entry: +; CHECK-LABEL: subtract_from_imm1 +; CHECK: subfic 3, 3, 32767 +; CHECK: blr + %sub = sub i64 32767, %v + ret i64 %sub +} + +define i64 @subtract_from_imm2(i64 %v) nounwind readnone { +entry: +; CHECK-LABEL: subtract_from_imm2 +; CHECK-NOT: subfic +; CHECK: blr + %sub = sub i64 32768, %v + ret i64 %sub +} + +define i64 @subtract_from_imm3(i64 %v) nounwind readnone { +entry: +; CHECK-LABEL: subtract_from_imm3 +; CHECK: subfic 3, 3, -32768 +; CHECK: blr + %sub = sub i64 -32768, %v + ret i64 %sub +} + +define i64 @subtract_from_imm4(i64 %v) nounwind readnone { +entry: +; CHECK-LABEL: subtract_from_imm4 +; CHECK-NOT: subfic +; CHECK: blr + %sub = sub i64 -32769, %v + ret i64 %sub +} +