From e7fba004ce02b6adbcc2e04d6adde18d63d0f228 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Thu, 18 Sep 2014 07:04:54 +0000 Subject: [PATCH] [FastISel][AArch64] Simplify XALU multiplies. Simplify {s|u}mul.with.overflow to {s|u}add.with.overflow when possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218033 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 23 ++++++++++++++++++++++- test/CodeGen/AArch64/arm64-xaluo.ll | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index cb0fa958a5a..e64f1bdacd8 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -3050,9 +3050,30 @@ bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { isCommutativeIntrinsic(II)) std::swap(LHS, RHS); + // Simplify multiplies. + unsigned IID = II->getIntrinsicID(); + switch (IID) { + default: + break; + case Intrinsic::smul_with_overflow: + if (const auto *C = dyn_cast(RHS)) + if (C->getValue() == 2) { + IID = Intrinsic::sadd_with_overflow; + RHS = LHS; + } + break; + case Intrinsic::umul_with_overflow: + if (const auto *C = dyn_cast(RHS)) + if (C->getValue() == 2) { + IID = Intrinsic::uadd_with_overflow; + RHS = LHS; + } + break; + } + unsigned ResultReg1 = 0, ResultReg2 = 0, MulReg = 0; AArch64CC::CondCode CC = AArch64CC::Invalid; - switch (II->getIntrinsicID()) { + switch (IID) { default: llvm_unreachable("Unexpected intrinsic!"); case Intrinsic::sadd_with_overflow: ResultReg1 = emitAdd(VT, LHS, RHS, /*SetFlags=*/true); diff --git a/test/CodeGen/AArch64/arm64-xaluo.ll b/test/CodeGen/AArch64/arm64-xaluo.ll index d23eb877b99..687a2f735b2 100644 --- a/test/CodeGen/AArch64/arm64-xaluo.ll +++ b/test/CodeGen/AArch64/arm64-xaluo.ll @@ -217,6 +217,18 @@ entry: ret i1 %obit } +define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) { +entry: +; CHECK-LABEL: smulo2.i64 +; CHECK: adds [[MREG:x[0-9]+]], x0, x0 +; CHECK-NEXT: cset {{w[0-9]+}}, vs + %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) + %val = extractvalue {i64, i1} %t, 0 + %obit = extractvalue {i64, i1} %t, 1 + store i64 %val, i64* %res + ret i1 %obit +} + define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) { entry: ; CHECK-LABEL: umulo.i32 @@ -243,6 +255,18 @@ entry: ret i1 %obit } +define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) { +entry: +; CHECK-LABEL: umulo2.i64 +; CHECK: adds [[MREG:x[0-9]+]], x0, x0 +; CHECK-NEXT: cset {{w[0-9]+}}, hs + %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) + %val = extractvalue {i64, i1} %t, 0 + %obit = extractvalue {i64, i1} %t, 1 + store i64 %val, i64* %res + ret i1 %obit +} + ; ; Check the use of the overflow bit in combination with a select instruction. -- 2.34.1