15
15
// It is a mandatory IRGen preparation pass (not a diagnostic pass).
16
16
//
17
17
// ===----------------------------------------------------------------------===//
18
+ // /
19
+ // / This file contains a pass for target specific constant folding:
20
+ // / `TargetConstantFolding`. For details see the comments there.
21
+ // /
22
+ // ===----------------------------------------------------------------------===//
18
23
19
24
#define DEBUG_TYPE " target-constant-folding"
20
- #include " IRGenModule.h"
25
+ #include " ../../IRGen/ IRGenModule.h"
21
26
#include " swift/SIL/SILBuilder.h"
22
27
#include " swift/SILOptimizer/PassManager/Transforms.h"
23
28
#include " swift/SILOptimizer/Utils/InstructionDeleter.h"
@@ -43,22 +48,28 @@ class TargetConstantFolding : public SILModuleTransform {
43
48
private:
44
49
// / The entry point to the transformation.
45
50
void run () override {
46
- auto *irgenOpts = getModule ()->getIRGenOptionsOrNull ();
51
+ SILModule *module = getModule ();
52
+
53
+ // We don't want to serialize target specific SIL.
54
+ assert (module ->isSerialized () &&
55
+ " TargetConstantFolding must not run before serialization" );
56
+
57
+ auto *irgenOpts = module ->getIRGenOptionsOrNull ();
47
58
if (!irgenOpts)
48
59
return ;
49
60
50
61
// We need an IRGenModule to get the actual sizes from type lowering.
51
62
// Creating an IRGenModule involves some effort. Therefore this is a
52
63
// module pass rather than a function pass so that this one-time setup
53
64
// only needs to be done once and not for all functions in a module.
54
- IRGenerator irgen (*irgenOpts, *getModule () );
65
+ IRGenerator irgen (*irgenOpts, *module );
55
66
auto targetMachine = irgen.createTargetMachine ();
56
67
if (!targetMachine)
57
68
return ;
58
69
IRGenModule IGM (irgen, std::move (targetMachine));
59
70
60
71
// Scan all instructions in the module for constant foldable instructions.
61
- for (SILFunction &function : *getModule () ) {
72
+ for (SILFunction &function : *module ) {
62
73
63
74
if (!function.shouldOptimize ())
64
75
continue ;
@@ -118,6 +129,12 @@ class TargetConstantFolding : public SILModuleTransform {
118
129
if (!intTy)
119
130
return false ;
120
131
132
+ // The bit widths can differ if we are compiling for a 32 bit target.
133
+ if (value.getActiveBits () > intTy->getGreatestWidth ()) {
134
+ // It's unlikely that a size/stride overflows 32 bits, but let's be on
135
+ // the safe side and catch a potential overflow.
136
+ return false ;
137
+ }
121
138
value = value.sextOrTrunc (intTy->getGreatestWidth ());
122
139
123
140
// Replace the builtin by an integer literal.
0 commit comments