Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td @@ -122,3 +122,10 @@ (SELECT_F32 F32:$rhs, F32:$lhs, I32:$cond)>; def : Pat<(select (i32 (seteq I32:$cond, 0)), F64:$lhs, F64:$rhs), (SELECT_F64 F64:$rhs, F64:$lhs, I32:$cond)>; + +// The legalizer inserts an unnecessary `and 1` to make input conform +// to getBooleanContents, which we can lower away. +def : Pat<(select (i32 (and I32:$cond, 1)), F32:$lhs, F32:$rhs), + (SELECT_F32 F32:$lhs, F32:$rhs, I32:$cond)>; +def : Pat<(select (i32 (and I32:$cond, 1)), F64:$lhs, F64:$rhs), + (SELECT_F64 F64:$lhs, F64:$rhs, I32:$cond)>; Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -122,3 +122,10 @@ (SELECT_I32 I32:$rhs, I32:$lhs, I32:$cond)>; def : Pat<(select (i32 (seteq I32:$cond, 0)), I64:$lhs, I64:$rhs), (SELECT_I64 I64:$rhs, I64:$lhs, I32:$cond)>; + +// The legalizer inserts an unnecessary `and 1` to make input conform +// to getBooleanContents, which we can lower away. +def : Pat<(select (i32 (and I32:$cond, 1)), I32:$lhs, I32:$rhs), + (SELECT_I32 I32:$lhs, I32:$rhs, I32:$cond)>; +def : Pat<(select (i32 (and I32:$cond, 1)), I64:$lhs, I64:$rhs), + (SELECT_I64 I64:$lhs, I64:$rhs, I32:$cond)>; Index: llvm/trunk/test/CodeGen/WebAssembly/select.ll =================================================================== --- llvm/trunk/test/CodeGen/WebAssembly/select.ll +++ llvm/trunk/test/CodeGen/WebAssembly/select.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes CHECK,SLOW ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel -fast-isel-abort=1 | FileCheck %s ; Test that wasm select instruction is selected from LLVM select instruction. @@ -16,6 +16,16 @@ ret i32 %cond } +; CHECK-LABEL: select_i32_bool_nozext: +; CHECK-NEXT: .param i32, i32, i32{{$}} +; CHECK-NEXT: .result i32{{$}} +; SLOW-NEXT: i32.select $push0=, $1, $2, $0{{$}} +; SLOW-NEXT: return $pop0{{$}} +define i32 @select_i32_bool_nozext(i1 %a, i32 %b, i32 %c) { + %cond = select i1 %a, i32 %b, i32 %c + ret i32 %cond +} + ; CHECK-LABEL: select_i32_eq: ; CHECK-NEXT: .param i32, i32, i32{{$}} ; CHECK-NEXT: .result i32{{$}} @@ -48,6 +58,16 @@ ret i64 %cond } +; CHECK-LABEL: select_i64_bool_nozext: +; CHECK-NEXT: .param i32, i64, i64{{$}} +; CHECK-NEXT: .result i64{{$}} +; SLOW-NEXT: i64.select $push0=, $1, $2, $0{{$}} +; SLOW-NEXT: return $pop0{{$}} +define i64 @select_i64_bool_nozext(i1 %a, i64 %b, i64 %c) { + %cond = select i1 %a, i64 %b, i64 %c + ret i64 %cond +} + ; CHECK-LABEL: select_i64_eq: ; CHECK-NEXT: .param i32, i64, i64{{$}} ; CHECK-NEXT: .result i64{{$}} @@ -80,6 +100,16 @@ ret float %cond } +; CHECK-LABEL: select_f32_bool_nozext: +; CHECK-NEXT: .param i32, f32, f32{{$}} +; CHECK-NEXT: .result f32{{$}} +; SLOW-NEXT: f32.select $push0=, $1, $2, $0{{$}} +; SLOW-NEXT: return $pop0{{$}} +define float @select_f32_bool_nozext(i1 %a, float %b, float %c) { + %cond = select i1 %a, float %b, float %c + ret float %cond +} + ; CHECK-LABEL: select_f32_eq: ; CHECK-NEXT: .param i32, f32, f32{{$}} ; CHECK-NEXT: .result f32{{$}} @@ -112,6 +142,16 @@ ret double %cond } +; CHECK-LABEL: select_f64_bool_nozext: +; CHECK-NEXT: .param i32, f64, f64{{$}} +; CHECK-NEXT: .result f64{{$}} +; SLOW-NEXT: f64.select $push0=, $1, $2, $0{{$}} +; SLOW-NEXT: return $pop0{{$}} +define double @select_f64_bool_nozext(i1 %a, double %b, double %c) { + %cond = select i1 %a, double %b, double %c + ret double %cond +} + ; CHECK-LABEL: select_f64_eq: ; CHECK-NEXT: .param i32, f64, f64{{$}} ; CHECK-NEXT: .result f64{{$}}