Skip to content

Commit bce255a

Browse files
author
Pratheek Gowda BS
committed
logic moves to constantfolding.cpp
1 parent 6b5a018 commit bce255a

File tree

9 files changed

+82
-312
lines changed

9 files changed

+82
-312
lines changed

.github/workflows/bazel-checks.yml

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,11 @@ jobs:
2222
if: github.repository == 'llvm/llvm-project'
2323
steps:
2424
- name: Fetch LLVM sources
25-
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
25+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
2626
- name: Setup Buildifier
2727
run: |
28-
sudo curl -L https://github.com/bazelbuild/buildtools/releases/download/v8.2.1/buildifier-linux-amd64 -o /usr/bin/buildifier --fail
28+
sudo curl -L https://github.com/bazelbuild/buildtools/releases/download/v8.2.1/buildifier-linux-amd64 -o /usr/bin/buildifier
2929
sudo chmod +x /usr/bin/buildifier
3030
- name: Run Buildifier
3131
run: |
3232
buildifier --mode=check $(find ./utils/bazel -name *BUILD*)
33-
34-
bazel-build:
35-
name: "Bazel Build/Test"
36-
# Only run on US Central workers so we only have to keep one cache warm as
37-
# the cache buckets are per cluster.
38-
runs-on:
39-
group: llvm-premerge-cluster-us-central
40-
labels: llvm-premerge-linux-runners
41-
if: github.repository == 'llvm/llvm-project'
42-
steps:
43-
- name: Fetch LLVM sources
44-
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
45-
# TODO(boomanaiden154): We should use a purpose built container for this. Move
46-
# over when we have fixed the issues with using custom containers with Github
47-
# ARC in GKE.
48-
- name: Setup System Dependencies
49-
run: |
50-
sudo apt-get update
51-
sudo apt-get install -y libmpfr-dev libpfm4-dev m4 libedit-dev
52-
sudo curl -L https://github.com/bazelbuild/bazelisk/releases/download/v1.27.0/bazelisk-amd64.deb --fail > /tmp/bazelisk.deb
53-
sudo apt-get install -y /tmp/bazelisk.deb
54-
rm /tmp/bazelisk.deb
55-
- name: Build/Test
56-
working-directory: utils/bazel
57-
run: |
58-
bazelisk test --config=ci --sandbox_base="" \
59-
--remote_cache=https://storage.googleapis.com/$CACHE_GCS_BUCKET-bazel \
60-
--google_default_credentials \
61-
@llvm-project//... //...

llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ class LibCallSimplifier {
209209
Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
210210
Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
211211
Value *optimizeFMod(CallInst *CI, IRBuilderBase &B);
212-
Value *optimizellrint(CallInst *CI,IRBuilderBase &B);
213212
Value *mergeSqrtToExp(CallInst *CI, IRBuilderBase &B);
214213
Value *optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B);
215214
Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B);

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
19431943
// environment, they can be folded in any case.
19441944
case Intrinsic::ceil:
19451945
case Intrinsic::floor:
1946+
case Intrinsic::llrint:
19461947
case Intrinsic::round:
19471948
case Intrinsic::roundeven:
19481949
case Intrinsic::trunc:
@@ -2007,7 +2008,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
20072008
return Name == "log" || Name == "logf" || Name == "logl" ||
20082009
Name == "log2" || Name == "log2f" || Name == "log10" ||
20092010
Name == "log10f" || Name == "logb" || Name == "logbf" ||
2010-
Name == "log1p" || Name == "log1pf";
2011+
Name == "log1p" || Name == "log1pf" || Name=="llrint" ||
2012+
Name=="llrintf";
20112013
case 'n':
20122014
return Name == "nearbyint" || Name == "nearbyintf";
20132015
case 'p':
@@ -2521,9 +2523,34 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
25212523

25222524
if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint ||
25232525
IntrinsicID == Intrinsic::roundeven) {
2524-
U.roundToIntegral(APFloat::rmNearestTiesToEven);
2525-
return ConstantFP::get(Ty->getContext(), U);
2526-
}
2526+
if (IntrinsicID == Intrinsic::llrint) {
2527+
2528+
// Use IEEE round-to-nearest, ties-to-even
2529+
unsigned Width = Ty->getIntegerBitWidth();
2530+
2531+
// llrint returns a signed long long, so result is signed.
2532+
APSInt Result(Width, /*isUnsigned=*/false);
2533+
2534+
bool IsExact = false;
2535+
2536+
// convertToInteger mutates, so use a temporary APFloat.
2537+
APFloat Tmp = U;
2538+
APFloat::opStatus Status = Tmp.convertToInteger(
2539+
Result, APFloat::rmNearestTiesToEven, &IsExact);
2540+
2541+
// Allowed: opOK or opInexact
2542+
// Disallowed: opInvalidOp (overflow)
2543+
if (Status == APFloat::opOK || Status == APFloat::opInexact)
2544+
return ConstantInt::get(Ty, Result);
2545+
2546+
return nullptr;
2547+
}
2548+
2549+
if (IntrinsicID == Intrinsic::nearbyint ||
2550+
IntrinsicID == Intrinsic::rint) {
2551+
U.roundToIntegral(APFloat::rmNearestTiesToEven);
2552+
return ConstantFP::get(Ty->getContext(), U);
2553+
}
25272554

25282555
if (IntrinsicID == Intrinsic::round) {
25292556
U.roundToIntegral(APFloat::rmNearestTiesToAway);
@@ -2940,6 +2967,12 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
29402967
return ConstantFP::get(Ty->getContext(), U);
29412968
}
29422969
break;
2970+
case LibFunc_llrint:
2971+
case LibFunc_llrintf:
2972+
if (TLI->has(Func)) {
2973+
return ConstantFP::get(Ty->getContext(), U);
2974+
}
2975+
break;
29432976
case LibFunc_log:
29442977
case LibFunc_logf:
29452978
case LibFunc_log_finite:

llvm/lib/Transforms/Utils/BuildLibCalls.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
13611361
case LibFunc_fminimum_numl:
13621362
case LibFunc_labs:
13631363
case LibFunc_llabs:
1364+
case LibFunc_llrintf:
1365+
case LibFunc_llrintl:
1366+
case LibFunc_llrint:
13641367
case LibFunc_nearbyint:
13651368
case LibFunc_nearbyintf:
13661369
case LibFunc_nearbyintl:
@@ -1383,13 +1386,6 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
13831386
Changed |= setDoesNotFreeMemory(F);
13841387
Changed |= setWillReturn(F);
13851388
break;
1386-
case LibFunc_llrintf:
1387-
case LibFunc_llrintl:
1388-
case LibFunc_llrint:
1389-
Changed|=setDoesNotThrow(F);
1390-
Changed|=setDoesNotAccessMemory(F);
1391-
Changed|=setWillReturn(F);
1392-
break;
13931389
case LibFunc_sincos:
13941390
case LibFunc_sincosf:
13951391
case LibFunc_sincosl:

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,28 +3188,6 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
31883188
return ConstantFP::get(CI->getType(), Rem);
31893189
}
31903190

3191-
Value *LibCallSimplifier::optimizellrint(CallInst *CI,IRBuilderBase &B){
3192-
const APFloat *X;
3193-
if(!match(CI->getOperand(0),m_APFloat(X))){
3194-
return nullptr;
3195-
}
3196-
Type *type=CI->getType();
3197-
3198-
unsigned width=type->getIntegerBitWidth();
3199-
3200-
APSInt Result(width,false);
3201-
bool Isexact;
3202-
3203-
APFloat::opStatus Status=X->convertToInteger(Result,APFloat::rmNearestTiesToEven,&Isexact);
3204-
3205-
if(Status==APFloat::opOK || Status==APFloat::opInexact){
3206-
return ConstantInt::get(type,Result);
3207-
}
3208-
3209-
return nullptr;
3210-
3211-
}
3212-
32133191
/// Constant folds fdim
32143192
Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
32153193
// Cannot perform the fold unless the call has attribute memory(none)
@@ -4130,6 +4108,8 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
41304108
return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
41314109
case LibFunc_floor:
41324110
return replaceUnaryCall(CI, Builder, Intrinsic::floor);
4111+
case LibFunc_llrint:
4112+
return replaceUnaryCall(CI, Builder, Intrinsic::llrint);
41334113
case LibFunc_round:
41344114
return replaceUnaryCall(CI, Builder, Intrinsic::round);
41354115
case LibFunc_roundeven:

llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,6 @@ declare void @memset_pattern16(ptr, ptr, i64)
12501250
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(read) }
12511251
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
12521252
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) }
1253-
; CHECK-DAG: attributes [[MATH_NOACCESS]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
12541253
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
12551254
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
12561255
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
Lines changed: 38 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,46 @@
1-
; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
2-
3-
4-
declare i64 @llrint(double)
5-
6-
; Positive number test
7-
; CHECK-LABEL: define i64 @test_llrint_pos()
8-
; CHECK-NEXT: entry:
9-
; CHECK-NEXT: ret i64 4
10-
define i64 @test_llrint_pos() {
11-
entry:
12-
%val = call i64 @llrint(double 3.5)
13-
ret i64 %val
14-
}
15-
16-
; Negative number test
17-
; CHECK-LABEL: define i64 @test_llrint_neg()
18-
; CHECK-NEXT: entry:
19-
; CHECK-NEXT: ret i64 -2
20-
define i64 @test_llrint_neg() {
21-
entry:
22-
%val = call i64 @llrint(double -2.5)
23-
ret i64 %val
24-
}
25-
26-
; Zero test
27-
; CHECK-LABEL: define i64 @test_llrint_zero()
28-
; CHECK-NEXT: entry:
29-
; CHECK-NEXT: ret i64 0
30-
define i64 @test_llrint_zero() {
31-
entry:
32-
%val = call i64 @llrint(double 0.0)
33-
ret i64 %val
34-
}
35-
36-
; Large value test
37-
; CHECK-LABEL: define i64 @test_llrint_large()
38-
; CHECK-NEXT: entry:
39-
; CHECK-NEXT: ret i64 1000000
40-
define i64 @test_llrint_large() {
41-
entry:
42-
%val = call i64 @llrint(double 1.0e6)
43-
ret i64 %val
1+
; RUN: opt -S -passes=instcombine %s | FileCheck %s
2+
3+
; ============================================================
4+
; Test constant folding of overloaded @llvm.llrint intrinsic
5+
; ============================================================
6+
7+
; LLVM intrinsic declarations (typed overloads)
8+
declare i64 @llvm.llrint.f32(float)
9+
declare i64 @llvm.llrint.f64(double)
10+
declare i64 @llvm.llrint.f80(x86_fp80)
11+
declare i64 @llvm.llrint.f128(fp128)
12+
13+
; ============================================================
14+
; float overload
15+
; ============================================================
16+
define i64 @test_f32_pos() {
17+
; CHECK-LABEL: @test_f32_pos(
18+
; CHECK-NEXT: ret i64 4
19+
%v = call i64 @llvm.llrint.f32(float 3.5)
20+
ret i64 %v
4421
}
4522

46-
; Rounding test (check ties-to-even)
47-
; CHECK-LABEL: define i64 @test_llrint_round_even()
48-
; CHECK-NEXT: entry:
49-
; CHECK-NEXT: ret i64 2
50-
define i64 @test_llrint_round_even() {
51-
entry:
52-
%val = call i64 @llrint(double 2.5)
53-
ret i64 %val
23+
define i64 @test_f32_neg() {
24+
; CHECK-LABEL: @test_f32_neg(
25+
; CHECK-NEXT: ret i64 -2
26+
%v = call i64 @llvm.llrint.f32(float -2.5)
27+
ret i64 %v
5428
}
5529

56-
; NaN test
57-
; CHECK-LABEL: define i64 @test_llrint_nan()
58-
; CHECK-NEXT: entry:
59-
; CHECK-NEXT: %val = call i64 @llrint(double 0x7FF8000000000000)
60-
; CHECK-NEXT: ret i64 %val
61-
define i64 @test_llrint_nan() {
62-
entry:
63-
%val = call i64 @llrint(double 0x7FF8000000000000) ; NaN
64-
ret i64 %val
30+
; ============================================================
31+
; double overload
32+
; ============================================================
33+
define i64 @test_f64_pos() {
34+
; CHECK-LABEL: @test_f64_pos(
35+
; CHECK-NEXT: ret i64 4
36+
%v = call i64 @llvm.llrint.f64(double 3.5)
37+
ret i64 %v
6538
}
6639

67-
; +Inf test
68-
; CHECK-LABEL: define i64 @test_llrint_posinf()
69-
; CHECK-NEXT: entry:
70-
; CHECK-NEXT: %val = call i64 @llrint(double 0x7FF0000000000000)
71-
; CHECK-NEXT: ret i64 %val
72-
define i64 @test_llrint_posinf() {
73-
entry:
74-
%val = call i64 @llrint(double 0x7FF0000000000000) ; +Inf
75-
ret i64 %val
40+
define i64 @test_f64_neg() {
41+
; CHECK-LABEL: @test_f64_neg(
42+
; CHECK-NEXT: ret i64 -2
43+
%v = call i64 @llvm.llrint.f64(double -2.5)
44+
ret i64 %v
7645
}
7746

78-
; -Inf test
79-
; CHECK-LABEL: define i64 @test_llrint_neginf()
80-
; CHECK-NEXT: entry:
81-
; CHECK-NEXT: %val = call i64 @llrint(double 0xFFF0000000000000)
82-
; CHECK-NEXT: ret i64 %val
83-
define i64 @test_llrint_neginf() {
84-
entry:
85-
%val = call i64 @llrint(double 0xFFF0000000000000) ; -Inf
86-
ret i64 %val
87-
}

0 commit comments

Comments
 (0)