@@ -1413,72 +1413,6 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon) (llvm.Value, e
14131413 }
14141414}
14151415
1416- func (c * Compiler ) emitBoundsCheck (frame * Frame , arrayLen , index llvm.Value , indexType types.Type ) {
1417- if frame .fn .IsNoBounds () {
1418- // The //go:nobounds pragma was added to the function to avoid bounds
1419- // checking.
1420- return
1421- }
1422-
1423- // Sometimes, the index can be e.g. an uint8 or int8, and we have to
1424- // correctly extend that type.
1425- if index .Type ().IntTypeWidth () < arrayLen .Type ().IntTypeWidth () {
1426- if indexType .(* types.Basic ).Info ()& types .IsUnsigned == 0 {
1427- index = c .builder .CreateZExt (index , arrayLen .Type (), "" )
1428- } else {
1429- index = c .builder .CreateSExt (index , arrayLen .Type (), "" )
1430- }
1431- }
1432-
1433- // Optimize away trivial cases.
1434- // LLVM would do this anyway with interprocedural optimizations, but it
1435- // helps to see cases where bounds check elimination would really help.
1436- if index .IsConstant () && arrayLen .IsConstant () && ! arrayLen .IsUndef () {
1437- index := index .SExtValue ()
1438- arrayLen := arrayLen .SExtValue ()
1439- if index >= 0 && index < arrayLen {
1440- return
1441- }
1442- }
1443-
1444- if index .Type ().IntTypeWidth () > c .intType .IntTypeWidth () {
1445- // Index is too big for the regular bounds check. Use the one for int64.
1446- c .createRuntimeCall ("lookupBoundsCheckLong" , []llvm.Value {arrayLen , index }, "" )
1447- } else {
1448- c .createRuntimeCall ("lookupBoundsCheck" , []llvm.Value {arrayLen , index }, "" )
1449- }
1450- }
1451-
1452- func (c * Compiler ) emitSliceBoundsCheck (frame * Frame , capacity , low , high llvm.Value , lowType , highType * types.Basic ) {
1453- if frame .fn .IsNoBounds () {
1454- // The //go:nobounds pragma was added to the function to avoid bounds
1455- // checking.
1456- return
1457- }
1458-
1459- uintptrWidth := c .uintptrType .IntTypeWidth ()
1460- if low .Type ().IntTypeWidth () > uintptrWidth || high .Type ().IntTypeWidth () > uintptrWidth {
1461- if low .Type ().IntTypeWidth () < 64 {
1462- if lowType .Info ()& types .IsUnsigned != 0 {
1463- low = c .builder .CreateZExt (low , c .ctx .Int64Type (), "" )
1464- } else {
1465- low = c .builder .CreateSExt (low , c .ctx .Int64Type (), "" )
1466- }
1467- }
1468- if high .Type ().IntTypeWidth () < 64 {
1469- if highType .Info ()& types .IsUnsigned != 0 {
1470- high = c .builder .CreateZExt (high , c .ctx .Int64Type (), "" )
1471- } else {
1472- high = c .builder .CreateSExt (high , c .ctx .Int64Type (), "" )
1473- }
1474- }
1475- // TODO: 32-bit or even 16-bit slice bounds checks for 8-bit platforms
1476- c .createRuntimeCall ("sliceBoundsCheck64" , []llvm.Value {capacity , low , high }, "" )
1477- } else {
1478- c .createRuntimeCall ("sliceBoundsCheck" , []llvm.Value {capacity , low , high }, "" )
1479- }
1480- }
1481-
14821416func (c * Compiler ) parseExpr (frame * Frame , expr ssa.Value ) (llvm.Value , error ) {
14831417 if value , ok := frame .locals [expr ]; ok {
14841418 // Value is a local variable that has already been computed.
@@ -1623,7 +1557,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
16231557 // Check bounds.
16241558 arrayLen := expr .X .Type ().(* types.Array ).Len ()
16251559 arrayLenLLVM := llvm .ConstInt (c .uintptrType , uint64 (arrayLen ), false )
1626- c .emitBoundsCheck (frame , arrayLenLLVM , index , expr .Index .Type ())
1560+ c .emitLookupBoundsCheck (frame , arrayLenLLVM , index , expr .Index .Type ())
16271561
16281562 // Can't load directly from array (as index is non-constant), so have to
16291563 // do it using an alloca+gep+load.
@@ -1670,7 +1604,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
16701604
16711605 // Bounds check.
16721606 // LLVM optimizes this away in most cases.
1673- c .emitBoundsCheck (frame , buflen , index , expr .Index .Type ())
1607+ c .emitLookupBoundsCheck (frame , buflen , index , expr .Index .Type ())
16741608
16751609 switch expr .X .Type ().Underlying ().(type ) {
16761610 case * types.Pointer :
@@ -1703,7 +1637,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
17031637 // Bounds check.
17041638 // LLVM optimizes this away in most cases.
17051639 length := c .builder .CreateExtractValue (value , 1 , "len" )
1706- c .emitBoundsCheck (frame , length , index , expr .Index .Type ())
1640+ c .emitLookupBoundsCheck (frame , length , index , expr .Index .Type ())
17071641
17081642 // Lookup byte
17091643 buf := c .builder .CreateExtractValue (value , 0 , "" )
0 commit comments