<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/85535>85535</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [InstCombine] WRONG code with sroa-skip-mem2reg
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation,
            llvm:instcombine
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          JonPsson1
      </td>
    </tr>
</table>

<pre>
    It seems that InstCombiner is incorrectly replacing a sext with a zext (see '<>' below):

```
left : clang -O3 -march=z16 wrong0.i -o a.out -fno-unroll-loops -mllvm -unroll-full-max-count=1 -fno-vectorize -fno-slp-vectorize
right: clang -O3 -march=z16 wrong0.i -o a.out -fno-unroll-loops -mllvm -unroll-full-max-count=1 -fno-vectorize -fno-slp-vectorize -mllvm -sroa-skip-mem2reg
```

```
; *** IR Dump After InstCombinePass on main ***                 ; *** IR Dump After InstCombinePass on main ***
; Function Attrs: nounwind ; Function Attrs: nounwind
define dso_local signext i32 @main() local_unnamed_addr    |    define dso_local signext i32 @main() local_unnamed_addr 
entry: entry:
  %0 = load ptr, ptr @IntVar1Ptr, align 8, !tbaa !13 %0 = load ptr, ptr @IntVar1Ptr, align 8, !tbaa !13
  store i32 -7, ptr %0, align 4, !tbaa !4                         store i32 -7, ptr %0, align 4, !tbaa !4
  %.pr.i = load i16, ptr @ShortIV, align 2, !tbaa !8       | %1 = load i16, ptr @ShortIV, align 2, !tbaa !8
  %cmp.i = icmp sgt i16 %.pr.i, -1                         |      %cmp.i = icmp sgt i16 %1, -1
 br i1 %cmp.i, label %for.cond.i, label %for.body11.lr.   |      br i1 %cmp.i, label %for.cond.us.i, label %for.cond.i,

for.cond.i: ; pred   |    for.cond.us.i: ; pred
  br label %for.cond.i                                     | br label %for.cond.us.i

for.body11.lr.ph.i: ; pred   |    for.cond.i:                                       ; pred
  %IntVar2.promoted.i = load i32, ptr @IntVar2, align 1,   |      %2 = load ptr, ptr @ShortVar1Ptr, align 8, !tbaa !13
  %1 = load ptr, ptr @ShortVar1Ptr, align 8, !tbaa !13     |      %.pre.i = load i32, ptr @IntVar2, align 4, !tbaa !4
  br label %for.body11.i br label %for.body11.i

for.body11.i: ; pred   |    for.body11.i: ; pred
  %add2325.i = phi i32 [ %IntVar2.promoted.i, %for.body1   | %3 = phi i32 [ %.pre.i, %for.cond.i ], [ %add.i, %for.
  %2 = load i32, ptr %0, align 4, !tbaa !4                 |      %4 = load i32, ptr %0, align 4, !tbaa !4
  %3 = trunc i32 %2 to i8 |      %5 = trunc i32 %4 to i8
  %4 = or i8 %3, -8 |      %6 = or i8 %5, -8
  %mul.i.i = mul i8 %4, -36 |      %conv14.i = mul nsw i8 %6, -36
>>%conv17.i = sext i8 %mul.i.i to i16                     <> %conv17.i = zext nneg i8 %conv14.i to i16     
  store i16 %conv17.i, ptr %1, align 2, !tbaa !8           |      store i16 %conv17.i, ptr %2, align 2, !tbaa !8
  %add.i = add nsw i32 %add2325.i, 1                       | %add.i = add nsw i32 %3, 1
  store i32 %add.i, ptr @IntVar2, align 4, !tbaa !4               store i32 %add.i, ptr @IntVar2, align 4, !tbaa !4
 %5 = load i16, ptr @ShortIV, align 2, !tbaa !8           |      %7 = load i16, ptr @ShortIV, align 2, !tbaa !8
  %inc18.i = add i16 %5, 1 |      %inc18.i = add i16 %7, 1
  store i16 %inc18.i, ptr @ShortIV, align 2, !tbaa !8             store i16 %inc18.i, ptr @ShortIV, align 2, !tbaa !8
  %cmp9.not.i = icmp eq i16 %inc18.i, 0 %cmp9.not.i = icmp eq i16 %inc18.i, 0
  br i1 %cmp9.not.i, label %fun.exit, label %for.body11.          br i1 %cmp9.not.i, label %fun.exit, label %for.body11.

fun.exit:                                         ; pred        fun.exit:                                         ; pred
  %6 = load i16, ptr @ShortVar1, align 2, !tbaa !8         |      %8 = load i16, ptr @ShortVar1, align 2, !tbaa !8
  %7 = lshr i16 %6, 8 |      %9 = lshr i16 %8, 8
  %conv1 = zext nneg i16 %7 to i32                         |      %conv1 = zext nneg i16 %9 to i32
 store i32 %conv1, ptr @Val, align 4, !tbaa !4                   store i32 %conv1, ptr @Val, align 4, !tbaa !4
  %call = call signext i32 (ptr, ...) @printf(ptr nounde          %call = call signext i32 (ptr, ...) @printf(ptr nounde
  ret i32 0 ret i32 0
} }

```
```
cat wrong0.i
int printf(const char *, ...);

int Val, IntVar1, IntVar2;
short ShortVar1;
short ShortIV = -1;
short *ShortVar1Ptr = &ShortVar1;
int *IntVar1Ptr = &IntVar1;

unsigned char safeMul(unsigned char si1, unsigned char si2) { return si1 * si2; }

void setVal(char b) { Val = b; }

void fun(int Arg) {  // -4
  long LongLoc;
  signed char CharArr[1][3][2];

  for (; ShortIV >= 0;)
 CharArr[0][2][1]++;

  signed char *CharElPtr = &CharArr[0][2][1];
 for (; ShortIV != 0; ShortIV++) {
    LongLoc = ((((unsigned)*IntVar1Ptr) | 0x5a915f8) * 9) & 0x7fffffffffffffff;
    *CharElPtr = ((unsigned char) (((unsigned long) LongLoc) & 0xff));
    *ShortVar1Ptr = ((signed char) safeMul(((unsigned int) (Arg & 0xff)), *CharElPtr));
    IntVar2 += 1;
 }
}

int main() {
  *IntVar1Ptr = -7;
  fun(-4);
 setVal(ShortVar1 >> 8);
  printf("checksum = %X\n", Val);
}
```

? @dtcxzyw @nikic
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWdtv4ywW_2vIC7Jl4_iShzykTbvq6tv9RrNSd99GxCYJOxi8gNvO_PUrwBfsOJ1eRvqiqHbh8Du_c4NjBytFT5yQLUhvQLpf4Vafhdz-XfAvSgkerw6i-rF90FARUiuoz1jDB670ragPlBMJqYKUl0JKUmr2A0rSMFxSfoIYKvKi4TPVZ4jhT3MPUKEIgQDlILkFyR1AOTwQJp4B2oBkB6I9iPq_WdR97b-MHDUEyQ6WDPMTDP5MYFBjWZ5Bsv8ZZ_BZCn6KQgoDAXEoWg2DIxdBy6VgLGBCNAoGNWNPNewHjy1jQY1fglK0XINkH7s1T6TUQtKfxP2rWDMOOTKSns76ryczYCgpcKC-0yaoSY0kOS26cHkwuYEA7dwXPnyF-7Zu4O6oifTD_AUrBQWHNabck59_PoU2Erpveamp4HCntVTG0Vy0_JnyCr4-7SAqcqScwEqJb0yUmEGb4S8a0gRBsI6MWoAKgDbQzn9rOcc1qb7hqpLWjPzWXD6H47gQruUPQ7G_ccMQApRGECR7yASuYKMlQLfmYoAfuH7EMv7iBjGjJw4LcwtQrA8Ym2uc_AaInozSQhJrVpAPICiNxrXr2dr1Rez7zwewPJ-EjQzpaBSNM8-of52F1A-PIxKaIRV9HuZmOI0_DuRRKuumo0TLuoHqpA3aQNasDOKr7uhy6RdIsUPptB4kpPGwwEwxfCDMjByFDEvBq4Vhs1HHcchk6Kt9C1arXtPi7x7eRLKzxdhIUo36ppCeSO_Pg1zSctV7c08uLre6ZiRHZzTnX5K182_7zO0BKHWlhsJGilpoUk3yN0EXRYnGtLNhn-YIulbRNmffUdPT_P8Y1kUGh40k77DvaqXP49iFi16duBLfVyK7JOH5BlcVSlDaGdOcqdvV05vlkDpDRkrjJpMsATg_eYu6PAfp3g46KVxNkT16aNnH79yT_dCtP4LoMXJ2atny0llqSGoBaTFRk16KrZ2Yh-W4CGkXozSxu98UJ5uKpE7Ew6hbFtIufHXLOjlrQZBk031X8Kd47cly9dzJZ51833zc2a7Urci7FbaNdeK9UmNQnF3ZIUxnC-cgtv_lnJw6pIGTBzU7jt3R0KN4EYt_fQJOov8rPPS2g9CmqzUGV5XzoQvwUEtm8bWjsCuXqyA2CeLLjsSvkzfvMzPdn0TrSA3Z_ZnWZF6W-W_pUSgv48Lzaxfr1AXE13dFMl_yvpvqVnzU2N-ANm3GNiEX2u-jyP8WwKP3SXsH09AudUunnVHLQ_JC9bXua7T6s0iTE6-XfXOfAv1T0X4-g-EFIHs1X01P8Za08DOy-Ayix6yrJHWWfYAt2PRY2VwI2a5nkmJmg5zv2V2V2N06QdcdNj91lnE2HU6ndbI92WWeFx4xe99j2CfQfC9gxix5ezN58kVF102GYWgefsE6aiTl-uhm7NN4RTyn_Aa0npkkblk03nWFku8hyPevveqY_ltiPbyocSOUazioLgVXGpZnLN0bip4fSG58HWZN59PukXu8RYOsMpkMx3xeGH94tP4J5pMA7fxu3QoBlF1iGSYA7cYH_1605zUl3nIbhcqZqPCR_KNlABWzcWrtmQ8iG6j8xgShldyIGd12JrmZx-FJ0Aoqoq2fCgtx6AEescuLw7V1x5YDVBjjdvLUr4IA3QN0D4MhY5ngJ_iH4Kc_RDlYCqFP-_aM5U5KkN7Epg1PbxJ3QeYydY59gjCpaViN4bkzTCMjizad4AgaeWidCnRjvnNonxNAO4Nwx7x4vQo5mLZEEMU9QTgcqpaCc1tPAPaO6jQWw7ePs7HPTyUHcAujlxRv4vRo33mZgG_cTQajl_w4_XhRgEt2FvNkc1AzJjawZqaP7aDveLQsN3M9C9ViAGeKxoSf6aNcd0R28jRXZbfL0ZIFAl3lQxv4PRyrzkvuaZab1PbeJHpxuqzmIPeUucoI1hMKQ5kNbnB5e2ee7n2qw0YHECrPpPyu2rpzV_ofkN5ygOxha9G8XW8gv_hyObk3-3ely5efP57NLaffabmqtkm1STZ4RbZxHkdZhFCcr87b4lBkJItJiUkW5eiwLqI0JgdMSJ7nUYVXdIsitI6SOIvTOEvzMEsPeVHlmyqu0ixZr8E6IjWmLGTsqQ6FPK2oUi3ZFmmapCvbVyn70wZCNVWlqBvKsKaiMw8gZBaCZEe50qV7PW2m0v1Kbs1UcGhPCqwjRpVWoxZNNbO_mXivtUG6h__--uc__wZLURH3w8fFq_lVK9n2rHWjQLJz29iJ6nN7CEtRA3Rv6bhL0EjxX1JqgO6tUQqge2vX_wMAAP___4X1aQ">