[llvm] [clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-10-31 Thread Léonard Oest O'Leary via cfe-commits

leo-ard wrote:

I'm closing this PR in favour of #70845

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Léonard Oest O'Leary via cfe-commits

leo-ard wrote:

> If I understood correctly, what you're trying to do here is to apply an icmp 
> fold early before the sext -> zext information gets lost. I don't think this 
> is the correct way to approach the problem. The correct way is to preserve 
> the fact that the operand is non-negative when converting to zext, which 
> would allow the InstCombine fold to reliably undo this. In fact, there is a 
> pending patch for this at https://reviews.llvm.org/D156444.

When tackling this problem, my first idea was to track the non-negativeness of 
the zext and use this information in InstCombine. I didn't know that you could 
do it through flags in the IR, which I think is a cleaner solution. Do you 
think this patch will be available soon ?


https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Nikita Popov via cfe-commits

https://github.com/nikic requested changes to this pull request.

If I understood correctly, what you're trying to do here is to apply an icmp 
fold early before the sext -> zext information gets lost. I don't think this is 
the correct way to approach the problem. The correct way is to preserve the 
fact that the operand is non-negative when converting to zext, which would 
allow the InstCombine fold to reliably undo this. In fact, there is a pending 
patch for this at https://reviews.llvm.org/D156444.

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Marianne Mailhot-Sarrasin via cfe-commits


@@ -0,0 +1,185 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --tool ./bin/opt --version 3
+; See PRXXX for more details

mariannems wrote:

`See PRXXX` Was that autogenerated ? Does it need to be updated ?

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Marianne Mailhot-Sarrasin via cfe-commits


@@ -193,6 +193,66 @@ static bool replaceSignedInst(SCCPSolver ,
 NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", );
 break;
   }
+  case Instruction::ICmp: {
+ICmpInst  = cast(Inst);
+
+ZExtInst *Op0_zext = dyn_cast(ICmp.getOperand(0));
+SExtInst *Op0_sext = dyn_cast(ICmp.getOperand(0));
+
+ZExtInst *Op1_zext = dyn_cast(ICmp.getOperand(1));
+SExtInst *Op1_sext = dyn_cast(ICmp.getOperand(1));
+
+CastInst *Op0;
+CastInst *Op1;
+
+if (Op0_zext)
+  Op0 = Op0_zext;
+else
+  Op0 = Op0_sext;
+if (Op1_zext)
+  Op1 = Op1_zext;
+else
+  Op1 = Op1_sext;
+
+bool reversed = false;
+
+if (!Op0 || !Op1) {
+  // Op0 and Op1 must be defined
+  return false;
+}
+
+if (Op1_zext && (!Op0_zext)) {
+  // We force Op0 to be a zext and reverse the arguments
+  //   at the end if we swap
+  reversed = true;

mariannems wrote:

IMHO the swapping makes it harder to read. Not swapping would force case to be 
checked in the if statement, but would make the code more readable.

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Marianne Mailhot-Sarrasin via cfe-commits


@@ -193,6 +193,60 @@ static bool replaceSignedInst(SCCPSolver ,
 NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", );
 break;
   }
+  case Instruction::ICmp: {
+ICmpInst  = cast(Inst);
+  
+ZExtInst *Op0_zext = dyn_cast(ICmp.getOperand(0));
+SExtInst *Op0_sext = dyn_cast(ICmp.getOperand(0));
+  
+ZExtInst *Op1_zext = dyn_cast(ICmp.getOperand(1));
+SExtInst *Op1_sext = dyn_cast(ICmp.getOperand(1));
+  
+CastInst *Op0;
+CastInst *Op1;
+  
+if (Op0_zext) Op0 = Op0_zext; else Op0 = Op0_sext;
+if (Op1_zext) Op1 = Op1_zext; else Op1 = Op1_sext;
+  
+bool reversed = false;
+  
+if (!Op0 || !Op1){
+  // Op0 and Op1 must be defined
+  return false;
+} 
+  
+if (Op1_zext && (! Op0_zext)){
+  // We force Op0 to be a zext and reverse the arguments
+  //   at the end if we swap
+  reversed = true; 
+  
+  std::swap(Op0_zext, Op1_zext);
+  std::swap(Op0_sext, Op1_sext);
+  std::swap(Op0, Op1);
+}
+  
+  
+if(Op0->getType() != Op1->getType()){

mariannems wrote:

Its is always better to exit early. This check should ideally be done before 
potential swapping.

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Marianne Mailhot-Sarrasin via cfe-commits

https://github.com/mariannems commented:

Thanks for fixing that regression!

https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Marianne Mailhot-Sarrasin via cfe-commits

https://github.com/mariannems edited 
https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Léonard Oest O'Leary via cfe-commits

https://github.com/leo-ard updated 
https://github.com/llvm/llvm-project/pull/67594

From 399f9d64cfde0761ac8278dd05ba704d879b1f5a Mon Sep 17 00:00:00 2001
From: leo-ard 
Date: Wed, 27 Sep 2023 13:35:53 -0400
Subject: [PATCH 1/2] Adding ICMP folding for SCCPSolver

---
 clang/test/CodeGen/X86/min_max.c  |  19 ++
 llvm/lib/Transforms/Utils/SCCPSolver.cpp  |  54 +
 .../Transforms/SCCP/icmp-fold-with-cast.ll| 185 ++
 llvm/test/Transforms/SCCP/widening.ll |   4 +-
 4 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/X86/min_max.c
 create mode 100644 llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll

diff --git a/clang/test/CodeGen/X86/min_max.c b/clang/test/CodeGen/X86/min_max.c
new file mode 100644
index 000..7af8181cc9ff367
--- /dev/null
+++ b/clang/test/CodeGen/X86/min_max.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -O2 -triple=x86_64-apple-darwin -emit-llvm -o - | 
FileCheck %s
+
+short vecreduce_smax_v2i16(int n, short* v)
+{
+  // CHECK: @llvm.smax
+  short p = 0;
+  for (int i = 0; i < n; ++i)
+p = p < v[i] ? v[i] : p;
+  return p;
+}
+
+short vecreduce_smin_v2i16(int n, short* v)
+{
+  // CHECK: @llvm.smin
+  short p = 0;
+  for (int i = 0; i < n; ++i)
+p = p > v[i] ? v[i] : p;
+  return p;
+}
\ No newline at end of file
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp 
b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 8a67fda7c98e787..09f64a925ab1b7c 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -193,6 +193,60 @@ static bool replaceSignedInst(SCCPSolver ,
 NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", );
 break;
   }
+  case Instruction::ICmp: {
+ICmpInst  = cast(Inst);
+  
+ZExtInst *Op0_zext = dyn_cast(ICmp.getOperand(0));
+SExtInst *Op0_sext = dyn_cast(ICmp.getOperand(0));
+  
+ZExtInst *Op1_zext = dyn_cast(ICmp.getOperand(1));
+SExtInst *Op1_sext = dyn_cast(ICmp.getOperand(1));
+  
+CastInst *Op0;
+CastInst *Op1;
+  
+if (Op0_zext) Op0 = Op0_zext; else Op0 = Op0_sext;
+if (Op1_zext) Op1 = Op1_zext; else Op1 = Op1_sext;
+  
+bool reversed = false;
+  
+if (!Op0 || !Op1){
+  // Op0 and Op1 must be defined
+  return false;
+} 
+  
+if (Op1_zext && (! Op0_zext)){
+  // We force Op0 to be a zext and reverse the arguments
+  //   at the end if we swap
+  reversed = true; 
+  
+  std::swap(Op0_zext, Op1_zext);
+  std::swap(Op0_sext, Op1_sext);
+  std::swap(Op0, Op1);
+}
+  
+  
+if(Op0->getType() != Op1->getType()){
+  // extensions are not of the same type
+  // This optimization is done in InstCombine
+  return false;
+}
+  
+// ICMP (sext X) (sext y) => ICMP X, Y
+// ICMP (zext X) (zext y) => ICMP X, Y
+// ICMP (zext X) (sext Y) => ICMP X, Y  if X >= 0 and ICMP signed
+if((Op0_zext && Op1_zext)
+   || (Op0_sext && Op1_sext) 
+   || (ICmp.isSigned() && Op0_zext && Op1_sext && 
isNonNegative(Op0_zext->getOperand(0{
+  
+  Value *X = Op0->getOperand(0);
+  Value *Y = Op1->getOperand(0);
+  NewInst = CmpInst::Create(ICmp.getOpcode(), ICmp.getPredicate(), 
reversed ? Y : X, reversed ? X : Y, "", );
+  break;
+}
+  
+return false;
+  }
   default:
 return false;
   }
diff --git a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll 
b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
new file mode 100644
index 000..90b2c123081fb49
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
@@ -0,0 +1,185 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --tool ./bin/opt --version 3
+; See PRXXX for more details
+; RUN: opt < %s -S -passes=ipsccp | FileCheck %s
+
+
+define signext i32 @sext_sext(i16 %x, i16 %y) {
+; CHECK-LABEL: define signext i32 @sext_sext(
+; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:[[CONV:%.*]] = sext i16 [[X]] to i32
+; CHECK-NEXT:[[CONV1:%.*]] = sext i16 [[Y]] to i32
+; CHECK-NEXT:[[CMP2:%.*]] = icmp sgt i16 [[X]], [[Y]]
+; CHECK-NEXT:br i1 [[CMP2]], label [[COND_TRUE:%.*]], label 
[[COND_FALSE:%.*]]
+; CHECK:   cond.true:
+; CHECK-NEXT:br label [[COND_END:%.*]]
+; CHECK:   cond.false:
+; CHECK-NEXT:br label [[COND_END]]
+; CHECK:   cond.end:
+; CHECK-NEXT:[[COND:%.*]] = phi i32 [ 0, [[COND_TRUE]] ], [ 1, 
[[COND_FALSE]] ]
+; CHECK-NEXT:ret i32 [[COND]]
+;
+entry:
+  %conv = sext i16 %x to i32
+  %conv1 = sext i16 %y to i32
+  %cmp2 = icmp sgt i32 %conv, %conv1
+  br i1 %cmp2, label %cond.true, label %cond.false
+
+cond.true:; preds = %for.body
+  br label %cond.end
+
+cond.false:   ; preds = %for.body
+  br label %cond.end
+
+cond.end: ; preds = %cond.false, 
%cond.true
+  %cond = phi i32 [ 

[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 5ffbdd9ed5fb719b354e4a46acc8737c5b624f94 
399f9d64cfde0761ac8278dd05ba704d879b1f5a -- clang/test/CodeGen/X86/min_max.c 
llvm/lib/Transforms/Utils/SCCPSolver.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp 
b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 09f64a925ab1..0038e8866c2c 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -195,56 +195,62 @@ static bool replaceSignedInst(SCCPSolver ,
   }
   case Instruction::ICmp: {
 ICmpInst  = cast(Inst);
-  
+
 ZExtInst *Op0_zext = dyn_cast(ICmp.getOperand(0));
 SExtInst *Op0_sext = dyn_cast(ICmp.getOperand(0));
-  
+
 ZExtInst *Op1_zext = dyn_cast(ICmp.getOperand(1));
 SExtInst *Op1_sext = dyn_cast(ICmp.getOperand(1));
-  
+
 CastInst *Op0;
 CastInst *Op1;
-  
-if (Op0_zext) Op0 = Op0_zext; else Op0 = Op0_sext;
-if (Op1_zext) Op1 = Op1_zext; else Op1 = Op1_sext;
-  
+
+if (Op0_zext)
+  Op0 = Op0_zext;
+else
+  Op0 = Op0_sext;
+if (Op1_zext)
+  Op1 = Op1_zext;
+else
+  Op1 = Op1_sext;
+
 bool reversed = false;
-  
-if (!Op0 || !Op1){
+
+if (!Op0 || !Op1) {
   // Op0 and Op1 must be defined
   return false;
-} 
-  
-if (Op1_zext && (! Op0_zext)){
+}
+
+if (Op1_zext && (!Op0_zext)) {
   // We force Op0 to be a zext and reverse the arguments
   //   at the end if we swap
-  reversed = true; 
-  
+  reversed = true;
+
   std::swap(Op0_zext, Op1_zext);
   std::swap(Op0_sext, Op1_sext);
   std::swap(Op0, Op1);
 }
-  
-  
-if(Op0->getType() != Op1->getType()){
+
+if (Op0->getType() != Op1->getType()) {
   // extensions are not of the same type
   // This optimization is done in InstCombine
   return false;
 }
-  
+
 // ICMP (sext X) (sext y) => ICMP X, Y
 // ICMP (zext X) (zext y) => ICMP X, Y
 // ICMP (zext X) (sext Y) => ICMP X, Y  if X >= 0 and ICMP signed
-if((Op0_zext && Op1_zext)
-   || (Op0_sext && Op1_sext) 
-   || (ICmp.isSigned() && Op0_zext && Op1_sext && 
isNonNegative(Op0_zext->getOperand(0{
-  
+if ((Op0_zext && Op1_zext) || (Op0_sext && Op1_sext) ||
+(ICmp.isSigned() && Op0_zext && Op1_sext &&
+ isNonNegative(Op0_zext->getOperand(0 {
+
   Value *X = Op0->getOperand(0);
   Value *Y = Op1->getOperand(0);
-  NewInst = CmpInst::Create(ICmp.getOpcode(), ICmp.getPredicate(), 
reversed ? Y : X, reversed ? X : Y, "", );
+  NewInst = CmpInst::Create(ICmp.getOpcode(), ICmp.getPredicate(),
+reversed ? Y : X, reversed ? X : Y, "", );
   break;
 }
-  
+
 return false;
   }
   default:

``




https://github.com/llvm/llvm-project/pull/67594
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [SCCP] [Transform] Adding ICMP folding for zext and sext in SCCPSolver (PR #67594)

2023-09-27 Thread Léonard Oest O'Leary via cfe-commits

https://github.com/leo-ard created 
https://github.com/llvm/llvm-project/pull/67594

This PR fixes #55013 : the max intrinsics is not generated for this simple loop 
case : https://godbolt.org/z/hxz1xhMPh. This is caused by a ICMP not being 
folded into a select, thus not generating the max intrinsics. 

Since LLVM 14, SCCP pass got smarter by folding sext into zext for positive 
ranges : https://reviews.llvm.org/D81756. After this change, InstCombine was 
sometimes unable to fold icmp correctly as both of the arguments pointed to 
mismatched zext/sext. To fix this, @rotateright implemented this fix : 
https://reviews.llvm.org/D124419 that tries to resolve the mismatch by knowing 
if the argument of a zext is positive (in which case, it is like a sext) by 
using ValueTracking. However, ValueTracking seems to be not smart enough for 
this case and cannot accurately know that the value is positive or not. This PR 
implements the folding in SCCP directly, where we have the knowledge that the 
value are positive or not.

This PR also contains test cases for sext/zext folding with SCCP as well as a 
x86 regression tests for the max/min case. 

From 399f9d64cfde0761ac8278dd05ba704d879b1f5a Mon Sep 17 00:00:00 2001
From: leo-ard 
Date: Wed, 27 Sep 2023 13:35:53 -0400
Subject: [PATCH] Adding ICMP folding for SCCPSolver

---
 clang/test/CodeGen/X86/min_max.c  |  19 ++
 llvm/lib/Transforms/Utils/SCCPSolver.cpp  |  54 +
 .../Transforms/SCCP/icmp-fold-with-cast.ll| 185 ++
 llvm/test/Transforms/SCCP/widening.ll |   4 +-
 4 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/X86/min_max.c
 create mode 100644 llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll

diff --git a/clang/test/CodeGen/X86/min_max.c b/clang/test/CodeGen/X86/min_max.c
new file mode 100644
index 000..7af8181cc9ff367
--- /dev/null
+++ b/clang/test/CodeGen/X86/min_max.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -O2 -triple=x86_64-apple-darwin -emit-llvm -o - | 
FileCheck %s
+
+short vecreduce_smax_v2i16(int n, short* v)
+{
+  // CHECK: @llvm.smax
+  short p = 0;
+  for (int i = 0; i < n; ++i)
+p = p < v[i] ? v[i] : p;
+  return p;
+}
+
+short vecreduce_smin_v2i16(int n, short* v)
+{
+  // CHECK: @llvm.smin
+  short p = 0;
+  for (int i = 0; i < n; ++i)
+p = p > v[i] ? v[i] : p;
+  return p;
+}
\ No newline at end of file
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp 
b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 8a67fda7c98e787..09f64a925ab1b7c 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -193,6 +193,60 @@ static bool replaceSignedInst(SCCPSolver ,
 NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", );
 break;
   }
+  case Instruction::ICmp: {
+ICmpInst  = cast(Inst);
+  
+ZExtInst *Op0_zext = dyn_cast(ICmp.getOperand(0));
+SExtInst *Op0_sext = dyn_cast(ICmp.getOperand(0));
+  
+ZExtInst *Op1_zext = dyn_cast(ICmp.getOperand(1));
+SExtInst *Op1_sext = dyn_cast(ICmp.getOperand(1));
+  
+CastInst *Op0;
+CastInst *Op1;
+  
+if (Op0_zext) Op0 = Op0_zext; else Op0 = Op0_sext;
+if (Op1_zext) Op1 = Op1_zext; else Op1 = Op1_sext;
+  
+bool reversed = false;
+  
+if (!Op0 || !Op1){
+  // Op0 and Op1 must be defined
+  return false;
+} 
+  
+if (Op1_zext && (! Op0_zext)){
+  // We force Op0 to be a zext and reverse the arguments
+  //   at the end if we swap
+  reversed = true; 
+  
+  std::swap(Op0_zext, Op1_zext);
+  std::swap(Op0_sext, Op1_sext);
+  std::swap(Op0, Op1);
+}
+  
+  
+if(Op0->getType() != Op1->getType()){
+  // extensions are not of the same type
+  // This optimization is done in InstCombine
+  return false;
+}
+  
+// ICMP (sext X) (sext y) => ICMP X, Y
+// ICMP (zext X) (zext y) => ICMP X, Y
+// ICMP (zext X) (sext Y) => ICMP X, Y  if X >= 0 and ICMP signed
+if((Op0_zext && Op1_zext)
+   || (Op0_sext && Op1_sext) 
+   || (ICmp.isSigned() && Op0_zext && Op1_sext && 
isNonNegative(Op0_zext->getOperand(0{
+  
+  Value *X = Op0->getOperand(0);
+  Value *Y = Op1->getOperand(0);
+  NewInst = CmpInst::Create(ICmp.getOpcode(), ICmp.getPredicate(), 
reversed ? Y : X, reversed ? X : Y, "", );
+  break;
+}
+  
+return false;
+  }
   default:
 return false;
   }
diff --git a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll 
b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
new file mode 100644
index 000..90b2c123081fb49
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
@@ -0,0 +1,185 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --tool ./bin/opt --version 3
+; See PRXXX for more details
+; RUN: opt < %s -S -passes=ipsccp | FileCheck %s
+
+
+define signext i32 @sext_sext(i16 %x, i16 %y) {
+; CHECK-LABEL: define signext i32 @sext_sext(
+;