Skip to content

Commit 0d8b864

Browse files
committed
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.
1 parent 11819a1 commit 0d8b864

File tree

5 files changed

+20
-37
lines changed

5 files changed

+20
-37
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,12 +1769,9 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
17691769
}
17701770

17711771
static Value *EmitAbs(CodeGenFunction &CGF, Value *ArgValue, bool HasNSW) {
1772-
// X < 0 ? -X : X
1773-
// TODO: Use phi-node (for better SimplifyCFGPass)
1774-
Value *NegOp = CGF.Builder.CreateNeg(ArgValue, "neg", false, HasNSW);
1775-
Constant *Zero = llvm::Constant::getNullValue(ArgValue->getType());
1776-
Value *CmpResult = CGF.Builder.CreateICmpSLT(ArgValue, Zero, "abscond");
1777-
return CGF.Builder.CreateSelect(CmpResult, NegOp, ArgValue, "abs");
1772+
return CGF.Builder.CreateBinaryIntrinsic(
1773+
Intrinsic::abs, ArgValue,
1774+
ConstantInt::get(CGF.Builder.getInt1Ty(), HasNSW));
17781775
}
17791776

17801777
static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,

clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-macros.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ typedef __SIZE_TYPE__ size_t;
1717
// BOTH-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
1818
// BOTH-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
1919
// BOTH-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
20-
// BOTH-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
21-
// BOTH-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
22-
// BOTH-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
20+
// BOTH-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 true)
2321
// BOTH-NEXT: ret i32 [[ABS]]
2422
signed int testabs(signed int a) {
2523
return __abs(a);
@@ -30,19 +28,15 @@ signed int testabs(signed int a) {
3028
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
3129
// 64BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
3230
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
33-
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
34-
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
35-
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
31+
// 64BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
3632
// 64BIT-NEXT: ret i64 [[ABS]]
3733
//
3834
// 32BIT-LABEL: @testlabs(
3935
// 32BIT-NEXT: entry:
4036
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
4137
// 32BIT-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
4238
// 32BIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
43-
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
44-
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
45-
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
39+
// 32BIT-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP0]], i1 true)
4640
// 32BIT-NEXT: ret i32 [[ABS]]
4741
//
4842
signed long testlabs(signed long a) {
@@ -54,19 +48,15 @@ signed long testlabs(signed long a) {
5448
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
5549
// 64BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
5650
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
57-
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
58-
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
59-
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
51+
// 64BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
6052
// 64BIT-NEXT: ret i64 [[ABS]]
6153
//
6254
// 32BIT-LABEL: @testllabs(
6355
// 32BIT-NEXT: entry:
6456
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
6557
// 32BIT-NEXT: store i64 [[A:%.*]], ptr [[A_ADDR]], align 8
6658
// 32BIT-NEXT: [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
67-
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
68-
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
69-
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
59+
// 32BIT-NEXT: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 [[TMP0]], i1 true)
7060
// 32BIT-NEXT: ret i64 [[ABS]]
7161
//
7262
signed long long testllabs(signed long long a) {

clang/test/CodeGen/abs-overflow.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
extern int abs(int x);
77

88
int absi(int x) {
9-
// WRAPV: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
10-
// WRAPV: [[CMP:%.*]] = icmp slt i32 [[X]], 0
11-
// WRAPV: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
9+
// WRAPV: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 false)
10+
// WRAPV-NEXT: ret i32 [[ABS]]
1211
//
1312
// BOTH-TRAP: [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
1413
// BOTH-TRAP: [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0
@@ -26,9 +25,8 @@ int absi(int x) {
2625
}
2726

2827
int babsi(int x) {
29-
// WRAPV: [[NEG:%.*]] = sub i32 0, [[X:%.*]]
30-
// WRAPV: [[CMP:%.*]] = icmp slt i32 [[X]], 0
31-
// WRAPV: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
28+
// WRAPV: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 false)
29+
// WRAPV-NEXT: ret i32 [[ABS]]
3230
//
3331
// BOTH-TRAP: [[NEG:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 0, i32 [[X:%.*]])
3432
// BOTH-TRAP: [[NEGV:%.*]] = extractvalue { i32, i1 } [[NEG]], 0

clang/test/CodeGen/builtin-abs.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,24 @@
22

33
int absi(int x) {
44
// CHECK-LABEL: @absi(
5-
// CHECK: [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
6-
// CHECK: [[CMP:%.*]] = icmp slt i32 [[X]], 0
7-
// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[X]]
5+
// CHECK: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 %0, i1 true)
6+
// CHECK-NEXT: ret i32 [[ABS]]
87
//
98
return __builtin_abs(x);
109
}
1110

1211
long absl(long x) {
1312
// CHECK-LABEL: @absl(
14-
// CHECK: [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
15-
// CHECK: [[CMP:%.*]] = icmp slt i64 [[X]], 0
16-
// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
13+
// CHECK: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 %0, i1 true)
14+
// CHECK-NEXT: ret i64 [[ABS]]
1715
//
1816
return __builtin_labs(x);
1917
}
2018

2119
long long absll(long long x) {
2220
// CHECK-LABEL: @absll(
23-
// CHECK: [[NEG:%.*]] = sub nsw i64 0, [[X:%.*]]
24-
// CHECK: [[CMP:%.*]] = icmp slt i64 [[X]], 0
25-
// CHECK: [[SEL:%.*]] = select i1 [[CMP]], i64 [[NEG]], i64 [[X]]
21+
// CHECK: [[ABS:%.*]] = call i64 @llvm.abs.i64(i64 %0, i1 true)
22+
// CHECK-NEXT: ret i64 [[ABS]]
2623
//
2724
return __builtin_llabs(x);
2825
}

clang/test/CodeGenCXX/builtins.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ long __builtin_abs(long); // #2
5353
extern "C" int __builtin_abs(int); // #3
5454

5555
int x = __builtin_abs(-2);
56-
// CHECK: store i32 2, ptr @x, align 4
56+
// CHECK: [[X:%.+]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
57+
// CHECK-NEXT: store i32 [[X]], ptr @x, align 4
5758

5859
long y = __builtin_abs(-2l);
5960
// CHECK: [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)

0 commit comments

Comments
 (0)