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,24 @@ 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
+ auto *irgenOpts = module ->getIRGenOptionsOrNull ();
47
54
if (!irgenOpts)
48
55
return ;
49
56
50
57
// We need an IRGenModule to get the actual sizes from type lowering.
51
58
// Creating an IRGenModule involves some effort. Therefore this is a
52
59
// module pass rather than a function pass so that this one-time setup
53
60
// only needs to be done once and not for all functions in a module.
54
- IRGenerator irgen (*irgenOpts, *getModule () );
61
+ IRGenerator irgen (*irgenOpts, *module );
55
62
auto targetMachine = irgen.createTargetMachine ();
56
63
if (!targetMachine)
57
64
return ;
58
65
IRGenModule IGM (irgen, std::move (targetMachine));
59
66
60
67
// Scan all instructions in the module for constant foldable instructions.
61
- for (SILFunction &function : *getModule () ) {
68
+ for (SILFunction &function : *module ) {
62
69
63
70
if (!function.shouldOptimize ())
64
71
continue ;
@@ -118,6 +125,12 @@ class TargetConstantFolding : public SILModuleTransform {
118
125
if (!intTy)
119
126
return false ;
120
127
128
+ // The bit widths can differ if we are compiling for a 32 bit target.
129
+ if (value.getActiveBits () > intTy->getGreatestWidth ()) {
130
+ // It's unlikely that a size/stride overflows 32 bits, but let's be on
131
+ // the safe side and catch a potential overflow.
132
+ return false ;
133
+ }
121
134
value = value.sextOrTrunc (intTy->getGreatestWidth ());
122
135
123
136
// Replace the builtin by an integer literal.
0 commit comments