;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-opt %s --precompute-propagate -all -S -o - | filecheck %s (module ;; CHECK: (type $0 (func (result i32))) ;; CHECK: (type $array16 (array (mut i16))) (type $array16 (array (mut i16))) (type $array16-imm (array i16)) ;; CHECK: (type $2 (func (result (ref string)))) ;; CHECK: (type $3 (func (result anyref))) ;; CHECK: (type $4 (func (result (ref any)))) ;; CHECK: (export "get_codepoint-unicode" (func $get_codepoint-unicode)) ;; CHECK: (export "get_codepoint-surrogate" (func $get_codepoint-surrogate)) ;; CHECK: (export "test" (func $encode-stashed)) ;; CHECK: (export "slice" (func $slice)) ;; CHECK: (export "slice-unicode" (func $slice-unicode)) ;; CHECK: (func $eq-no (type $0) (result i32) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) (func $eq-no (result i32) (string.eq (string.const "ab") (string.const "cdefg") ) ) ;; CHECK: (func $eq-yes (type $0) (result i32) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $eq-yes (result i32) (string.eq (string.const "ab") (string.const "ab") ) ) ;; CHECK: (func $concat (type $0) (result i32) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $concat (result i32) (string.eq (string.concat (string.const "a") (string.const "b")) (string.const "ab") ) ) ;; CHECK: (func $concat-surrogates (type $0) (result i32) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $concat-surrogates (result i32) (string.eq ;; Concatenating these surrogates creates '𐍈', which has a different UTF-8 encoding. (string.concat (string.const "\ED\A0\80") (string.const "\ED\BD\88")) (string.const "\F0\90\8D\88") ) ) ;; CHECK: (func $length (type $0) (result i32) ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) (func $length (result i32) (string.measure_wtf16 (string.const "1234567") ) ) ;; CHECK: (func $length-unicode (type $0) (result i32) ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) (func $length-unicode (result i32) (string.measure_wtf16 ;; $_£_€_𐍈 (the last character is encoded as a surrogate pair) (string.const "$_\C2\A3_\E2\82\AC_\F0\90\8D\88") ) ) ;; CHECK: (func $get_codepoint (type $0) (result i32) ;; CHECK-NEXT: (i32.const 95) ;; CHECK-NEXT: ) (func $get_codepoint (result i32) ;; Returns 95 ('_'). (stringview_wtf16.get_codeunit ;; $_£_€_𐍈 (string.const "$_\C2\A3_\E2\82\AC_\F0\90\8D\88") (i32.const 1) ) ) ;; CHECK: (func $get_codepoint-unicode (type $0) (result i32) ;; CHECK-NEXT: (i32.const 8364) ;; CHECK-NEXT: ) (func $get_codepoint-unicode (export "get_codepoint-unicode") (result i32) ;; Returns 8364 ('€') (stringview_wtf16.get_codeunit ;; $_£_€_𐍈 (string.const "$_\C2\A3_\E2\82\AC_\F0\90\8D\88") (i32.const 4) ) ) ;; CHECK: (func $get_codepoint-surrogate (type $0) (result i32) ;; CHECK-NEXT: (i32.const 55296) ;; CHECK-NEXT: ) (func $get_codepoint-surrogate (export "get_codepoint-surrogate") (result i32) ;; Returns 0xd800 (the high surrogate in '𐍈') (stringview_wtf16.get_codeunit ;; $_£_€_𐍈 (string.const "$_\C2\A3_\E2\82\AC_\F0\90\8D\88") (i32.const 6) ) ) ;; CHECK: (func $encode (type $0) (result i32) ;; CHECK-NEXT: (string.encode_wtf16_array ;; CHECK-NEXT: (string.const "$_") ;; CHECK-NEXT: (array.new_default $array16 ;; CHECK-NEXT: (i32.const 20) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $encode (result i32) ;; We could optimize away the encode operation here as the reference does not ;; escape, but we do not do escape analysis here. (string.encode_wtf16_array (string.const "$_") (array.new_default $array16 (i32.const 20) ) (i32.const 0) ) ) ;; CHECK: (func $encode-unicode (type $0) (result i32) ;; CHECK-NEXT: (string.encode_wtf16_array ;; CHECK-NEXT: (string.const "$_\c2\a3_\e2\82\ac_\f0\90\8d\88") ;; CHECK-NEXT: (array.new_default $array16 ;; CHECK-NEXT: (i32.const 20) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $encode-unicode (result i32) (string.encode_wtf16_array ;; $_£_€_𐍈 (string.const "$_\C2\A3_\E2\82\AC_\F0\90\8D\88") (array.new_default $array16 (i32.const 20) ) (i32.const 0) ) ) ;; CHECK: (func $encode-stashed (type $4) (result (ref any)) ;; CHECK-NEXT: (local $1 (ref $array16)) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (array.new_default $array16 ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.encode_wtf16_array ;; CHECK-NEXT: (string.const "0123456789") ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) (func $encode-stashed (export "test") (result (ref any)) (local $1 (ref $array16)) ;; Create a zero-filled array. (local.set $1 (array.new_default $array16 (i32.const 10) ) ) ;; Fill it with some string data. (drop (string.encode_wtf16_array (string.const "0123456789") (local.get $1) (i32.const 0) ) ) ;; Return the modified array. We must not have removed the encode operation ;; above us (it has the side effect of modifying the array, just like an ;; array.copy does). (local.get $1) ) ;; CHECK: (func $slice (type $2) (result (ref string)) ;; CHECK-NEXT: (string.const "def") ;; CHECK-NEXT: ) (func $slice (export "slice") (result (ref string)) ;; Slicing [3:6] here should definitely output "def". (stringview_wtf16.slice (string.const "abcdefgh") (i32.const 3) (i32.const 6) ) ) ;; CHECK: (func $slice-unicode (type $2) (result (ref string)) ;; CHECK-NEXT: (string.const "d\c2\a3f") ;; CHECK-NEXT: ) (func $slice-unicode (export "slice-unicode") (result (ref string)) (stringview_wtf16.slice ;; abcd£fgh (string.const "abcd\C2\A3fgh") (i32.const 3) (i32.const 6) ) ) ;; CHECK: (func $string.new-mutable (type $3) (result anyref) ;; CHECK-NEXT: (string.new_wtf16_array ;; CHECK-NEXT: (array.new_fixed $array16 4 ;; CHECK-NEXT: (i32.const 65) ;; CHECK-NEXT: (i32.const 66) ;; CHECK-NEXT: (i32.const 67) ;; CHECK-NEXT: (i32.const 68) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $string.new-mutable (result anyref) ;; We do not precompute this because the array is mutable, and we do not yet ;; do an analysis to see that it does not "escape" into places that modify it. (string.new_wtf16_array (array.new_fixed $array16 4 (i32.const 65) (i32.const 66) (i32.const 67) (i32.const 68) ) (i32.const 0) (i32.const 4) ) ) ;; CHECK: (func $string.new-immutable (type $3) (result anyref) ;; CHECK-NEXT: (string.const "ABCD") ;; CHECK-NEXT: ) (func $string.new-immutable (result anyref) ;; This array is immutable and we can optimize here. (string.new_wtf16_array (array.new_fixed $array16-imm 4 (i32.const 65) (i32.const 66) (i32.const 67) (i32.const 68) ) (i32.const 0) (i32.const 4) ) ) )