[llvm] af8b444 - [VE] Update ISel patterns for select instruction

Kazushi Marukawa via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 19 02:28:32 PDT 2020


Author: Kazushi (Jam) Marukawa
Date: 2020-10-19T18:28:21+09:00
New Revision: af8b444de328b87d404304acb7259304d06b5a36

URL: https://github.com/llvm/llvm-project/commit/af8b444de328b87d404304acb7259304d06b5a36
DIFF: https://github.com/llvm/llvm-project/commit/af8b444de328b87d404304acb7259304d06b5a36.diff

LOG: [VE] Update ISel patterns for select instruction

Add an ISel pattern for fp128 select instruction and optimize generated
code for other types' select. instructions.  Add a regression test also.

Reviewed By: simoll

Differential Revision: https://reviews.llvm.org/D89509

Added: 
    

Modified: 
    llvm/lib/Target/VE/VEInstrInfo.td
    llvm/test/CodeGen/VE/pic_access_static_data.ll
    llvm/test/CodeGen/VE/select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index accea5309cdf..53924395375c 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -1773,6 +1773,7 @@ let Uses = [SX11], hasSideEffects = 1 in
 def GETSTACKTOP : Pseudo<(outs I64:$dst), (ins),
                          "# GET STACK TOP",
                          [(set iPTR:$dst, (GetStackTop))]>;
+
 // SETCC pattern matches
 //
 //   CMP  %tmp, lhs, rhs     ; compare lhs and rhs
@@ -1860,6 +1861,41 @@ def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLE)),
 def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLE)),
           (MINSWSXrr $LHS, $RHS)>;
 
+// Helper classes to construct cmov patterns for the ease.
+//
+//   Hiding INSERT_SUBREG/EXTRACT_SUBREG patterns.
+
+class cmovrr<Instruction INSN> :
+    OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f),
+               (INSN $cond, $comp, $t, $f)>;
+class cmovrm<Instruction INSN, SDNodeXForm MOP = MIMM> :
+    OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f),
+               (INSN $cond, $comp, (MOP $t), $f)>;
+class cmov32rr<Instruction INSN, SubRegIndex sub_oty> :
+    OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f),
+               (EXTRACT_SUBREG
+                   (INSN $cond, $comp,
+                         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_oty),
+                         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_oty)),
+                   sub_oty)>;
+class cmov32rm<Instruction INSN, SubRegIndex sub_oty, SDNodeXForm MOP = MIMM> :
+    OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f),
+               (EXTRACT_SUBREG
+                   (INSN $cond, $comp,
+                         (MOP $t),
+                         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_oty)),
+                   sub_oty)>;
+class cmov128rr<Instruction INSN> :
+    OutPatFrag<(ops node:$cond, node:$comp, node:$t, node:$f),
+               (INSERT_SUBREG
+                 (INSERT_SUBREG (f128 (IMPLICIT_DEF)),
+                   (INSN $cond, $comp,
+                       (EXTRACT_SUBREG $t, sub_odd),
+                       (EXTRACT_SUBREG $f, sub_odd)), sub_odd),
+                 (INSN $cond, $comp,
+                     (EXTRACT_SUBREG $t, sub_even),
+                     (EXTRACT_SUBREG $f, sub_even)), sub_even)>;
+
 // Generic SELECTCC pattern matches
 //
 //   CMP  %tmp, %l, %r       ; compare %l and %r
@@ -1987,25 +2023,36 @@ def : Pat<(f32 (selectcc f64:$l, f64:$r, f32:$t, f32:$f, cond:$cond)),
 //
 //   CMOV.w.ne %res, %tval, %tmp  ; set tval if %tmp is true
 
-def : Pat<(i64 (select i32:$pred, i64:$t, i64:$f)),
-          (CMOVWrr CC_INE, $pred, $t, $f)>;
-
 def : Pat<(i32 (select i32:$pred, i32:$t, i32:$f)),
-          (EXTRACT_SUBREG
-              (CMOVWrr CC_INE, $pred,
-                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
-                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
-              sub_i32)>;
+          (cmov32rr<CMOVWrr, sub_i32> CC_INE, $pred, $t, $f)>;
+def : Pat<(i32 (select i32:$pred, (i32 mimm:$t), i32:$f)),
+          (cmov32rm<CMOVWrm, sub_i32> CC_INE, $pred, $t, $f)>;
+def : Pat<(i32 (select i32:$pred, i32:$t, (i32 mimm:$f))),
+          (cmov32rm<CMOVWrm, sub_i32> CC_IEQ, $pred, $f, $t)>;
 
-def : Pat<(f64 (select i32:$pred, f64:$t, f64:$f)),
-          (CMOVWrr CC_INE, $pred, $t, $f)>;
+def : Pat<(i64 (select i32:$pred, i64:$t, i64:$f)),
+          (cmovrr<CMOVWrr> CC_INE, $pred, $t, $f)>;
+def : Pat<(i64 (select i32:$pred, (i64 mimm:$t), i64:$f)),
+          (cmovrm<CMOVWrm, MIMM> CC_INE, $pred, $t, $f)>;
+def : Pat<(i64 (select i32:$pred, i64:$t, (i64 mimm:$f))),
+          (cmovrm<CMOVWrm, MIMM> CC_IEQ, $pred, $f, $t)>;
 
 def : Pat<(f32 (select i32:$pred, f32:$t, f32:$f)),
-          (EXTRACT_SUBREG
-            (CMOVWrr CC_INE, $pred,
-                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_f32),
-                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
-            sub_f32)>;
+          (cmov32rr<CMOVWrr, sub_f32> CC_INE, $pred, $t, $f)>;
+def : Pat<(f32 (select i32:$pred, (f32 mimmfp:$t), f32:$f)),
+          (cmov32rm<CMOVWrm, sub_f32, MIMMFP> CC_INE, $pred, $t, $f)>;
+def : Pat<(f32 (select i32:$pred, f32:$t, (f32 mimmfp:$f))),
+          (cmov32rm<CMOVWrm, sub_f32, MIMMFP> CC_IEQ, $pred, $f, $t)>;
+
+def : Pat<(f64 (select i32:$pred, f64:$t, f64:$f)),
+          (cmovrr<CMOVWrr> CC_INE, $pred, $t, $f)>;
+def : Pat<(f64 (select i32:$pred, (f64 mimmfp:$t), f64:$f)),
+          (cmovrm<CMOVWrm, MIMMFP> CC_INE, $pred, $t, $f)>;
+def : Pat<(f64 (select i32:$pred, f64:$t, (f64 mimmfp:$f))),
+          (cmovrm<CMOVWrm, MIMMFP> CC_IEQ, $pred, $f, $t)>;
+
+def : Pat<(f128 (select i32:$pred, f128:$t, f128:$f)),
+          (cmov128rr<CMOVWrr> CC_INE, $pred, $t, $f)>;
 
 // bitconvert
 def : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>;

diff  --git a/llvm/test/CodeGen/VE/pic_access_static_data.ll b/llvm/test/CodeGen/VE/pic_access_static_data.ll
index 892aa8465d99..62bb782846d7 100644
--- a/llvm/test/CodeGen/VE/pic_access_static_data.ll
+++ b/llvm/test/CodeGen/VE/pic_access_static_data.ll
@@ -15,9 +15,8 @@ define void @func() {
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s0, src at gotoff_hi(, %s0)
 ; CHECK-NEXT:    ld1b.zx %s0, (%s0, %s15)
-; CHECK-NEXT:    or %s1, 0, (0)1
-; CHECK-NEXT:    lea %s2, 100
-; CHECK-NEXT:    cmov.w.ne %s1, %s2, %s0
+; CHECK-NEXT:    lea %s1, 100
+; CHECK-NEXT:    cmov.w.eq %s1, (0)1, %s0
 ; CHECK-NEXT:    lea %s0, dst at gotoff_lo
 ; CHECK-NEXT:    and %s0, %s0, (32)0
 ; CHECK-NEXT:    lea.sl %s0, dst at gotoff_hi(, %s0)

diff  --git a/llvm/test/CodeGen/VE/select.ll b/llvm/test/CodeGen/VE/select.ll
index f4b97deea725..96fd3df3c3e0 100644
--- a/llvm/test/CodeGen/VE/select.ll
+++ b/llvm/test/CodeGen/VE/select.ll
@@ -1,29 +1,135 @@
-; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+; RUN: llc < %s -mtriple=ve | FileCheck %s
 
-define double @selectf64(i1 zeroext, double, double) {
-; CHECK-LABEL: selectf64:
+;;; Test ‘select’ instruction
+;;;
+;;; Syntax:
+;;;   <result> = select [fast-math flags] selty <cond>, <ty> <val1>, <ty> <val2>
+;;;                                             ; yields ty
+;;;
+;;;   selty is either i1 or {<N x i1>}
+;;;
+;;; Overview:
+;;;   The ‘select’ instruction is used to choose one value based on a condition,
+;;;   without IR-level branching.
+;;;
+;;; Arguments:
+;;;   The ‘select’ instruction requires an ‘i1’ value or a vector of ‘i1’ values
+;;;   indicating the condition, and two values of the same first class type.
+;;;
+;;;   The optional fast-math flags marker indicates that the select has one or
+;;;   more fast-math flags. These are optimization hints to enable otherwise
+;;;   unsafe floating-point optimizations. Fast-math flags are only valid for
+;;;   selects that return a floating-point scalar or vector type, or an array
+;;;   (nested to any depth) of floating-point scalar or vector types.
+;;;
+;;; Semantics:
+;;;   If the condition is an i1 and it evaluates to 1, the instruction returns
+;;;   the first value argument; otherwise, it returns the second value argument.
+;;;
+;;;   If the condition is a vector of i1, then the value arguments must be
+;;;   vectors of the same size, and the selection is done element by element.
+;;;
+;;;   If the condition is an i1 and the value arguments are vectors of the same
+;;;   size, then an entire vector is selected.
+;;;
+;;; Example:
+;;;   %X = select i1 true, i8 17, i8 42 ; yields i8:17
+;;;
+;;; Note:
+;;;   We test only i1/i8/u8/i16/u16/i32/u32/i64/u64/i128/u128/float/double/fp128
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i1 @select_i1_var(i1 zeroext %0, i1 zeroext %1, i1 zeroext %2) {
+; CHECK-LABEL: select_i1_var:
 ; CHECK:       .LBB{{[0-9]+}}_2:
-; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
-; CHECK-NEXT:    or %s0, 0, %s2
+; CHECK-NEXT:    adds.w.zx %s0, %s2, (0)1
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %4 = select i1 %0, double %1, double %2
-  ret double %4
+  %4 = select i1 %0, i1 %1, i1 %2
+  ret i1 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i8 @select_i8_var(i1 zeroext %0, i8 signext %1, i8 signext %2) {
+; CHECK-LABEL: select_i8_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i8 %1, i8 %2
+  ret i8 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i8 @select_u8_var(i1 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
+; CHECK-LABEL: select_u8_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i8 %1, i8 %2
+  ret i8 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i16 @select_i16_var(i1 zeroext %0, i16 signext %1, i16 signext %2) {
+; CHECK-LABEL: select_i16_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i16 %1, i16 %2
+  ret i16 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i16 @select_u16_var(i1 zeroext %0, i16 zeroext %1, i16 zeroext %2) {
+; CHECK-LABEL: select_u16_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i16 %1, i16 %2
+  ret i16 %4
 }
 
-define float @selectf32(i1 zeroext, float, float) {
-; CHECK-LABEL: selectf32:
+; Function Attrs: norecurse nounwind readnone
+define signext i32 @select_i32_var(i1 zeroext %0, i32 signext %1, i32 signext %2) {
+; CHECK-LABEL: select_i32_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i32 %1, i32 %2
+  ret i32 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i32 @select_u32_var(i1 zeroext %0, i32 zeroext %1, i32 zeroext %2) {
+; CHECK-LABEL: select_u32_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i32 %1, i32 %2
+  ret i32 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_i64_var(i1 zeroext %0, i64 %1, i64 %2) {
+; CHECK-LABEL: select_i64_var:
 ; CHECK:       .LBB{{[0-9]+}}_2:
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
 ; CHECK-NEXT:    or %s0, 0, %s2
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %4 = select i1 %0, float %1, float %2
-  ret float %4
+  %4 = select i1 %0, i64 %1, i64 %2
+  ret i64 %4
 }
 
-define i64 @selecti64(i1 zeroext, i64, i64) {
-; CHECK-LABEL: selecti64:
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_u64_var(i1 zeroext %0, i64 %1, i64 %2) {
+; CHECK-LABEL: select_u64_var:
 ; CHECK:       .LBB{{[0-9]+}}_2:
 ; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
@@ -33,22 +139,412 @@ define i64 @selecti64(i1 zeroext, i64, i64) {
   ret i64 %4
 }
 
-define i32 @selecti32(i1 zeroext, i32, i32) {
-; CHECK-LABEL: selecti32:
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_i128_var(i1 zeroext %0, i128 %1, i128 %2) {
+; CHECK-LABEL: select_i128_var:
 ; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s3, %s1, %s0
+; CHECK-NEXT:    cmov.w.ne %s4, %s2, %s0
+; CHECK-NEXT:    or %s0, 0, %s3
+; CHECK-NEXT:    or %s1, 0, %s4
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i128 %1, i128 %2
+  ret i128 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_u128_var(i1 zeroext %0, i128 %1, i128 %2) {
+; CHECK-LABEL: select_u128_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s3, %s1, %s0
+; CHECK-NEXT:    cmov.w.ne %s4, %s2, %s0
+; CHECK-NEXT:    or %s0, 0, %s3
+; CHECK-NEXT:    or %s1, 0, %s4
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select i1 %0, i128 %1, i128 %2
+  ret i128 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define float @select_float_var(i1 zeroext %0, float %1, float %2) {
+; CHECK-LABEL: select_float_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
 ; CHECK-NEXT:    or %s0, 0, %s2
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %4 = select i1 %0, i32 %1, i32 %2
-  ret i32 %4
+  %4 = select fast i1 %0, float %1, float %2
+  ret float %4
 }
 
-define zeroext i1 @selecti1(i1 zeroext, i1 zeroext, i1 zeroext) {
-; CHECK-LABEL: selecti1:
+; Function Attrs: norecurse nounwind readnone
+define double @select_double_var(i1 zeroext %0, double %1, double %2) {
+; CHECK-LABEL: select_double_var:
 ; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
 ; CHECK-NEXT:    cmov.w.ne %s2, %s1, %s0
-; CHECK-NEXT:    adds.w.zx %s0, %s2, (0)1
+; CHECK-NEXT:    or %s0, 0, %s2
 ; CHECK-NEXT:    or %s11, 0, %s9
-  %4 = select i1 %0, i1 %1, i1 %2
+  %4 = select fast i1 %0, double %1, double %2
+  ret double %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define fp128 @select_quad_var(i1 zeroext %0, fp128 %1, fp128 %2) {
+; CHECK-LABEL: select_quad_var:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s4, %s2, %s0
+; CHECK-NEXT:    cmov.w.ne %s5, %s3, %s0
+; CHECK-NEXT:    or %s0, 0, %s4
+; CHECK-NEXT:    or %s1, 0, %s5
+; CHECK-NEXT:    or %s11, 0, %s9
+  %4 = select fast i1 %0, fp128 %1, fp128 %2
+  ret fp128 %4
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i1 @select_i1_mimm(i1 zeroext %0, i1 zeroext %1) {
+; CHECK-LABEL: select_i1_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = or i1 %0, %1
+  ret i1 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i8 @select_i8_mimm(i1 zeroext %0, i8 signext %1) {
+; CHECK-LABEL: select_i8_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (57)1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i8 -128, i8 %1
+  ret i8 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i8 @select_u8_mimm(i1 zeroext %0, i8 zeroext %1) {
+; CHECK-LABEL: select_u8_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (57)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i8 127, i8 %1
+  ret i8 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i16 @select_i16_mimm(i1 zeroext %0, i16 signext %1) {
+; CHECK-LABEL: select_i16_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (49)1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i16 -32768, i16 %1
+  ret i16 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i16 @select_u16_mimm(i1 zeroext %0, i16 zeroext %1) {
+; CHECK-LABEL: select_u16_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (49)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i16 32767, i16 %1
+  ret i16 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i32 @select_i32_mimm(i1 zeroext %0, i32 signext %1) {
+; CHECK-LABEL: select_i32_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i32 65535, i32 %1
+  ret i32 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i32 @select_u32_mimm(i1 zeroext %0, i32 zeroext %1) {
+; CHECK-LABEL: select_u32_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i32 65535, i32 %1
+  ret i32 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_i64_mimm(i1 zeroext %0, i64 %1) {
+; CHECK-LABEL: select_i64_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i64 65535, i64 %1
+  ret i64 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_u64_mimm(i1 zeroext %0, i64 %1) {
+; CHECK-LABEL: select_u64_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i64 65535, i64 %1
+  ret i64 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_i128_mimm(i1 zeroext %0, i128 %1) {
+; CHECK-LABEL: select_i128_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    cmov.w.ne %s2, (0)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s1, 0, %s2
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i128 65535, i128 %1
+  ret i128 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_u128_mimm(i1 zeroext %0, i128 %1) {
+; CHECK-LABEL: select_u128_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (48)0, %s0
+; CHECK-NEXT:    cmov.w.ne %s2, (0)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s1, 0, %s2
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i128 65535, i128 %1
+  ret i128 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define float @select_float_mimm(i1 zeroext %0, float %1) {
+; CHECK-LABEL: select_float_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (2)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, float -2.000000e+00, float %1
+  ret float %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define double @select_double_mimm(i1 zeroext %0, double %1) {
+; CHECK-LABEL: select_double_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s1, (2)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select fast i1 %0, double -2.000000e+00, double %1
+  ret double %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define fp128 @select_quad_mimm(i1 zeroext %0, fp128 %1) {
+; CHECK-LABEL: select_quad_mimm:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, .LCPI{{[0-9]+}}_0 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, .LCPI{{[0-9]+}}_0 at hi(, %s1)
+; CHECK-NEXT:    ld %s4, 8(, %s1)
+; CHECK-NEXT:    ld %s5, (, %s1)
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s2, %s4, %s0
+; CHECK-NEXT:    cmov.w.ne %s3, %s5, %s0
+; CHECK-NEXT:    or %s0, 0, %s2
+; CHECK-NEXT:    or %s1, 0, %s3
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select fast i1 %0, fp128 0xL0000000000000000C000000000000000, fp128 %1
+  ret fp128 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i1 @select_mimm_i1(i1 zeroext %0, i1 zeroext %1) {
+; CHECK-LABEL: select_mimm_i1:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    xor %s0, 1, %s0
+; CHECK-NEXT:    or %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = xor i1 %0, true
+  %4 = or i1 %3, %1
   ret i1 %4
 }
+
+; Function Attrs: norecurse nounwind readnone
+define signext i8 @select_mimm_i8(i1 zeroext %0, i8 signext %1) {
+; CHECK-LABEL: select_mimm_i8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (57)1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i8 %1, i8 -128
+  ret i8 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i8 @select_mimm_u8(i1 zeroext %0, i8 zeroext %1) {
+; CHECK-LABEL: select_mimm_u8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (57)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i8 %1, i8 127
+  ret i8 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i16 @select_mimm_i16(i1 zeroext %0, i16 signext %1) {
+; CHECK-LABEL: select_mimm_i16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (49)1, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i16 %1, i16 -32768
+  ret i16 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i16 @select_mimm_u16(i1 zeroext %0, i16 zeroext %1) {
+; CHECK-LABEL: select_mimm_u16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (49)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i16 %1, i16 32767
+  ret i16 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i32 @select_mimm_i32(i1 zeroext %0, i32 signext %1) {
+; CHECK-LABEL: select_mimm_i32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i32 %1, i32 65535
+  ret i32 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i32 @select_mimm_u32(i1 zeroext %0, i32 zeroext %1) {
+; CHECK-LABEL: select_mimm_u32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    adds.w.zx %s0, %s1, (0)1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i32 %1, i32 65535
+  ret i32 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_mimm_i64(i1 zeroext %0, i64 %1) {
+; CHECK-LABEL: select_mimm_i64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i64 %1, i64 65535
+  ret i64 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @select_mimm_u64(i1 zeroext %0, i64 %1) {
+; CHECK-LABEL: select_mimm_u64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i64 %1, i64 65535
+  ret i64 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_mimm_i128(i1 zeroext %0, i128 %1) {
+; CHECK-LABEL: select_mimm_i128:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    cmov.w.eq %s2, (0)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s1, 0, %s2
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i128 %1, i128 65535
+  ret i128 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i128 @select_mimm_u128(i1 zeroext %0, i128 %1) {
+; CHECK-LABEL: select_mimm_u128:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (48)0, %s0
+; CHECK-NEXT:    cmov.w.eq %s2, (0)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s1, 0, %s2
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, i128 %1, i128 65535
+  ret i128 %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define float @select_mimm_float(i1 zeroext %0, float %1) {
+; CHECK-LABEL: select_mimm_float:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (2)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select i1 %0, float %1, float -2.000000e+00
+  ret float %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define double @select_mimm_double(i1 zeroext %0, double %1) {
+; CHECK-LABEL: select_mimm_double:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.eq %s1, (2)1, %s0
+; CHECK-NEXT:    or %s0, 0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select fast i1 %0, double %1, double -2.000000e+00
+  ret double %3
+}
+
+; Function Attrs: norecurse nounwind readnone
+define fp128 @select_mimm_quad(i1 zeroext %0, fp128 %1) {
+; CHECK-LABEL: select_mimm_quad:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, .LCPI{{[0-9]+}}_0 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, .LCPI{{[0-9]+}}_0 at hi(, %s1)
+; CHECK-NEXT:    ld %s4, 8(, %s1)
+; CHECK-NEXT:    ld %s5, (, %s1)
+; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
+; CHECK-NEXT:    cmov.w.ne %s4, %s2, %s0
+; CHECK-NEXT:    cmov.w.ne %s5, %s3, %s0
+; CHECK-NEXT:    or %s0, 0, %s4
+; CHECK-NEXT:    or %s1, 0, %s5
+; CHECK-NEXT:    or %s11, 0, %s9
+  %3 = select fast i1 %0, fp128 %1, fp128 0xL0000000000000000C000000000000000
+  ret fp128 %3
+}


        


More information about the llvm-commits mailing list