Skip to content

Commit 90feaa5

Browse files
jinge90AlexeySachkovArtem Gindinson
committed
Support llvm.is.constant
Signed-off-by: Ge Jin <[email protected]> Co-authored-by: Alexey Sachkov <[email protected]> Co-authored-by: Artem Gindinson <[email protected]>
1 parent 9f3c10f commit 90feaa5

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "SPIRVFunction.h"
4949
#include "SPIRVInstruction.h"
5050
#include "SPIRVInternal.h"
51+
#include "SPIRVLLVMUtil.h"
5152
#include "SPIRVMDWalker.h"
5253
#include "SPIRVModule.h"
5354
#include "SPIRVType.h"
@@ -2744,6 +2745,13 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
27442745
// llvm.trap intrinsic is not implemented. But for now don't crash. This
27452746
// change is pending the trap/abort intrinsic implementation.
27462747
return nullptr;
2748+
case Intrinsic::is_constant: {
2749+
auto *CO = dyn_cast<Constant>(II->getOperand(0));
2750+
if (CO && isManifestConstant(CO))
2751+
return transValue(ConstantInt::getTrue(II->getType()), BB, false);
2752+
else
2753+
return transValue(ConstantInt::getFalse(II->getType()), BB, false);
2754+
}
27472755
default:
27482756
if (BM->isSPIRVAllowUnknownIntrinsicsEnabled())
27492757
return BM->addCallInst(

lib/SPIRV/libSPIRV/SPIRVLLVMUtil.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===- SPIRVLLVMUtil.h - SPIR-V LLVM-specific Utility Functions -*- C++ -*-===//
2+
//
3+
// Has inclusions from the LLVM Project, under the Apache License v2.0 with LLVM
4+
// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
///
10+
/// This file defines utility functions dedicated to processing LLVM classes
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef SPIRV_LIBSPIRV_SPIRVLLVMUTIL_H
15+
#define SPIRV_LIBSPIRV_SPIRVLLVMUTIL_H
16+
17+
#include "llvm/IR/Constants.h"
18+
#include "llvm/Support/Casting.h"
19+
20+
namespace SPIRV {
21+
inline bool isManifestConstant(const llvm::Constant *C) {
22+
if (llvm::isa<llvm::ConstantData>(C)) {
23+
return true;
24+
} else if (llvm::isa<llvm::ConstantAggregate>(C) ||
25+
llvm::isa<llvm::ConstantExpr>(C)) {
26+
for (const llvm::Value *Subc : C->operand_values()) {
27+
if (!isManifestConstant(llvm::cast<llvm::Constant>(Subc)))
28+
return false;
29+
}
30+
return true;
31+
}
32+
return false;
33+
}
34+
} // namespace SPIRV
35+
36+
#endif // SPIRV_LIBSPIRV_SPIRVLLVMUTIL_H

test/llvm.is.constant.ll

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv
3+
; RUN: llvm-spirv -r %t.spv -o %t_recover.bc
4+
; RUN: llvm-dis %t_recover.bc -o - | FileCheck %s
5+
6+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
7+
target triple = "spir64-unknown-unknown"
8+
9+
; CHECK: spir_func i1 @TestIsConstantInt32_False
10+
; CHECK: ret i1 false
11+
12+
; Function Attrs: nounwind readnone
13+
define spir_func i1 @TestIsConstantInt32_False(i32 %x) local_unnamed_addr #0 {
14+
entry:
15+
%0 = tail call i1 @llvm.is.constant.i32(i32 %x)
16+
ret i1 %0
17+
}
18+
19+
; CHECK: spir_func i1 @TestIsConstantInt32_True
20+
; CHECK: ret i1 true
21+
22+
; Function Attrs: nounwind readnone
23+
define spir_func i1 @TestIsConstantInt32_True() local_unnamed_addr #0 {
24+
entry:
25+
%0 = tail call i1 @llvm.is.constant.i32(i32 1)
26+
ret i1 %0
27+
}
28+
29+
; CHECK: spir_func i1 @TestIsConstantInt64_False
30+
; CHECK: ret i1 false
31+
32+
; Function Attrs: nounwind readnone
33+
define spir_func i1 @TestIsConstantInt64_False(i64 %x) local_unnamed_addr #0 {
34+
entry:
35+
%0 = tail call i1 @llvm.is.constant.i64(i64 %x)
36+
ret i1 %0
37+
}
38+
39+
40+
; CHECK: spir_func i1 @TestIsConstantInt64_True
41+
; CHECK: ret i1 true
42+
43+
; Function Attrs: nounwind readnone
44+
define spir_func i1 @TestIsConstantInt64_True() local_unnamed_addr #0 {
45+
entry:
46+
%0 = tail call i1 @llvm.is.constant.i64(i64 1)
47+
ret i1 %0
48+
}
49+
50+
; CHECK: spir_func i1 @TestIsConstantF32_False
51+
; CHECK: ret i1 false
52+
53+
; Function Attrs: nounwind readnone
54+
define spir_func i1 @TestIsConstantF32_False(float %x) local_unnamed_addr #0 {
55+
entry:
56+
%0 = tail call i1 @llvm.is.constant.f32(float %x)
57+
ret i1 %0
58+
}
59+
60+
61+
; CHECK: spir_func i1 @TestIsConstantF32_True
62+
; CHECK: ret i1 true
63+
64+
; Function Attrs: nounwind readnone
65+
define spir_func i1 @TestIsConstantF32_True() local_unnamed_addr #0 {
66+
entry:
67+
%0 = tail call i1 @llvm.is.constant.f32(float 0.5)
68+
ret i1 %0
69+
}
70+
71+
; CHECK: spir_func i1 @TestIsConstantF64_False
72+
; CHECK: ret i1 false
73+
74+
; Function Attrs: nounwind readnone
75+
define spir_func i1 @TestIsConstantF64_False(double %x) local_unnamed_addr #0 {
76+
entry:
77+
%0 = tail call i1 @llvm.is.constant.f64(double %x)
78+
ret i1 %0
79+
}
80+
81+
; CHECK: spir_func i1 @TestIsConstantF64_True
82+
; CHECK: ret i1 true
83+
84+
; Function Attrs: nounwind readnone
85+
define spir_func i1 @TestIsConstantF64_True() local_unnamed_addr #0 {
86+
entry:
87+
%0 = tail call i1 @llvm.is.constant.f64(double 0.5)
88+
ret i1 %0
89+
}
90+
91+
; CHECK: spir_func i1 @TestIsConstantVec_False
92+
; CHECK: ret i1 false
93+
94+
; Function Attrs: nounwind readnone
95+
define spir_func i1 @TestIsConstantVec_False(<4 x float> %x) local_unnamed_addr #0 {
96+
entry:
97+
%0 = tail call i1 @llvm.is.constant.v4f32(<4 x float> %x)
98+
ret i1 %0
99+
}
100+
101+
; CHECK: spir_func i1 @TestIsConstantVec_True
102+
; CHECK: ret i1 true
103+
104+
; Function Attrs: nounwind readnone
105+
define spir_func i1 @TestIsConstantVec_True() local_unnamed_addr #0 {
106+
entry:
107+
%0 = tail call i1 @llvm.is.constant.v4f32(<4 x float> <float 0.5, float 0.5, float 0.5, float 0.5>)
108+
ret i1 %0
109+
}
110+
111+
; Function Attrs: nounwind readnone
112+
declare i1 @llvm.is.constant.i32(i32) #1
113+
114+
; Function Attrs: nounwind readnone
115+
declare i1 @llvm.is.constant.i64(i64) #1
116+
117+
; Function Attrs: nounwind readnone
118+
declare i1 @llvm.is.constant.f32(float) #1
119+
120+
; Function Attrs: nounwind readnone
121+
declare i1 @llvm.is.constant.f64(double) #1
122+
123+
; Function Attrs: nounwind readnone
124+
declare i1 @llvm.is.constant.v4f32(<4 x float>) #1
125+
126+
attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
127+
attributes #1 = { nounwind readnone speculatable willreturn }
128+
129+
!llvm.module.flags = !{!0}
130+
!opencl.ocl.version = !{!1}
131+
!opencl.spir.version = !{!2}
132+
133+
!0 = !{i32 1, !"wchar_size", i32 4}
134+
!1 = !{i32 1, i32 0}
135+
!2 = !{i32 1, i32 2}

0 commit comments

Comments
 (0)