[clang] 0d8b864 - CGBuiltin: emit llvm.abs.* instead of neg+icmp+select for abs
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 27 21:30:01 PDT 2023
Author: Fangrui Song
Date: 2023-09-27T21:29:56-07:00
New Revision: 0d8b864829073cf6f0a40f1b257d6631fc4145d0
URL: https://github.com/llvm/llvm-project/commit/0d8b864829073cf6f0a40f1b257d6631fc4145d0
DIFF: https://github.com/llvm/llvm-project/commit/0d8b864829073cf6f0a40f1b257d6631fc4145d0.diff
LOG: CGBuiltin: emit llvm.abs.* instead of neg+icmp+select for abs
instcombine will combine neg+icmp+select to llvm.abs.*. Let's just emit
llvm.abs.* in the first place.
Added:
Modified:
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
clang/test/CodeGen/abs-overflow.c
clang/test/CodeGen/builtin-abs.c
clang/test/CodeGenCXX/builtins.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 04c0325c7fd038b..b0fd38408806566 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -1769,12 +1769,9 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
}
static Value *EmitAbs(CodeGenFunction &CGF, Value *ArgValue, bool HasNSW) {
- // X < 0 ? -X : X
- // TODO: Use phi-node (for better SimplifyCFGPass)
- Value *NegOp = CGF.Builder.CreateNeg(ArgValue, "neg", false, HasNSW);
- Constant *Zero = llvm::Constant::getNullValue(ArgValue->getType());
- Value *CmpResult = CGF.Builder.CreateICmpSLT(ArgValue, Zero, "abscond");
- return CGF.Builder.CreateSelect(CmpResult, NegOp, ArgValue, "abs");
+ return CGF.Builder.CreateBinaryIntrinsic(
+ Intrinsic::abs, ArgValue,
+ ConstantInt::get(CGF.Builder.getInt1Ty(), HasNSW));
}
static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
index 64bd6e3ed41e8bb..2ef4c28a5e999a4 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c
@@ -17,9 +17,7 @@ typedef __SIZE_TYPE__ size_t;
// BOTH-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// BOTH-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
// BOTH-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// BOTH-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
-// BOTH-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
-// BOTH-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
+// BOTH-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 true)
// BOTH-NEXT: ret i32 [[ABS]]
signed int testabs(signed int a) {
return __abs(a);
@@ -30,9 +28,7 @@ signed int testabs(signed int a) {
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 64BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
-// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
-// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
+// 64BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
// 64BIT-NEXT: ret i64 [[ABS]]
//
// 32BIT-LABEL: @testlabs(
@@ -40,9 +36,7 @@ signed int testabs(signed int a) {
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// 32BIT-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
// 32BIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
-// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
-// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
+// 32BIT-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP0]], i1 true)
// 32BIT-NEXT: ret i32 [[ABS]]
//
signed long testlabs(signed long a) {
@@ -54,9 +48,7 @@ signed long testlabs(signed long a) {
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 64BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
-// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
-// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
+// 64BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
// 64BIT-NEXT: ret i64 [[ABS]]
//
// 32BIT-LABEL: @testllabs(
@@ -64,9 +56,7 @@ signed long testlabs(signed long a) {
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 32BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
// 32BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
-// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
-// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
-// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
+// 32BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
// 32BIT-NEXT: ret i64 [[ABS]]
//
signed long long testllabs(signed long long a) {
diff --git a/clang/test/CodeGen/abs-overflow.c b/clang/test/CodeGen/abs-overflow.c
index 2b7647af9727096..aead4e282bd6211 100644
--- a/clang/test/CodeGen/abs-overflow.c
+++ b/clang/test/CodeGen/abs-overflow.c
@@ -6,9 +6,8 @@
extern int abs(int x);
int absi(int x) {
-// WRAPV: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
-// WRAPV: [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// WRAPV: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// WRAPV: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 false)
+// WRAPV-NEXT: ret i32 [[ABS]]
//
// BOTH-TRAP: [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
// BOTH-TRAP: [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
@@ -26,9 +25,8 @@ int absi(int x) {
}
int babsi(int x) {
-// WRAPV: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
-// WRAPV: [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// WRAPV: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// WRAPV: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 false)
+// WRAPV-NEXT: ret i32 [[ABS]]
//
// BOTH-TRAP: [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
// BOTH-TRAP: [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
diff --git a/clang/test/CodeGen/builtin-abs.c b/clang/test/CodeGen/builtin-abs.c
index 791395368a8c014..fd88b206f4a5a39 100644
--- a/clang/test/CodeGen/builtin-abs.c
+++ b/clang/test/CodeGen/builtin-abs.c
@@ -2,27 +2,24 @@
int absi(int x) {
// CHECK-LABEL: @absi(
-// CHECK: [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
-// CHECK: [[CMP:%.*]] = icmp slt i32 [[X]], 0
-// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
+// CHECK: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 true)
+// CHECK-NEXT: ret i32 [[ABS]]
//
return __builtin_abs(x);
}
long absl(long x) {
// CHECK-LABEL: @absl(
-// CHECK: [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK: [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 %0, i1 true)
+// CHECK-NEXT: ret i64 [[ABS]]
//
return __builtin_labs(x);
}
long long absll(long long x) {
// CHECK-LABEL: @absll(
-// CHECK: [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
-// CHECK: [[CMP:%.*]] = icmp slt i64 [[X]], 0
-// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
+// CHECK: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 %0, i1 true)
+// CHECK-NEXT: ret i64 [[ABS]]
//
return __builtin_llabs(x);
}
diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp
index 39201595d55e6e4..90265186fb3d8c8 100644
--- a/clang/test/CodeGenCXX/builtins.cpp
+++ b/clang/test/CodeGenCXX/builtins.cpp
@@ -53,7 +53,8 @@ long __builtin_abs(long); // #2
extern "C" int __builtin_abs(int); // #3
int x = __builtin_abs(-2);
-// CHECK: store i32 2, ptr @x, align 4
+// CHECK: [[X:%.+]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
+// CHECK-NEXT: store i32 [[X]], ptr @x, align 4
long y = __builtin_abs(-2l);
// CHECK: [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
More information about the cfe-commits
mailing list