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

    <tr>
        <th>Summary</th>
        <td>
            [IndVarSimplify] WRONG code with i128 and -replexitval=always
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation,
            loopoptim
      </td>
    </tr>

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

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

<pre>
    This program should print -86:

```
int printf(const char *, ...);

unsigned short a = 0, b = 0;
unsigned __int128 c = 0, d = 0;

unsigned char e(unsigned char f, unsigned char g) { return f + g; }

long h() {
  for (; c != 2; c = e(c, 3)) {
    --d;
    if (d)
      continue;
    return a;
  }
  return b;
}

int main() {
  h();
  printf("%d\n", (int)d);
}
```
With the option -replexitval=always, the IndVarSimplifyPass does something quite weird that I don't understand. It seems it is trying to compute the final value that is stored in the preheader, but that computation is '0', so it must be wrong.

`clang -O3 -march=z15 wrong0.i -o ./a.out    <>  clang -O3 -march=z15 wrong0.i -o ./a.out -mllvm -replexitval=always
`

```
IR Dump After IndVarSimplifyPass on for.body

define dso_local i64 @h() local_unnamed_addr #1 { define dso_local i64 @h() local_unnamed_addr #1 {
entry: entry:
  %.pr = load i128, ptr @c, align 8, !tbaa !4                     %.pr = load i128, ptr @c, align 8, !tbaa !4
  %d.promoted = load i128, ptr @d, align 1, !tbaa !4 %d.promoted = load i128, ptr @d, align 1, !tbaa !4
  %cmp.not5 = icmp eq i128 %.pr, 2                                %cmp.not5 = icmp eq i128 %.pr, 2
  %extract.t9 = trunc i128 %.pr to i8 %extract.t9 = trunc i128 %.pr to i8
  br i1 %cmp.not5, label %return, label %for.body.prehea          br i1 %cmp.not5, label %return, label %for.body.prehea

for.body.preheader:                               ; pred        for.body.preheader:                               ; pred
 >      %0 = add i128 %d.promoted, -1
 >      %1 = mul i8 %extract.t9, 85
 >      %2 = add i8 %1, 85
 >      %3 = zext i8 %2 to i128
 >      %umin = call i128 @llvm.umin.i128(i128 %0, i128 %3)
 >      %4 = sub i128 %0, %umin
  br label %for.body br label %for.body

for.body: ; pred        for.body: ; pred
  %.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, %          %.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, %
  %dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, %          %dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, %
  %dec = add i128 %dec46, -1                                      %dec = add i128 %dec46, -1
 %tobool.not = icmp eq i128 %dec, 0                              %tobool.not = icmp eq i128 %dec, 0
  br i1 %tobool.not, label %for.body.return_crit_edge, l          br i1 %tobool.not, label %for.body.return_crit_edge, l

for.inc: ; pred        for.inc:                                          ; pred
  %add.i = add i8 %.off0, 3 %add.i = add i8 %.off0, 3
  %conv2 = zext i8 %add.i to i128 %conv2 = zext i8 %add.i to i128
  store i128 %conv2, ptr @c, align 8, !tbaa !4                    store i128 %conv2, ptr @c, align 8, !tbaa !4
  %cmp.not = icmp eq i8 %add.i, 2 %cmp.not = icmp eq i8 %add.i, 2
  br i1 %cmp.not, label %for.cond.return_crit_edge, labe          br i1 %cmp.not, label %for.cond.return_crit_edge, labe

for.cond.return_crit_edge: ; pred        for.cond.return_crit_edge:                        ; pred
  %dec.lcssa10 = phi i128 [ %dec, %for.inc ]               | store i128 %4, ptr @d, align 8, !tbaa !4
  store i128 %dec.lcssa10, ptr @d, align 8, !tbaa !4       <
  br label %return br label %return

for.body.return_crit_edge: ; pred        for.body.return_crit_edge: ; pred
  %dec.lcssa = phi i128 [ %dec, %for.body ]                | store i128 %4, ptr @d, align 8, !tbaa !4
  store i128 %dec.lcssa, ptr @d, align 8, !tbaa !4         <
  br label %return br label %return

return: ; pred        return: ; pred
  %retval.0.in.in = phi ptr [ @a, %for.body.return_crit_ %retval.0.in.in = phi ptr [ @a, %for.body.return_crit_
  %retval.0.in = load i16, ptr %retval.0.in.in, align 2,          %retval.0.in = load i16, ptr %retval.0.in.in, align 2,
  %retval.0 = zext i16 %retval.0.in to i64 %retval.0 = zext i16 %retval.0.in to i64
  ret i64 %retval.0                                               ret i64 %retval.0
} }
;
```

@nikic @xortator @uweigand 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WF2TojgX_jXx5pQUBFC88KK7ffut3oudqdmtnUsrJFGyCwmThP6YX7-VgAiK0_Y4a3W1Ep7znO9DCDFG7CXna5Teo3QzI40tlF7_puRnY5SMZrlib-s_C2Gg1mqvSQWmUE3JoNZCWphnCxTfoXCDwsP_Rdj9-UsH8tAdwhlV0ligBdGA8B3CDxAEAcIrFN8PKRrpjWJOlbZAAMUbCB08734e8D1yuxXSRjgDegSzE_CJiDeDI5yNV3ZOdLy0R3gFaHkPmttGS9gBwvewR_E9oOVmSF4quYcC4ayTaFcBdsp5nDkJCghHzjDcXcUbbwV1emMXjLEowHzOeh_ctXD6M-ag_RoAVdIK2fARtDOYDBZ7i_u7-TFCY29c7ioi5Lk_nYsD2j7HCGOEU4bSB-l_PjhjhbQIr9go1b2uccF8FbYAW3BQtRVKwlzzuuSvwj6TEsUbUr6QN-NoHeZJsr-I_kNUdSl2b5-JMcAUN2BUxW0h5B6-NcJyeOFCM7AFsfAETEmElxYaybg2lkgWwJMFw3llQFgQBqx-c8JWAVVV3Vjute2EJCU8k7LhLZcwYKzSnIGQHlFrXnDCuPbF2tgW1nIQ744wgPAyRHjpIEY5hVVjLOQcXrSS--CkmWhJ5B7mn2KYV0TTAsWb71HaYsNAwFxBgPAjCVRjXcpR_IDi_wF8SG5eleVzdSHWfZYud_nTF9g0VQ13O8v1VFaUdD0QuGkypGF8JyQHZtS2VJSUIBYJoCQ8tJBf3DZSkoqzLWHMtVEc-Wa8QbZVzqXVbyi-g8OPvkVwGtTad2apCAMROcYHqK12CnynklLsJWRtfUc2J8R9JzD1uYFvYBILaq0qZTm7yMSOTNGZZbdTDIyhVR1IZVPPI2hVA__mqTpnnSieDMY4LlfxDPTyV6sJtYFdeQmrG0mHeNeyIrseeaDONYhoaJBTXJKcl26xHZSjpUM1B23LH526lWnYHie33FyJ794LanzvxhA7XN_C0UXHz5MuYaGPJmGsj-WxqJxb82hCKPJCVVOe5caJZOmECD7q8SLRRWTskd_5q-2g2KfWlfU5uKmE9HhKyrJzIQnd8AvcraDthuzgm99HHC7i4xN3SJl4PtPkMJLqlA0K7Czjk4tT-XcZu5TX4b3hAFO7XZuruhA-MOm9WyeMBaKzz1EISQGlG7_SIsbJQTgdD7JfxzucbZwmiyOrj2MrxTj9Ieu4-k6t_YW8Y2vPu8BpahvgneYaWfcjnkOt4dSqXKnSTZPJOdn5Er6r8Eqes6F4lJueXO1U21It7JazPfeoo-bbeE4bQkh6qR-6W1d_JvrG1_HJ7PE177fn7yOGz0gln_HpcGqluwF1HepA6beaY7kbdiU_z3a-DRhXUzaaB_ha3KVH8VmpUCXZdKmQnE9U3U_xnFbdNPhCHV4EX1-HjNOgpMaQKLx-fp3SLh9O0pxM7_QupngsPbDpSp7ev4ep5-Dh_fNsaXIPdG3w3wVPRfmKGPsn9nmQ_7sofyzGt0W5W5kI6fmdQfw0d6-KQRi4rZPsg-itdjFMQnISwVFmfgHFtDHD15tFH8dTZceg-tF3DOTNXBNWDUZ8tDhV4Sb9IvkgfHCMcyb9sc8EQ39IMzji6o9uxi__3f8klOIfQV3GXpW2xCpfus0LF3siGczYOmareEVmfB0tw1UUR1Eazop1stgts4jEyyXhOIlznC2Wy3TFc8oXYZ6nM7HGIU5CjLMoiVdRGDCM0yUlKxphkoUsQknIKyLKwG_kld7PhDENX2cxXmQzX_bGn3BiXAlDVVWL0h_HtCdUCONSqVrVVlRuJd3M9NpRzfNmb9z7gTDWHMmtsKU_MR0fdLjZ8PXLp9__D1QxDi_CFm1TO-8nj1ZmjS7XhbW1QfEdwo8IP-6FLZo8oKpC-NFp7L7mtVZ_c2oRfvS-GYQfvXv_BgAA___x6f_c">