Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp: InstCombinerImpl::foldICmpShlConstant
Issue title: wrong code at -O1 and above on x86_64-linux-gnu
Labels: miscompilation
confirmed
llvm:instcombine
Reported by: zhendongsu

This appears to be a recent regression as it doesn't reproduce with 18.1.0 and earlier.

Compiler Explorer: https://godbolt.org/z/T9b4a7z3v

```console
% clangtk -v
clang version 19.0.0git (https://github.com/llvm/llvm-project.git 338cbfef03e0ab58d7b52f3301928c58b194a1b4)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /local/suz-local/software/local/clang-trunk/bin
Build config: +assertions
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Candidate multilib: .;@m64
Selected multilib: .;@m64
% 
% clangtk -O0 small.c; ./a.out
% clangtk -O1 small.c
% ./a.out
Aborted
% cat small.c
int a;
char b(char c, char d) { return c - d; }
int main() {
  int e;
  for (a = -10; a > -11; a--)
    e = b(a, -1);
  if (e > -2)
    __builtin_abort();
  return 0;
}
```

Comments: author: dtcxzyw
body: Reproducer: https://alive2.llvm.org/ce/z/_3cyuT
```ll
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"

define i1 @src() {
entry:
  br label %for.body

for.body:
  %storemerge4 = phi i32 [ -10, %entry ], [ %dec, %for.body ]
  %dec = add nsw i32 %storemerge4, -1
  %cmp = icmp ugt i32 %dec, -11
  br i1 %cmp, label %for.body, label %for.end

for.end:
  %sub.i.le = shl nsw i32 %storemerge4, 24
  %cmp2 = icmp ugt i32 %sub.i.le, -50331648
  ret i1 %cmp2
}

define i1 @tgt() {
entry:
  br label %for.body

for.body:
  %storemerge4 = phi i32 [ -10, %entry ], [ %dec, %for.body ]
  %dec = add nsw i32 %storemerge4, -1
  %cmp = icmp ugt i32 %dec, -11
  br i1 %cmp, label %for.body, label %for.end

for.end:
  %0 = trunc nuw i32 %storemerge4 to i8
  %cmp2 = icmp ugt i8 %0, -3
  ret i1 %cmp2
}
```

`nuw` flag is incorrectly added.
author: dtcxzyw
body: Caused by https://github.com/llvm/llvm-project/commit/5c7c1f6aba467b1c5a51d58fc591314ecd7147ce.

Fix patch:
commit e4b0655b297e4f4b0eb26548c8be48d527ebc178
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Mon Jun 10 03:17:01 2024 +0800

    [InstCombine] Fix missing argument typo in `InstCombinerImpl::foldICmpShlConstant` (#94899)
    
    Closes #94897.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 4203147bc6a5..3fce4a3c20b3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2441,9 +2441,10 @@ Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
       Type *TruncTy = ShType->getWithNewBitWidth(TypeBits - Amt);
       Constant *NewC =
           ConstantInt::get(TruncTy, RHSC.ashr(*ShiftAmt).trunc(TypeBits - Amt));
-      return new ICmpInst(
-          CmpPred, Builder.CreateTrunc(X, TruncTy, "", Shl->hasNoSignedWrap()),
-          NewC);
+      return new ICmpInst(CmpPred,
+                          Builder.CreateTrunc(X, TruncTy, "", /*IsNUW=*/false,
+                                              Shl->hasNoSignedWrap()),
+                          NewC);
     }
   }
 


Regression tests:
file: llvm/test/Transforms/InstCombine/icmp.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: test_icmp_shl_sgt
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @test_icmp_shl_sgt(i64 %x) {
  %shl = shl i64 %x, 32
  %cmp = icmp sgt i64 %shl, 8589934591
  ret i1 %cmp
}

test_name: test_icmp_shl_nuw_i31
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @test_icmp_shl_nuw_i31(i31 %x) {
  %shl = shl nuw i31 %x, 23
  %cmp = icmp ugt i31 %shl, -50331648
  ret i1 %cmp
}

test_name: test_icmp_shl_vec
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define <2 x i1> @test_icmp_shl_vec(<2 x i64> %x) {
  %shl = shl <2 x i64> %x, splat (i64 32)
  %cmp = icmp ult <2 x i64> %shl, splat (i64 8589934593)
  ret <2 x i1> %cmp
}

test_name: test_icmp_shl_nsw_i31
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @test_icmp_shl_nsw_i31(i31 %x) {
  %shl = shl nsw i31 %x, 23
  %cmp = icmp ugt i31 %shl, -50331648
  ret i1 %cmp
}

test_name: test_icmp_shl_nsw
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @test_icmp_shl_nsw(i64 %x) {
  %shl = shl nsw i64 %x, 32
  %cmp = icmp ult i64 %shl, 8589934593
  ret i1 %cmp
}

test_name: pr94897
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @pr94897(i32 range(i32 -2147483648, 0) %x) {
  %shl = shl nsw i32 %x, 24
  %cmp = icmp ugt i32 %shl, -50331648
  ret i1 %cmp
}

test_name: test_icmp_shl_nuw
test_body: target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

define i1 @test_icmp_shl_nuw(i64 %x) {
  %shl = shl nuw i64 %x, 32
  %cmp = icmp ult i64 %shl, 8589934593
  ret i1 %cmp
}