diff options
| author | Amara Emerson <aemerson@apple.com> | 2018-01-03 04:56:56 +0000 |
|---|---|---|
| committer | Amara Emerson <aemerson@apple.com> | 2018-01-03 04:56:56 +0000 |
| commit | 9de62130fd62c8e6b6f51c123c5ed692828aad50 (patch) | |
| tree | 3c5e5764ee610116a91995381b57cbcfa806896e /llvm/lib/CodeGen | |
| parent | 12e17b19bab419f11070f504017b6ff3f86d673b (diff) | |
| download | bcm5719-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.cpp | 16 |
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; } |

