]> granicus.if.org Git - clang/commitdiff
[SystemZ] Add support for z13 low-level vector builtins
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 5 May 2015 19:36:42 +0000 (19:36 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 5 May 2015 19:36:42 +0000 (19:36 +0000)
This adds low-level builtins to allow access to all of the z13 vector
instructions.  Note that instructions whose semantics can be described
by standard C (including clang extensions) do not get any builtins.

For each instructions whose semantics *cannot* (fully) be described, we
define a builtin named __builtin_s390_<insn> that directly maps to this
instruction.  These are intended to be compatible with GCC.

For instructions that also set the condition code, the builtin will take
an extra argument of type "int *" at the end.  The integer pointed to by
this argument will be set to the post-instruction CC value.

For many instructions, the low-level builtin is mapped to the corresponding
LLVM IR intrinsic.  However, a number of instructions can be represented
in standard LLVM IR without requiring use of a target intrinsic.

Some instructions require immediate integer operands within a certain
range.  Those are verified at the Sema level.

Based on a patch by Richard Sandiford.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236532 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/BuiltinsSystemZ.def
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaChecking.cpp
test/CodeGen/builtins-systemz-vector-error.c [new file with mode: 0644]
test/CodeGen/builtins-systemz-vector.c [new file with mode: 0644]

index 613e9de9d75a2af154f4f2c1044383613524fc5a..68d5a1c9440733919d1a1016f60fcdc845d08e65 100644 (file)
@@ -24,4 +24,229 @@ BUILTIN(__builtin_tx_nesting_depth, "i", "nc")
 BUILTIN(__builtin_tx_assist, "vi", "n")
 BUILTIN(__builtin_non_tx_store, "vULi*ULi", "")
 
+// Vector intrinsics.
+// These all map directly to z instructions, except that some variants ending
+// in "s" have a final "int *" that receives the post-instruction CC value.
+
+// Vector support instructions (chapter 21 of the PoP)
+BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc")
+BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "")
+BUILTIN(__builtin_s390_vll, "V16ScUivC*", "")
+BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "")
+BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc")
+BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc")
+BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc")
+BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc")
+BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc")
+BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc")
+BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc")
+BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc")
+BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc")
+BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc")
+BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc")
+BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc")
+BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc")
+BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc")
+BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc")
+BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc")
+BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc")
+BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc")
+
+// Vector integer instructions (chapter 22 of the PoP)
+BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc")
+BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc")
+BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc")
+BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc")
+BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc")
+BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc")
+BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc")
+BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc")
+BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc")
+BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc")
+BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc")
+BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc")
+BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc")
+BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc")
+BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc")
+BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc")
+BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc")
+BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc")
+BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc")
+BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc")
+BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc")
+BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc")
+BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc")
+BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc")
+BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc")
+BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc")
+BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc")
+BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc")
+BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc")
+BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc")
+BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc")
+BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc")
+BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc")
+
+// Vector string instructions (chapter 23 of the PoP)
+BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc")
+BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc")
+BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc")
+BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc")
+BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc")
+BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc")
+BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc")
+BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc")
+BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc")
+BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc")
+BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc")
+BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc")
+BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc")
+BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc")
+BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc")
+BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc")
+BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc")
+BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc")
+BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc")
+BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc")
+BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc")
+BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc")
+BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc")
+BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc")
+BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc")
+BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc")
+BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc")
+
+// Vector floating-point instructions (chapter 24 of the PoP)
+BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc")
+BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc")
+BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc")
+BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc")
+BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc")
+BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc")
+BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc")
+BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc")
+BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc")
+BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc")
+
 #undef BUILTIN
index 2653d7cd1a74e3db9168d5bb361efe5c7cc008fc..3e5c1d3b949df1b7d1e56bbf6d29f769f8f15f9c 100644 (file)
@@ -6478,6 +6478,24 @@ Value *CodeGenFunction::EmitR600BuiltinExpr(unsigned BuiltinID,
   }
 }
 
+/// Handle a SystemZ function in which the final argument is a pointer
+/// to an int that receives the post-instruction CC value.  At the LLVM level
+/// this is represented as a function that returns a {result, cc} pair.
+static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
+                                         unsigned IntrinsicID,
+                                         const CallExpr *E) {
+  unsigned NumArgs = E->getNumArgs() - 1;
+  SmallVector<Value *, 8> Args(NumArgs);
+  for (unsigned I = 0; I < NumArgs; ++I)
+    Args[I] = CGF.EmitScalarExpr(E->getArg(I));
+  Value *CCPtr = CGF.EmitScalarExpr(E->getArg(NumArgs));
+  Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
+  Value *Call = CGF.Builder.CreateCall(F, Args);
+  Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
+  CGF.Builder.CreateStore(CC, CCPtr);
+  return CGF.Builder.CreateExtractValue(Call, 0);
+}
+
 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
                                                const CallExpr *E) {
   switch (BuiltinID) {
@@ -6511,6 +6529,193 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall2(F, Data, Address);
   }
 
+  // Vector builtins.  Note that most vector builtins are mapped automatically
+  // to target-specific LLVM intrinsics.  The ones handled specially here can
+  // be represented via standard LLVM IR, which is preferable to enable common
+  // LLVM optimizations.
+
+  case SystemZ::BI__builtin_s390_vpopctb:
+  case SystemZ::BI__builtin_s390_vpopcth:
+  case SystemZ::BI__builtin_s390_vpopctf:
+  case SystemZ::BI__builtin_s390_vpopctg: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
+    return Builder.CreateCall(F, X);
+  }
+
+  case SystemZ::BI__builtin_s390_vclzb:
+  case SystemZ::BI__builtin_s390_vclzh:
+  case SystemZ::BI__builtin_s390_vclzf:
+  case SystemZ::BI__builtin_s390_vclzg: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
+    return Builder.CreateCall2(F, X, Undef);
+  }
+
+  case SystemZ::BI__builtin_s390_vctzb:
+  case SystemZ::BI__builtin_s390_vctzh:
+  case SystemZ::BI__builtin_s390_vctzf:
+  case SystemZ::BI__builtin_s390_vctzg: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
+    Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
+    return Builder.CreateCall2(F, X, Undef);
+  }
+
+  case SystemZ::BI__builtin_s390_vfsqdb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
+    return Builder.CreateCall(F, X);
+  }
+  case SystemZ::BI__builtin_s390_vfmadb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Value *Y = EmitScalarExpr(E->getArg(1));
+    Value *Z = EmitScalarExpr(E->getArg(2));
+    Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+    return Builder.CreateCall3(F, X, Y, Z);
+  }
+  case SystemZ::BI__builtin_s390_vfmsdb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Value *Y = EmitScalarExpr(E->getArg(1));
+    Value *Z = EmitScalarExpr(E->getArg(2));
+    Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+    Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+    return Builder.CreateCall3(F, X, Y, Builder.CreateFSub(Zero, Z, "sub"));
+  }
+  case SystemZ::BI__builtin_s390_vflpdb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
+    return Builder.CreateCall(F, X);
+  }
+  case SystemZ::BI__builtin_s390_vflndb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+    Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
+    return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
+  }
+  case SystemZ::BI__builtin_s390_vfidb: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *X = EmitScalarExpr(E->getArg(0));
+    // Constant-fold the M4 and M5 mask arguments.
+    llvm::APSInt M4, M5;
+    bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext());
+    bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
+    assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
+    (void)IsConstM4; (void)IsConstM5;
+    // Check whether this instance of vfidb can be represented via a LLVM
+    // standard intrinsic.  We only support some combinations of M4 and M5.
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+    switch (M4.getZExtValue()) {
+    default: break;
+    case 0:  // IEEE-inexact exception allowed
+      switch (M5.getZExtValue()) {
+      default: break;
+      case 0: ID = Intrinsic::rint; break;
+      }
+      break;
+    case 4:  // IEEE-inexact exception suppressed
+      switch (M5.getZExtValue()) {
+      default: break;
+      case 0: ID = Intrinsic::nearbyint; break;
+      case 1: ID = Intrinsic::round; break;
+      case 5: ID = Intrinsic::trunc; break;
+      case 6: ID = Intrinsic::ceil; break;
+      case 7: ID = Intrinsic::floor; break;
+      }
+      break;
+    }
+    if (ID != Intrinsic::not_intrinsic) {
+      Function *F = CGM.getIntrinsic(ID, ResultType);
+      return Builder.CreateCall(F, X);
+    }
+    Function *F = CGM.getIntrinsic(Intrinsic::s390_vfidb);
+    Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
+    Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
+    return Builder.CreateCall3(F, X, M4Value, M5Value);
+  }
+
+  // Vector intrisincs that output the post-instruction CC value.
+
+#define INTRINSIC_WITH_CC(NAME) \
+    case SystemZ::BI__builtin_##NAME: \
+      return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E)
+
+  INTRINSIC_WITH_CC(s390_vpkshs);
+  INTRINSIC_WITH_CC(s390_vpksfs);
+  INTRINSIC_WITH_CC(s390_vpksgs);
+
+  INTRINSIC_WITH_CC(s390_vpklshs);
+  INTRINSIC_WITH_CC(s390_vpklsfs);
+  INTRINSIC_WITH_CC(s390_vpklsgs);
+
+  INTRINSIC_WITH_CC(s390_vceqbs);
+  INTRINSIC_WITH_CC(s390_vceqhs);
+  INTRINSIC_WITH_CC(s390_vceqfs);
+  INTRINSIC_WITH_CC(s390_vceqgs);
+
+  INTRINSIC_WITH_CC(s390_vchbs);
+  INTRINSIC_WITH_CC(s390_vchhs);
+  INTRINSIC_WITH_CC(s390_vchfs);
+  INTRINSIC_WITH_CC(s390_vchgs);
+
+  INTRINSIC_WITH_CC(s390_vchlbs);
+  INTRINSIC_WITH_CC(s390_vchlhs);
+  INTRINSIC_WITH_CC(s390_vchlfs);
+  INTRINSIC_WITH_CC(s390_vchlgs);
+
+  INTRINSIC_WITH_CC(s390_vfaebs);
+  INTRINSIC_WITH_CC(s390_vfaehs);
+  INTRINSIC_WITH_CC(s390_vfaefs);
+
+  INTRINSIC_WITH_CC(s390_vfaezbs);
+  INTRINSIC_WITH_CC(s390_vfaezhs);
+  INTRINSIC_WITH_CC(s390_vfaezfs);
+
+  INTRINSIC_WITH_CC(s390_vfeebs);
+  INTRINSIC_WITH_CC(s390_vfeehs);
+  INTRINSIC_WITH_CC(s390_vfeefs);
+
+  INTRINSIC_WITH_CC(s390_vfeezbs);
+  INTRINSIC_WITH_CC(s390_vfeezhs);
+  INTRINSIC_WITH_CC(s390_vfeezfs);
+
+  INTRINSIC_WITH_CC(s390_vfenebs);
+  INTRINSIC_WITH_CC(s390_vfenehs);
+  INTRINSIC_WITH_CC(s390_vfenefs);
+
+  INTRINSIC_WITH_CC(s390_vfenezbs);
+  INTRINSIC_WITH_CC(s390_vfenezhs);
+  INTRINSIC_WITH_CC(s390_vfenezfs);
+
+  INTRINSIC_WITH_CC(s390_vistrbs);
+  INTRINSIC_WITH_CC(s390_vistrhs);
+  INTRINSIC_WITH_CC(s390_vistrfs);
+
+  INTRINSIC_WITH_CC(s390_vstrcbs);
+  INTRINSIC_WITH_CC(s390_vstrchs);
+  INTRINSIC_WITH_CC(s390_vstrcfs);
+
+  INTRINSIC_WITH_CC(s390_vstrczbs);
+  INTRINSIC_WITH_CC(s390_vstrczhs);
+  INTRINSIC_WITH_CC(s390_vstrczfs);
+
+  INTRINSIC_WITH_CC(s390_vfcedbs);
+  INTRINSIC_WITH_CC(s390_vfchdbs);
+  INTRINSIC_WITH_CC(s390_vfchedbs);
+
+  INTRINSIC_WITH_CC(s390_vftcidb);
+
+#undef INTRINSIC_WITH_CC
+
   default:
     return nullptr;
   }
index fd91c77bf12a7998f72e65469659bb479e3d709c..48c276eb09b9e5b7d0fddd9ca44170c53912d71c 100644 (file)
@@ -959,7 +959,49 @@ bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID,
              << Arg->getSourceRange();
   }
 
-  return false;
+  // For intrinsics which take an immediate value as part of the instruction,
+  // range check them here.
+  unsigned i = 0, l = 0, u = 0;
+  switch (BuiltinID) {
+  default: return false;
+  case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break;
+  case SystemZ::BI__builtin_s390_verimb:
+  case SystemZ::BI__builtin_s390_verimh:
+  case SystemZ::BI__builtin_s390_verimf:
+  case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break;
+  case SystemZ::BI__builtin_s390_vfaeb:
+  case SystemZ::BI__builtin_s390_vfaeh:
+  case SystemZ::BI__builtin_s390_vfaef:
+  case SystemZ::BI__builtin_s390_vfaebs:
+  case SystemZ::BI__builtin_s390_vfaehs:
+  case SystemZ::BI__builtin_s390_vfaefs:
+  case SystemZ::BI__builtin_s390_vfaezb:
+  case SystemZ::BI__builtin_s390_vfaezh:
+  case SystemZ::BI__builtin_s390_vfaezf:
+  case SystemZ::BI__builtin_s390_vfaezbs:
+  case SystemZ::BI__builtin_s390_vfaezhs:
+  case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break;
+  case SystemZ::BI__builtin_s390_vfidb:
+    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15) ||
+           SemaBuiltinConstantArgRange(TheCall, 2, 0, 15);
+  case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break;
+  case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break;
+  case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break;
+  case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break;
+  case SystemZ::BI__builtin_s390_vstrcb:
+  case SystemZ::BI__builtin_s390_vstrch:
+  case SystemZ::BI__builtin_s390_vstrcf:
+  case SystemZ::BI__builtin_s390_vstrczb:
+  case SystemZ::BI__builtin_s390_vstrczh:
+  case SystemZ::BI__builtin_s390_vstrczf:
+  case SystemZ::BI__builtin_s390_vstrcbs:
+  case SystemZ::BI__builtin_s390_vstrchs:
+  case SystemZ::BI__builtin_s390_vstrcfs:
+  case SystemZ::BI__builtin_s390_vstrczbs:
+  case SystemZ::BI__builtin_s390_vstrczhs:
+  case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break;
+  }
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u);
 }
 
 bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
diff --git a/test/CodeGen/builtins-systemz-vector-error.c b/test/CodeGen/builtins-systemz-vector-error.c
new file mode 100644 (file)
index 0000000..6f4ecc2
--- /dev/null
@@ -0,0 +1,174 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z13 -triple s390x-unknown-unknown \
+// RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s
+
+typedef __attribute__((vector_size(16))) signed char vec_schar;
+typedef __attribute__((vector_size(16))) signed short vec_sshort;
+typedef __attribute__((vector_size(16))) signed int vec_sint;
+typedef __attribute__((vector_size(16))) signed long long vec_slong;
+typedef __attribute__((vector_size(16))) unsigned char vec_uchar;
+typedef __attribute__((vector_size(16))) unsigned short vec_ushort;
+typedef __attribute__((vector_size(16))) unsigned int vec_uint;
+typedef __attribute__((vector_size(16))) unsigned long long vec_ulong;
+typedef __attribute__((vector_size(16))) double vec_double;
+
+volatile vec_schar vsc;
+volatile vec_sshort vss;
+volatile vec_sint vsi;
+volatile vec_slong vsl;
+volatile vec_uchar vuc;
+volatile vec_ushort vus;
+volatile vec_uint vui;
+volatile vec_ulong vul;
+volatile vec_double vd;
+
+volatile unsigned int len;
+const void * volatile cptr;
+int cc;
+
+void test_core(void) {
+  __builtin_s390_lcbb(cptr, -1);       // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_lcbb(cptr, 16);       // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_lcbb(cptr, len);      // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vlbb(cptr, -1);       // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vlbb(cptr, 16);       // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vlbb(cptr, len);      // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vpdi(vul, vul, -1);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vpdi(vul, vul, 16);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vpdi(vul, vul, len);  // expected-error {{must be a constant integer}}
+}
+
+void test_integer(void) {
+  __builtin_s390_verimb(vuc, vuc, vuc, -1);    // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimb(vuc, vuc, vuc, 256);   // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimb(vuc, vuc, vuc, len);   // expected-error {{must be a constant integer}}
+
+  __builtin_s390_verimh(vus, vus, vus, -1);    // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimh(vus, vus, vus, 256);   // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimh(vus, vus, vus, len);   // expected-error {{must be a constant integer}}
+
+  __builtin_s390_verimf(vui, vui, vui, -1);    // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimf(vui, vui, vui, 256);   // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimf(vui, vui, vui, len);   // expected-error {{must be a constant integer}}
+
+  __builtin_s390_verimg(vul, vul, vul, -1);    // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimg(vul, vul, vul, 256);   // expected-error {{argument should be a value from 0 to 255}}
+  __builtin_s390_verimg(vul, vul, vul, len);   // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vsldb(vuc, vuc, -1);          // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vsldb(vuc, vuc, 16);          // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vsldb(vuc, vuc, len);         // expected-error {{must be a constant integer}}
+}
+
+void test_string(void) {
+  __builtin_s390_vfaeb(vuc, vuc, -1);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaeb(vuc, vuc, 16);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaeb(vuc, vuc, len);              // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaeh(vus, vus, -1);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaeh(vus, vus, 16);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaeh(vus, vus, len);              // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaef(vui, vui, -1);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaef(vui, vui, 16);               // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaef(vui, vui, len);              // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezb(vuc, vuc, -1);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezb(vuc, vuc, 16);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezb(vuc, vuc, len);             // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezh(vus, vus, -1);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezh(vus, vus, 16);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezh(vus, vus, len);             // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezf(vui, vui, -1);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezf(vui, vui, 16);              // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezf(vui, vui, len);             // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrcb(vuc, vuc, vuc, -1);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcb(vuc, vuc, vuc, 16);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcb(vuc, vuc, vuc, len);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrch(vus, vus, vus, -1);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrch(vus, vus, vus, 16);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrch(vus, vus, vus, len);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrcf(vui, vui, vui, -1);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcf(vui, vui, vui, 16);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcf(vui, vui, vui, len);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczb(vuc, vuc, vuc, -1);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczb(vuc, vuc, vuc, 16);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczb(vuc, vuc, vuc, len);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczh(vus, vus, vus, -1);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczh(vus, vus, vus, 16);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczh(vus, vus, vus, len);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczf(vui, vui, vui, -1);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczf(vui, vui, vui, 16);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczf(vui, vui, vui, len);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaebs(vuc, vuc, -1, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaebs(vuc, vuc, 16, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaebs(vuc, vuc, len, &cc);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaehs(vus, vus, -1, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaehs(vus, vus, 16, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaehs(vus, vus, len, &cc);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaefs(vui, vui, -1, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaefs(vui, vui, 16, &cc);         // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaefs(vui, vui, len, &cc);        // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezbs(vuc, vuc, -1, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezbs(vuc, vuc, 16, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezbs(vuc, vuc, len, &cc);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezhs(vus, vus, -1, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezhs(vus, vus, 16, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezhs(vus, vus, len, &cc);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfaezfs(vui, vui, -1, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezfs(vui, vui, 16, &cc);        // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfaezfs(vui, vui, len, &cc);       // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrcbs(vuc, vuc, vuc, -1, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcbs(vuc, vuc, vuc, 16, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcbs(vuc, vuc, vuc, len, &cc);  // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrchs(vus, vus, vus, -1, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrchs(vus, vus, vus, 16, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrchs(vus, vus, vus, len, &cc);  // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrcfs(vui, vui, vui, -1, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcfs(vui, vui, vui, 16, &cc);   // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrcfs(vui, vui, vui, len, &cc);  // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczbs(vuc, vuc, vuc, -1, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczbs(vuc, vuc, vuc, 16, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczbs(vuc, vuc, vuc, len, &cc); // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczhs(vus, vus, vus, -1, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczhs(vus, vus, vus, 16, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczhs(vus, vus, vus, len, &cc); // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vstrczfs(vui, vui, vui, -1, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczfs(vui, vui, vui, 16, &cc);  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vstrczfs(vui, vui, vui, len, &cc); // expected-error {{must be a constant integer}}
+}
+
+void test_float(void) {
+  __builtin_s390_vftcidb(vd, -1, &cc);              // expected-error {{argument should be a value from 0 to 4095}}
+  __builtin_s390_vftcidb(vd, 4096, &cc);            // expected-error {{argument should be a value from 0 to 4095}}
+  __builtin_s390_vftcidb(vd, len, &cc);             // expected-error {{must be a constant integer}}
+
+  __builtin_s390_vfidb(vd, -1, 0);                  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfidb(vd, 16, 0);                  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfidb(vd, len, 0);                 // expected-error {{must be a constant integer}}
+  __builtin_s390_vfidb(vd, 0, -1);                  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfidb(vd, 0, 16);                  // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_s390_vfidb(vd, 0, len);                 // expected-error {{must be a constant integer}}
+}
diff --git a/test/CodeGen/builtins-systemz-vector.c b/test/CodeGen/builtins-systemz-vector.c
new file mode 100644 (file)
index 0000000..6d94cfa
--- /dev/null
@@ -0,0 +1,610 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z13 -triple s390x-ibm-linux -fno-lax-vector-conversions \
+// RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
+
+typedef __attribute__((vector_size(16))) signed char vec_schar;
+typedef __attribute__((vector_size(16))) signed short vec_sshort;
+typedef __attribute__((vector_size(16))) signed int vec_sint;
+typedef __attribute__((vector_size(16))) signed long long vec_slong;
+typedef __attribute__((vector_size(16))) unsigned char vec_uchar;
+typedef __attribute__((vector_size(16))) unsigned short vec_ushort;
+typedef __attribute__((vector_size(16))) unsigned int vec_uint;
+typedef __attribute__((vector_size(16))) unsigned long long vec_ulong;
+typedef __attribute__((vector_size(16))) double vec_double;
+
+volatile vec_schar vsc;
+volatile vec_sshort vss;
+volatile vec_sint vsi;
+volatile vec_slong vsl;
+volatile vec_uchar vuc;
+volatile vec_ushort vus;
+volatile vec_uint vui;
+volatile vec_ulong vul;
+volatile vec_double vd;
+
+volatile unsigned int len;
+const void * volatile cptr;
+void * volatile ptr;
+int cc;
+
+void test_core(void) {
+  len = __builtin_s390_lcbb(cptr, 0);
+  // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 0)
+  len = __builtin_s390_lcbb(cptr, 15);
+  // CHECK: call i32 @llvm.s390.lcbb(i8* %{{.*}}, i32 15)
+
+  vsc = __builtin_s390_vlbb(cptr, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0)
+  vsc = __builtin_s390_vlbb(cptr, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 15)
+
+  vsc = __builtin_s390_vll(len, cptr);
+  // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}})
+
+  vul = __builtin_s390_vpdi(vul, vul, 0);
+  // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0)
+  vul = __builtin_s390_vpdi(vul, vul, 15);
+  // CHECK: call <2 x i64> @llvm.s390.vpdi(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vperm(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vuc = __builtin_s390_vpklsh(vus, vus);
+  // CHECK: call <16 x i8> @llvm.s390.vpklsh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vus = __builtin_s390_vpklsf(vui, vui);
+  // CHECK: call <8 x i16> @llvm.s390.vpklsf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vui = __builtin_s390_vpklsg(vul, vul);
+  // CHECK: call <4 x i32> @llvm.s390.vpklsg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vuc = __builtin_s390_vpklshs(vus, vus, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vpklshs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vus = __builtin_s390_vpklsfs(vui, vui, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vpklsfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vui = __builtin_s390_vpklsgs(vul, vul, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vpklsgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vpksh(vss, vss);
+  // CHECK: call <16 x i8> @llvm.s390.vpksh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vss = __builtin_s390_vpksf(vsi, vsi);
+  // CHECK: call <8 x i16> @llvm.s390.vpksf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsi = __builtin_s390_vpksg(vsl, vsl);
+  // CHECK: call <4 x i32> @llvm.s390.vpksg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vpkshs(vss, vss, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vpkshs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vss = __builtin_s390_vpksfs(vsi, vsi, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vpksfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsi = __builtin_s390_vpksgs(vsl, vsl, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vpksgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  __builtin_s390_vstl(vsc, len, ptr);
+  // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}})
+
+  vss = __builtin_s390_vuphb(vsc);
+  // CHECK: call <8 x i16> @llvm.s390.vuphb(<16 x i8> %{{.*}})
+  vsi = __builtin_s390_vuphh(vss);
+  // CHECK: call <4 x i32> @llvm.s390.vuphh(<8 x i16> %{{.*}})
+  vsl = __builtin_s390_vuphf(vsi);
+  // CHECK: call <2 x i64> @llvm.s390.vuphf(<4 x i32> %{{.*}})
+
+  vss = __builtin_s390_vuplb(vsc);
+  // CHECK: call <8 x i16> @llvm.s390.vuplb(<16 x i8> %{{.*}})
+  vsi = __builtin_s390_vuplhw(vss);
+  // CHECK: call <4 x i32> @llvm.s390.vuplhw(<8 x i16> %{{.*}})
+  vsl = __builtin_s390_vuplf(vsi);
+  // CHECK: call <2 x i64> @llvm.s390.vuplf(<4 x i32> %{{.*}})
+
+  vus = __builtin_s390_vuplhb(vuc);
+  // CHECK: call <8 x i16> @llvm.s390.vuplhb(<16 x i8> %{{.*}})
+  vui = __builtin_s390_vuplhh(vus);
+  // CHECK: call <4 x i32> @llvm.s390.vuplhh(<8 x i16> %{{.*}})
+  vul = __builtin_s390_vuplhf(vui);
+  // CHECK: call <2 x i64> @llvm.s390.vuplhf(<4 x i32> %{{.*}})
+
+  vus = __builtin_s390_vupllb(vuc);
+  // CHECK: call <8 x i16> @llvm.s390.vupllb(<16 x i8> %{{.*}})
+  vui = __builtin_s390_vupllh(vus);
+  // CHECK: call <4 x i32> @llvm.s390.vupllh(<8 x i16> %{{.*}})
+  vul = __builtin_s390_vupllf(vui);
+  // CHECK: call <2 x i64> @llvm.s390.vupllf(<4 x i32> %{{.*}})
+}
+
+void test_integer(void) {
+  vuc = __builtin_s390_vaq(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vaq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vacq(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vacq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vaccq(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vaccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vacccq(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vacccq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vuc = __builtin_s390_vaccb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vaccb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vacch(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vacch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vaccf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vaccf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vaccg(vul, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vaccg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vavgb(vsc, vsc);
+  // CHECK: call <16 x i8> @llvm.s390.vavgb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vavgh(vss, vss);
+  // CHECK: call <8 x i16> @llvm.s390.vavgh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vavgf(vsi, vsi);
+  // CHECK: call <4 x i32> @llvm.s390.vavgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vavgg(vsl, vsl);
+  // CHECK: call <2 x i64> @llvm.s390.vavgg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vuc = __builtin_s390_vavglb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vavglb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vavglh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vavglh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vavglf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vavglf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vavglg(vul, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vavglg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vui = __builtin_s390_vcksm(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vcksm(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vclzb(vuc);
+  // CHECK: call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %{{.*}}, i1 false)
+  vus = __builtin_s390_vclzh(vus);
+  // CHECK: call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %{{.*}}, i1 false)
+  vui = __builtin_s390_vclzf(vui);
+  // CHECK: call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %{{.*}}, i1 false)
+  vul = __builtin_s390_vclzg(vul);
+  // CHECK: call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %{{.*}}, i1 false)
+
+  vuc = __builtin_s390_vctzb(vuc);
+  // CHECK: call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %{{.*}}, i1 false)
+  vus = __builtin_s390_vctzh(vus);
+  // CHECK: call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %{{.*}}, i1 false)
+  vui = __builtin_s390_vctzf(vui);
+  // CHECK: call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %{{.*}}, i1 false)
+  vul = __builtin_s390_vctzg(vul);
+  // CHECK: call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %{{.*}}, i1 false)
+
+  vuc = __builtin_s390_verimb(vuc, vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_verimb(vuc, vuc, vuc, 255);
+  // CHECK: call <16 x i8> @llvm.s390.verimb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 255)
+  vus = __builtin_s390_verimh(vus, vus, vus, 0);
+  // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_verimh(vus, vus, vus, 255);
+  // CHECK: call <8 x i16> @llvm.s390.verimh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 255)
+  vui = __builtin_s390_verimf(vui, vui, vui, 0);
+  // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_verimf(vui, vui, vui, 255);
+  // CHECK: call <4 x i32> @llvm.s390.verimf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 255)
+  vul = __builtin_s390_verimg(vul, vul, vul, 0);
+  // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 0)
+  vul = __builtin_s390_verimg(vul, vul, vul, 255);
+  // CHECK: call <2 x i64> @llvm.s390.verimg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i32 255)
+
+  vuc = __builtin_s390_verllb(vuc, len);
+  // CHECK: call <16 x i8> @llvm.s390.verllb(<16 x i8> %{{.*}}, i32 %{{.*}})
+  vus = __builtin_s390_verllh(vus, len);
+  // CHECK: call <8 x i16> @llvm.s390.verllh(<8 x i16> %{{.*}}, i32 %{{.*}})
+  vui = __builtin_s390_verllf(vui, len);
+  // CHECK: call <4 x i32> @llvm.s390.verllf(<4 x i32> %{{.*}}, i32 %{{.*}})
+  vul = __builtin_s390_verllg(vul, len);
+  // CHECK: call <2 x i64> @llvm.s390.verllg(<2 x i64> %{{.*}}, i32 %{{.*}})
+
+  vuc = __builtin_s390_verllvb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.verllvb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_verllvh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.verllvh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_verllvf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.verllvf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_verllvg(vul, vul);
+  // CHECK: call <2 x i64> @llvm.s390.verllvg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vus = __builtin_s390_vgfmb(vuc, vuc);
+  // CHECK: call <8 x i16> @llvm.s390.vgfmb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vui = __builtin_s390_vgfmh(vus, vus);
+  // CHECK: call <4 x i32> @llvm.s390.vgfmh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vul = __builtin_s390_vgfmf(vui, vui);
+  // CHECK: call <2 x i64> @llvm.s390.vgfmf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vuc = __builtin_s390_vgfmg(vul, vul);
+  // CHECK: call <16 x i8> @llvm.s390.vgfmg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vus = __builtin_s390_vgfmab(vuc, vuc, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vgfmab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vgfmah(vus, vus, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vgfmah(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vgfmaf(vui, vui, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vgfmaf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}})
+  vuc = __builtin_s390_vgfmag(vul, vul, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vgfmag(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}})
+
+  vsc = __builtin_s390_vmahb(vsc, vsc, vsc);
+  // CHECK: call <16 x i8> @llvm.s390.vmahb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vmahh(vss, vss, vss);
+  // CHECK: call <8 x i16> @llvm.s390.vmahh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vmahf(vsi, vsi, vsi);
+  // CHECK: call <4 x i32> @llvm.s390.vmahf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vuc = __builtin_s390_vmalhb(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vmalhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vmalhh(vus, vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vmalhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vmalhf(vui, vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vmalhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vss = __builtin_s390_vmaeb(vsc, vsc, vss);
+  // CHECK: call <8 x i16> @llvm.s390.vmaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vmaeh(vss, vss, vsi);
+  // CHECK: call <4 x i32> @llvm.s390.vmaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vmaef(vsi, vsi, vsl);
+  // CHECK: call <2 x i64> @llvm.s390.vmaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}})
+  vus = __builtin_s390_vmaleb(vuc, vuc, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vmaleb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vmaleh(vus, vus, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vmaleh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vmalef(vui, vui, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vmalef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}})
+
+  vss = __builtin_s390_vmaob(vsc, vsc, vss);
+  // CHECK: call <8 x i16> @llvm.s390.vmaob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vmaoh(vss, vss, vsi);
+  // CHECK: call <4 x i32> @llvm.s390.vmaoh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vmaof(vsi, vsi, vsl);
+  // CHECK: call <2 x i64> @llvm.s390.vmaof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}})
+  vus = __builtin_s390_vmalob(vuc, vuc, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vmalob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vmaloh(vus, vus, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vmaloh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vmalof(vui, vui, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vmalof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vmhb(vsc, vsc);
+  // CHECK: call <16 x i8> @llvm.s390.vmhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vmhh(vss, vss);
+  // CHECK: call <8 x i16> @llvm.s390.vmhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vmhf(vsi, vsi);
+  // CHECK: call <4 x i32> @llvm.s390.vmhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vuc = __builtin_s390_vmlhb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vmlhb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vmlhh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vmlhh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vmlhf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vmlhf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vss = __builtin_s390_vmeb(vsc, vsc);
+  // CHECK: call <8 x i16> @llvm.s390.vmeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vsi = __builtin_s390_vmeh(vss, vss);
+  // CHECK: call <4 x i32> @llvm.s390.vmeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsl = __builtin_s390_vmef(vsi, vsi);
+  // CHECK: call <2 x i64> @llvm.s390.vmef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vus = __builtin_s390_vmleb(vuc, vuc);
+  // CHECK: call <8 x i16> @llvm.s390.vmleb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vui = __builtin_s390_vmleh(vus, vus);
+  // CHECK: call <4 x i32> @llvm.s390.vmleh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vul = __builtin_s390_vmlef(vui, vui);
+  // CHECK: call <2 x i64> @llvm.s390.vmlef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vss = __builtin_s390_vmob(vsc, vsc);
+  // CHECK: call <8 x i16> @llvm.s390.vmob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vsi = __builtin_s390_vmoh(vss, vss);
+  // CHECK: call <4 x i32> @llvm.s390.vmoh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsl = __builtin_s390_vmof(vsi, vsi);
+  // CHECK: call <2 x i64> @llvm.s390.vmof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vus = __builtin_s390_vmlob(vuc, vuc);
+  // CHECK: call <8 x i16> @llvm.s390.vmlob(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vui = __builtin_s390_vmloh(vus, vus);
+  // CHECK: call <4 x i32> @llvm.s390.vmloh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vul = __builtin_s390_vmlof(vui, vui);
+  // CHECK: call <2 x i64> @llvm.s390.vmlof(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vpopctb(vuc);
+  // CHECK: call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %{{.*}})
+  vus = __builtin_s390_vpopcth(vus);
+  // CHECK: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %{{.*}})
+  vui = __builtin_s390_vpopctf(vui);
+  // CHECK: call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %{{.*}})
+  vul = __builtin_s390_vpopctg(vul);
+  // CHECK: call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %{{.*}})
+
+  vuc = __builtin_s390_vsq(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vsbiq(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vscbiq(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vscbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vsbcbiq(vuc, vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsbcbiq(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vuc = __builtin_s390_vscbib(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vscbib(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vscbih(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vscbih(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vscbif(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vscbif(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vul = __builtin_s390_vscbig(vul, vul);
+  // CHECK: call <2 x i64> @llvm.s390.vscbig(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vuc = __builtin_s390_vsldb(vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vsldb(vuc, vuc, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vsl(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vslb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vuc = __builtin_s390_vsra(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsra(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vsrab(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vuc = __builtin_s390_vsrl(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsrl(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vuc = __builtin_s390_vsrlb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vui = __builtin_s390_vsumb(vuc, vuc);
+  // CHECK: call <4 x i32> @llvm.s390.vsumb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vui = __builtin_s390_vsumh(vus, vus);
+  // CHECK: call <4 x i32> @llvm.s390.vsumh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vul = __builtin_s390_vsumgh(vus, vus);
+  // CHECK: call <2 x i64> @llvm.s390.vsumgh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vul = __builtin_s390_vsumgf(vui, vui);
+  // CHECK: call <2 x i64> @llvm.s390.vsumgf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vuc = __builtin_s390_vsumqf(vui, vui);
+  // CHECK: call <16 x i8> @llvm.s390.vsumqf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vuc = __builtin_s390_vsumqg(vul, vul);
+  // CHECK: call <16 x i8> @llvm.s390.vsumqg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  len = __builtin_s390_vtm(vuc, vuc);
+  // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+  vsc = __builtin_s390_vceqbs(vsc, vsc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vceqbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vceqhs(vss, vss, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vceqhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vceqfs(vsi, vsi, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vceqfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vceqgs(vsl, vsl, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vceqgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vchbs(vsc, vsc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vchhs(vss, vss, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vchfs(vsi, vsi, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vchgs(vsl, vsl, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+  vsc = __builtin_s390_vchlbs(vuc, vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vchlbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vss = __builtin_s390_vchlhs(vus, vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vchlhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vsi = __builtin_s390_vchlfs(vui, vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vchlfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+  vsl = __builtin_s390_vchlgs(vul, vul, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vchlgs(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+}
+
+void test_string(void) {
+  vuc = __builtin_s390_vfaeb(vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vfaeb(vuc, vuc, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vfaeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vfaeh(vus, vus, 0);
+  // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vfaeh(vus, vus, 15);
+  // CHECK: call <8 x i16> @llvm.s390.vfaeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vfaef(vui, vui, 0);
+  // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vfaef(vui, vui, 15);
+  // CHECK: call <4 x i32> @llvm.s390.vfaef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vfaezb(vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vfaezb(vuc, vuc, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vfaezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vfaezh(vus, vus, 0);
+  // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vfaezh(vus, vus, 15);
+  // CHECK: call <8 x i16> @llvm.s390.vfaezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vfaezf(vui, vui, 0);
+  // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vfaezf(vui, vui, 15);
+  // CHECK: call <4 x i32> @llvm.s390.vfaezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vfeeb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vfeeb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfeeh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vfeeh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfeef(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vfeef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfeezb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vfeezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfeezh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vfeezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfeezf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vfeezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfeneb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vfeneb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfeneh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vfeneh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfenef(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vfenef(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfenezb(vuc, vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vfenezb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfenezh(vus, vus);
+  // CHECK: call <8 x i16> @llvm.s390.vfenezh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfenezf(vui, vui);
+  // CHECK: call <4 x i32> @llvm.s390.vfenezf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vistrb(vuc);
+  // CHECK: call <16 x i8> @llvm.s390.vistrb(<16 x i8> %{{.*}})
+  vus = __builtin_s390_vistrh(vus);
+  // CHECK: call <8 x i16> @llvm.s390.vistrh(<8 x i16> %{{.*}})
+  vui = __builtin_s390_vistrf(vui);
+  // CHECK: call <4 x i32> @llvm.s390.vistrf(<4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vstrcb(vuc, vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vstrcb(vuc, vuc, vuc, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vstrcb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vstrch(vus, vus, vus, 0);
+  // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vstrch(vus, vus, vus, 15);
+  // CHECK: call <8 x i16> @llvm.s390.vstrch(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vstrcf(vui, vui, vui, 0);
+  // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vstrcf(vui, vui, vui, 15);
+  // CHECK: call <4 x i32> @llvm.s390.vstrcf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vstrczb(vuc, vuc, vuc, 0);
+  // CHECK: call <16 x i8> @llvm.s390.vstrczb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vstrczb(vuc, vuc, vuc, 15);
+  // CHECK: call <16 x i8> @llvm.s390.vstrczb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vstrczh(vus, vus, vus, 0);
+  // CHECK: call <8 x i16> @llvm.s390.vstrczh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vstrczh(vus, vus, vus, 15);
+  // CHECK: call <8 x i16> @llvm.s390.vstrczh(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vstrczf(vui, vui, vui, 0);
+  // CHECK: call <4 x i32> @llvm.s390.vstrczf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vstrczf(vui, vui, vui, 15);
+  // CHECK: call <4 x i32> @llvm.s390.vstrczf(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vfaebs(vuc, vuc, 0, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vfaebs(vuc, vuc, 15, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vfaehs(vus, vus, 0, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vfaehs(vus, vus, 15, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vfaefs(vui, vui, 0, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vfaefs(vui, vui, 15, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vfaezbs(vuc, vuc, 0, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vfaezbs(vuc, vuc, 15, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfaezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vfaezhs(vus, vus, 0, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vfaezhs(vus, vus, 15, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfaezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vfaezfs(vui, vui, 0, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vfaezfs(vui, vui, 15, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfaezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vfeebs(vuc, vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfeehs(vus, vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfeefs(vui, vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfeezbs(vuc, vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfeezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfeezhs(vus, vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfeezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfeezfs(vui, vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfeezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfenebs(vuc, vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenebs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfenehs(vus, vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenehs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfenefs(vui, vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenefs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vfenezbs(vuc, vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vfenezbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+  vus = __builtin_s390_vfenezhs(vus, vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vfenezhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+  vui = __builtin_s390_vfenezfs(vui, vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfenezfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vistrbs(vuc, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vistrbs(<16 x i8> %{{.*}})
+  vus = __builtin_s390_vistrhs(vus, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vistrhs(<8 x i16> %{{.*}})
+  vui = __builtin_s390_vistrfs(vui, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vistrfs(<4 x i32> %{{.*}})
+
+  vuc = __builtin_s390_vstrcbs(vuc, vuc, vuc, 0, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vstrcbs(vuc, vuc, vuc, 15, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrcbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vstrchs(vus, vus, vus, 0, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vstrchs(vus, vus, vus, 15, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrchs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vstrcfs(vui, vui, vui, 0, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vstrcfs(vui, vui, vui, 15, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrcfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+
+  vuc = __builtin_s390_vstrczbs(vuc, vuc, vuc, 0, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrczbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+  vuc = __builtin_s390_vstrczbs(vuc, vuc, vuc, 15, &cc);
+  // CHECK: call { <16 x i8>, i32 } @llvm.s390.vstrczbs(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+  vus = __builtin_s390_vstrczhs(vus, vus, vus, 0, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrczhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 0)
+  vus = __builtin_s390_vstrczhs(vus, vus, vus, 15, &cc);
+  // CHECK: call { <8 x i16>, i32 } @llvm.s390.vstrczhs(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i32 15)
+  vui = __builtin_s390_vstrczfs(vui, vui, vui, 0, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrczfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 0)
+  vui = __builtin_s390_vstrczfs(vui, vui, vui, 15, &cc);
+  // CHECK: call { <4 x i32>, i32 } @llvm.s390.vstrczfs(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i32 15)
+}
+
+void test_float(void) {
+  vsl = __builtin_s390_vfcedbs(vd, vd, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+  vsl = __builtin_s390_vfchdbs(vd, vd, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+  vsl = __builtin_s390_vfchedbs(vd, vd, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+  vsl = __builtin_s390_vftcidb(vd, 0, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 0)
+  vsl = __builtin_s390_vftcidb(vd, 4095, &cc);
+  // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4095)
+
+  vd = __builtin_s390_vfsqdb(vd);
+  // CHECK: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %{{.*}})
+
+  vd = __builtin_s390_vfmadb(vd, vd, vd);
+  // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
+  vd = __builtin_s390_vfmsdb(vd, vd, vd);
+  // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.*}}
+  // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]])
+
+  vd = __builtin_s390_vflpdb(vd);
+  // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vflndb(vd);
+  // CHECK: [[ABS:%[^ ]+]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+  // CHECK: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[ABS]]
+
+  vd = __builtin_s390_vfidb(vd, 0, 0);
+  // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 0);
+  // CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 1);
+  // CHECK: call <2 x double> @llvm.round.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 5);
+  // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 6);
+  // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 7);
+  // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}})
+  vd = __builtin_s390_vfidb(vd, 4, 4);
+  // CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
+}