OEFACE         // itable and data words of an empty-interface value.
        OITAB          // itable word of an interface value.
        OIDATA         // data word of an interface value in X
-       OSPTR          // base pointer of a slice or string.
+       OSPTR          // base pointer of a slice or string. Bounded==1 means known non-nil.
        OCFUNC         // reference to c function pointer (not go func value)
        OCHECKNIL      // emit code to ensure pointer/interface not nil
        ORESULT        // result of a function call; Xoffset is stack offset
 
                n := n.(*ir.UnaryExpr)
                a := s.expr(n.X)
                if n.X.Type().IsSlice() {
-                       return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
+                       if n.Bounded() {
+                               return s.newValue1(ssa.OpSlicePtr, n.Type(), a)
+                       }
+                       return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), a)
                } else {
                        return s.newValue1(ssa.OpStringPtr, n.Type(), a)
                }
 
 
                // Copy from the static string data to the [n]byte.
                if len(sc) > 0 {
-                       as := ir.NewAssignStmt(base.Pos, ir.NewStarExpr(base.Pos, p), ir.NewStarExpr(base.Pos, typecheck.ConvNop(ir.NewUnaryExpr(base.Pos, ir.OSPTR, s), t.PtrTo())))
+                       sptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
+                       sptr.SetBounded(true)
+                       as := ir.NewAssignStmt(base.Pos, ir.NewStarExpr(base.Pos, p), ir.NewStarExpr(base.Pos, typecheck.ConvNop(sptr, t.PtrTo())))
                        appendWalkStmt(init, as)
                }
 
 
                // Pointer to current iteration position. Start on entry to the loop
                // with the pointer in hu.
                ptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, hs)
+               ptr.SetBounded(true)
                huVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ptr)
                huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUINTPTR], huVal)
                hu := typecheck.Temp(types.Types[types.TUINTPTR])
 
--- /dev/null
+// run
+
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "unsafe"
+
+//go:noinline
+func f(x []byte) bool {
+       return unsafe.SliceData(x) != nil
+}
+
+//go:noinline
+func g(x string) bool {
+       return unsafe.StringData(x) != nil
+}
+
+func main() {
+       if f(nil) {
+               panic("bad f")
+       }
+       if g("") {
+               panic("bad g")
+       }
+}