summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2018-01-03 04:56:56 +0000
committerAmara Emerson <aemerson@apple.com>2018-01-03 04:56:56 +0000
commit9de62130fd62c8e6b6f51c123c5ed692828aad50 (patch)
tree3c5e5764ee610116a91995381b57cbcfa806896e /llvm/lib/CodeGen
parent12e17b19bab419f11070f504017b6ff3f86d673b (diff)
downloadbcm5719-llvm-9de62130fd62c8e6b6f51c123c5ed692828aad50.tar.gz
bcm5719-llvm-9de62130fd62c8e6b6f51c123c5ed692828aad50.zip
[GlobalISel][Legalizer] Fix legalization of llvm.smul.with.overflow
Previously the code for handling G_SMULO didn't properly check for the signed multiply overflow, instead treating it the same as the unsigned G_UMULO. Fixes PR35800. llvm-svn: 321690
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index a3b43c92a7f..c7118201b75 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -813,7 +813,21 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
unsigned Zero = MRI.createGenericVirtualRegister(Ty);
MIRBuilder.buildConstant(Zero, 0);
- MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
+
+ // For *signed* multiply, overflow is detected by checking:
+ // (hi != (lo >> bitwidth-1))
+ if (Opcode == TargetOpcode::G_SMULH) {
+ unsigned Shifted = MRI.createGenericVirtualRegister(Ty);
+ unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildConstant(ShiftAmt, Ty.getSizeInBits() - 1);
+ MIRBuilder.buildInstr(TargetOpcode::G_ASHR)
+ .addDef(Shifted)
+ .addUse(Res)
+ .addUse(ShiftAmt);
+ MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Shifted);
+ } else {
+ MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
+ }
MI.eraseFromParent();
return Legalized;
}
OpenPOWER on IntegriCloud