1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -O0 | FileCheck %s 3; RUN: llc -fast-isel=false < %s -O0 | FileCheck %s -check-prefixes NO-FAST-ISEL 4 5target triple = "wasm32-unknown-unknown" 6 7 8declare i32 @foo(i1 signext noundef, i32 noundef) 9 10; callsite_signext and callsite_nosignext must emit equivalent codes 11 12define i32 @callsite_nosignext() { 13; CHECK-LABEL: callsite_nosignext: 14; CHECK: .functype callsite_nosignext () -> (i32) 15; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32 16; CHECK-NEXT: # %bb.0: # %start 17; CHECK-NEXT: i32.const 1 18; CHECK-NEXT: local.set 0 19; CHECK-NEXT: i32.const 0 20; CHECK-NEXT: local.set 1 21; CHECK-NEXT: i32.const 31 22; CHECK-NEXT: local.set 2 23; CHECK-NEXT: local.get 0 24; CHECK-NEXT: local.get 2 25; CHECK-NEXT: i32.shl 26; CHECK-NEXT: local.set 3 27; CHECK-NEXT: local.get 3 28; CHECK-NEXT: local.get 2 29; CHECK-NEXT: i32.shr_s 30; CHECK-NEXT: local.set 4 31; CHECK-NEXT: local.get 4 32; CHECK-NEXT: local.get 1 33; CHECK-NEXT: call foo 34; CHECK-NEXT: local.set 5 35; CHECK-NEXT: local.get 5 36; CHECK-NEXT: return 37; 38; NO-FAST-ISEL-LABEL: callsite_nosignext: 39; NO-FAST-ISEL: .functype callsite_nosignext () -> (i32) 40; NO-FAST-ISEL-NEXT: .local i32, i32, i32 41; NO-FAST-ISEL-NEXT: # %bb.0: # %start 42; NO-FAST-ISEL-NEXT: i32.const 0 43; NO-FAST-ISEL-NEXT: local.set 0 44; NO-FAST-ISEL-NEXT: i32.const -1 45; NO-FAST-ISEL-NEXT: local.set 1 46; NO-FAST-ISEL-NEXT: local.get 1 47; NO-FAST-ISEL-NEXT: local.get 0 48; NO-FAST-ISEL-NEXT: call foo 49; NO-FAST-ISEL-NEXT: local.set 2 50; NO-FAST-ISEL-NEXT: local.get 2 51; NO-FAST-ISEL-NEXT: return 52start: 53 %0 = call i32 @foo(i1 1, i32 0) 54 ret i32 %0 55} 56 57define i32 @callsite_signext() { 58; CHECK-LABEL: callsite_signext: 59; CHECK: .functype callsite_signext () -> (i32) 60; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32 61; CHECK-NEXT: # %bb.0: # %start 62; CHECK-NEXT: i32.const 1 63; CHECK-NEXT: local.set 0 64; CHECK-NEXT: i32.const 0 65; CHECK-NEXT: local.set 1 66; CHECK-NEXT: i32.const 31 67; CHECK-NEXT: local.set 2 68; CHECK-NEXT: local.get 0 69; CHECK-NEXT: local.get 2 70; CHECK-NEXT: i32.shl 71; CHECK-NEXT: local.set 3 72; CHECK-NEXT: local.get 3 73; CHECK-NEXT: local.get 2 74; CHECK-NEXT: i32.shr_s 75; CHECK-NEXT: local.set 4 76; CHECK-NEXT: local.get 4 77; CHECK-NEXT: local.get 1 78; CHECK-NEXT: call foo 79; CHECK-NEXT: local.set 5 80; CHECK-NEXT: local.get 5 81; CHECK-NEXT: return 82; 83; NO-FAST-ISEL-LABEL: callsite_signext: 84; NO-FAST-ISEL: .functype callsite_signext () -> (i32) 85; NO-FAST-ISEL-NEXT: .local i32, i32, i32 86; NO-FAST-ISEL-NEXT: # %bb.0: # %start 87; NO-FAST-ISEL-NEXT: i32.const 0 88; NO-FAST-ISEL-NEXT: local.set 0 89; NO-FAST-ISEL-NEXT: i32.const -1 90; NO-FAST-ISEL-NEXT: local.set 1 91; NO-FAST-ISEL-NEXT: local.get 1 92; NO-FAST-ISEL-NEXT: local.get 0 93; NO-FAST-ISEL-NEXT: call foo 94; NO-FAST-ISEL-NEXT: local.set 2 95; NO-FAST-ISEL-NEXT: local.get 2 96; NO-FAST-ISEL-NEXT: return 97start: 98 %0 = call i32 @foo(i1 signext 1, i32 0) 99 ret i32 %0 100} 101 102declare i32 @foo2(i1 zeroext noundef, i32 noundef) 103 104; callsite_zeroext and callsite_nozeroext must emit equivalent codes 105 106define i32 @callsite_nozeroext() { 107; CHECK-LABEL: callsite_nozeroext: 108; CHECK: .functype callsite_nozeroext () -> (i32) 109; CHECK-NEXT: .local i32, i32, i32, i32, i32 110; CHECK-NEXT: # %bb.0: # %start 111; CHECK-NEXT: i32.const 1 112; CHECK-NEXT: local.set 0 113; CHECK-NEXT: i32.const 0 114; CHECK-NEXT: local.set 1 115; CHECK-NEXT: i32.const 1 116; CHECK-NEXT: local.set 2 117; CHECK-NEXT: local.get 0 118; CHECK-NEXT: local.get 2 119; CHECK-NEXT: i32.and 120; CHECK-NEXT: local.set 3 121; CHECK-NEXT: local.get 3 122; CHECK-NEXT: local.get 1 123; CHECK-NEXT: call foo2 124; CHECK-NEXT: local.set 4 125; CHECK-NEXT: local.get 4 126; CHECK-NEXT: return 127; 128; NO-FAST-ISEL-LABEL: callsite_nozeroext: 129; NO-FAST-ISEL: .functype callsite_nozeroext () -> (i32) 130; NO-FAST-ISEL-NEXT: .local i32, i32, i32 131; NO-FAST-ISEL-NEXT: # %bb.0: # %start 132; NO-FAST-ISEL-NEXT: i32.const 0 133; NO-FAST-ISEL-NEXT: local.set 0 134; NO-FAST-ISEL-NEXT: i32.const 1 135; NO-FAST-ISEL-NEXT: local.set 1 136; NO-FAST-ISEL-NEXT: local.get 1 137; NO-FAST-ISEL-NEXT: local.get 0 138; NO-FAST-ISEL-NEXT: call foo2 139; NO-FAST-ISEL-NEXT: local.set 2 140; NO-FAST-ISEL-NEXT: local.get 2 141; NO-FAST-ISEL-NEXT: return 142start: 143 %0 = call i32 @foo2(i1 1, i32 0) 144 ret i32 %0 145} 146 147define i32 @callsite_zeroext() { 148; CHECK-LABEL: callsite_zeroext: 149; CHECK: .functype callsite_zeroext () -> (i32) 150; CHECK-NEXT: .local i32, i32, i32, i32, i32 151; CHECK-NEXT: # %bb.0: # %start 152; CHECK-NEXT: i32.const 1 153; CHECK-NEXT: local.set 0 154; CHECK-NEXT: i32.const 0 155; CHECK-NEXT: local.set 1 156; CHECK-NEXT: i32.const 1 157; CHECK-NEXT: local.set 2 158; CHECK-NEXT: local.get 0 159; CHECK-NEXT: local.get 2 160; CHECK-NEXT: i32.and 161; CHECK-NEXT: local.set 3 162; CHECK-NEXT: local.get 3 163; CHECK-NEXT: local.get 1 164; CHECK-NEXT: call foo2 165; CHECK-NEXT: local.set 4 166; CHECK-NEXT: local.get 4 167; CHECK-NEXT: return 168; 169; NO-FAST-ISEL-LABEL: callsite_zeroext: 170; NO-FAST-ISEL: .functype callsite_zeroext () -> (i32) 171; NO-FAST-ISEL-NEXT: .local i32, i32, i32 172; NO-FAST-ISEL-NEXT: # %bb.0: # %start 173; NO-FAST-ISEL-NEXT: i32.const 0 174; NO-FAST-ISEL-NEXT: local.set 0 175; NO-FAST-ISEL-NEXT: i32.const 1 176; NO-FAST-ISEL-NEXT: local.set 1 177; NO-FAST-ISEL-NEXT: local.get 1 178; NO-FAST-ISEL-NEXT: local.get 0 179; NO-FAST-ISEL-NEXT: call foo2 180; NO-FAST-ISEL-NEXT: local.set 2 181; NO-FAST-ISEL-NEXT: local.get 2 182; NO-FAST-ISEL-NEXT: return 183start: 184 %0 = call i32 @foo2(i1 zeroext 1, i32 0) 185 ret i32 %0 186} 187