1515// It is a mandatory IRGen preparation pass (not a diagnostic pass).
1616//
1717// ===----------------------------------------------------------------------===//
18+ // /
19+ // / This file contains a pass for target specific constant folding:
20+ // / `TargetConstantFolding`. For details see the comments there.
21+ // /
22+ // ===----------------------------------------------------------------------===//
1823
1924#define DEBUG_TYPE " target-constant-folding"
20- #include " IRGenModule.h"
25+ #include " ../../IRGen/ IRGenModule.h"
2126#include " swift/SIL/SILBuilder.h"
2227#include " swift/SILOptimizer/PassManager/Transforms.h"
2328#include " swift/SILOptimizer/Utils/InstructionDeleter.h"
@@ -43,22 +48,24 @@ class TargetConstantFolding : public SILModuleTransform {
4348private:
4449 // / The entry point to the transformation.
4550 void run () override {
46- auto *irgenOpts = getModule ()->getIRGenOptionsOrNull ();
51+ SILModule *module = getModule ();
52+
53+ auto *irgenOpts = module ->getIRGenOptionsOrNull ();
4754 if (!irgenOpts)
4855 return ;
4956
5057 // We need an IRGenModule to get the actual sizes from type lowering.
5158 // Creating an IRGenModule involves some effort. Therefore this is a
5259 // module pass rather than a function pass so that this one-time setup
5360 // only needs to be done once and not for all functions in a module.
54- IRGenerator irgen (*irgenOpts, *getModule () );
61+ IRGenerator irgen (*irgenOpts, *module );
5562 auto targetMachine = irgen.createTargetMachine ();
5663 if (!targetMachine)
5764 return ;
5865 IRGenModule IGM (irgen, std::move (targetMachine));
5966
6067 // Scan all instructions in the module for constant foldable instructions.
61- for (SILFunction &function : *getModule () ) {
68+ for (SILFunction &function : *module ) {
6269
6370 if (!function.shouldOptimize ())
6471 continue ;
@@ -118,6 +125,12 @@ class TargetConstantFolding : public SILModuleTransform {
118125 if (!intTy)
119126 return false ;
120127
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+ }
121134 value = value.sextOrTrunc (intTy->getGreatestWidth ());
122135
123136 // Replace the builtin by an integer literal.
0 commit comments