diff options
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 14 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/abs-1.ll | 24 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/call-callconv.ll | 16 |
3 files changed, 27 insertions, 27 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 78864ea479c..32e47b652aa 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1682,12 +1682,12 @@ Value *LibCallSimplifier::optimizeFls(CallInst *CI, IRBuilder<> &B) { } Value *LibCallSimplifier::optimizeAbs(CallInst *CI, IRBuilder<> &B) { - // abs(x) -> x >s -1 ? x : -x - Value *Op = CI->getArgOperand(0); - Value *Pos = - B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), "ispos"); - Value *Neg = B.CreateNeg(Op, "neg"); - return B.CreateSelect(Pos, Op, Neg); + // abs(x) -> x <s 0 ? -x : x + // The negation has 'nsw' because abs of INT_MIN is undefined. + Value *X = CI->getArgOperand(0); + Value *IsNeg = B.CreateICmpSLT(X, Constant::getNullValue(X->getType())); + Value *NegX = B.CreateNSWNeg(X, "neg"); + return B.CreateSelect(IsNeg, NegX, X); } Value *LibCallSimplifier::optimizeIsDigit(CallInst *CI, IRBuilder<> &B) { @@ -2716,4 +2716,4 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { FortifiedLibCallSimplifier::FortifiedLibCallSimplifier( const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize) - : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {}
\ No newline at end of file + : TLI(TLI), OnlyLowerUnknownSize(OnlyLowerUnknownSize) {} diff --git a/llvm/test/Transforms/InstCombine/abs-1.ll b/llvm/test/Transforms/InstCombine/abs-1.ll index 85543f975b7..ab1813c9043 100644 --- a/llvm/test/Transforms/InstCombine/abs-1.ll +++ b/llvm/test/Transforms/InstCombine/abs-1.ll @@ -12,10 +12,10 @@ declare i64 @llabs(i64) define i32 @test_abs(i32 %x) { ; CHECK-LABEL: @test_abs( -; CHECK-NEXT: [[ISPOS:%.*]] = icmp slt i32 [[X:%.*]], 0 -; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i32 [[NEG]], i32 [[X]] -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[X]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[NEG]], i32 [[X]] +; CHECK-NEXT: ret i32 [[TMP2]] ; %ret = call i32 @abs(i32 %x) ret i32 %ret @@ -23,10 +23,10 @@ define i32 @test_abs(i32 %x) { define i64 @test_labs(i64 %x) { ; CHECK-LABEL: @test_labs( -; CHECK-NEXT: [[ISPOS:%.*]] = icmp slt i64 [[X:%.*]], 0 -; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[X]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 [[NEG]], i64 [[X]] -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[X]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]] +; CHECK-NEXT: ret i64 [[TMP2]] ; %ret = call i64 @labs(i64 %x) ret i64 %ret @@ -34,10 +34,10 @@ define i64 @test_labs(i64 %x) { define i64 @test_llabs(i64 %x) { ; CHECK-LABEL: @test_llabs( -; CHECK-NEXT: [[ISPOS:%.*]] = icmp slt i64 [[X:%.*]], 0 -; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[X]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 [[NEG]], i64 [[X]] -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[X:%.*]], 0 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[X]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[NEG]], i64 [[X]] +; CHECK-NEXT: ret i64 [[TMP2]] ; %ret = call i64 @llabs(i64 %x) ret i64 %ret diff --git a/llvm/test/Transforms/InstCombine/call-callconv.ll b/llvm/test/Transforms/InstCombine/call-callconv.ll index f7f0d3aaa46..0cb2c55f9fd 100644 --- a/llvm/test/Transforms/InstCombine/call-callconv.ll +++ b/llvm/test/Transforms/InstCombine/call-callconv.ll @@ -6,10 +6,10 @@ define arm_aapcscc i32 @_abs(i32 %i) nounwind readnone { ; CHECK-LABEL: @_abs( -; CHECK-NEXT: [[ISPOS:%.*]] = icmp slt i32 [[I:%.*]], 0 -; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[I]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i32 [[NEG]], i32 [[I]] -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[I:%.*]], 0 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[I]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[NEG]], i32 [[I]] +; CHECK-NEXT: ret i32 [[TMP2]] ; %call = tail call arm_aapcscc i32 @abs(i32 %i) nounwind readnone ret i32 %call @@ -19,10 +19,10 @@ declare arm_aapcscc i32 @abs(i32) nounwind readnone define arm_aapcscc i32 @_labs(i32 %i) nounwind readnone { ; CHECK-LABEL: @_labs( -; CHECK-NEXT: [[ISPOS:%.*]] = icmp slt i32 [[I:%.*]], 0 -; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[I]] -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i32 [[NEG]], i32 [[I]] -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[I:%.*]], 0 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[I]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[NEG]], i32 [[I]] +; CHECK-NEXT: ret i32 [[TMP2]] ; %call = tail call arm_aapcscc i32 @labs(i32 %i) nounwind readnone ret i32 %call |