Bug type: crash
Component: ConstantFold
Bug location: llvm/lib/Analysis/ConstantFolding.cpp: ConstantFoldFixedVectorCall
Issue title: [WebAssembly] Assertion `llvm::isUIntN(BitWidth, val) && "Value is not an N-bit unsigned value"' failed
Labels: crash
constant-folding
Reported by: mr-c

Reproduced using 804aa88317ddbdb6e713306d48dbee0443b252b1

git-bisecting from the emscripten side narrowed down the introduction of the crash to https://github.com/llvm/llvm-project/compare/55eaa6c27b36...88b77d5eaa66


[26060.zip](https://github.com/user-attachments/files/24526777/26060.zip)

Emscripten issue: https://github.com/emscripten-core/emscripten/issues/26060#issue-3795333593

Comments: author: mr-c
body: I've git-bisected this to a83c89495ba6fe0134dcaa02372c320cc7ff0dbf
Tagging @nikic 
author: nikic
body: Reduced:
```llvm
; RUN: opt -S -passes=instsimplify < %s
target triple = "wasm32-unknown-emscripten"

define <4 x i32> @test() {
  %dot = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> <i16 19733, i16 18694, i16 -2158, i16 -12949, i16 -22664, i16 -3805, i16 30779, i16 1600>, <8 x i16> <i16 11918, i16 7268, i16 32199, i16 14806, i16 -14152, i16 -23986, i16 16941, i16 17135>)
  ret <4 x i32> %dot
}
```
author: mr-c
body: Thank you for the quick fix @nikic ! I can confirm it from my end using emscripten + https://github.com/llvm/llvm-project/commit/4996e3be341af782b856597023c83ee3ef9b5094 and the entire SIMDe test suite

Fix patch:
commit 4996e3be341af782b856597023c83ee3ef9b5094
Author: Nikita Popov <npopov@redhat.com>
Date:   Fri Jan 9 17:13:21 2026 +0100

    [ConstantFolding] Allow truncation when folding wasm.dot
    
    Changes this to getSigned() to match the signedness of the calculation.
    However, we still need to allow truncation because the addition
    result may overflow, and the operation is specified to truncate
    in that case.
    
    Fixes https://github.com/llvm/llvm-project/issues/175159.

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index c3a3035fcaa9..eaf4eb445423 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -4288,7 +4288,7 @@ static Constant *ConstantFoldFixedVectorCall(
     }
     for (unsigned I = 0; I < Result.size(); I++) {
       int64_t IAdd = (int64_t)MulVector[I * 2] + (int64_t)MulVector[I * 2 + 1];
-      Result[I] = ConstantInt::get(Ty, IAdd);
+      Result[I] = ConstantInt::getSigned(Ty, IAdd, /*ImplicitTrunc=*/true);
     }
 
     return ConstantVector::get(Result);


Regression tests:
file: llvm/test/Transforms/InstSimplify/ConstProp/WebAssembly/dot.ll
commands: opt -passes=instsimplify -S < %s
tests: test_name: dot_one_negative
test_body: target triple = "wasm32-unknown-unknown"

define <4 x i32> @dot_one_negative() {
  %res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> splat (i16 1), <8 x i16> splat (i16 -1))
  ret <4 x i32> %res
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i32> @llvm.wasm.dot(<8 x i16>, <8 x i16>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: dot_doubly_negative
test_body: target triple = "wasm32-unknown-unknown"

define <4 x i32> @dot_doubly_negative() {
  %res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> splat (i16 -1), <8 x i16> splat (i16 -1))
  ret <4 x i32> %res
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i32> @llvm.wasm.dot(<8 x i16>, <8 x i16>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

test_name: dot_nonzero
test_body: target triple = "wasm32-unknown-unknown"

define <4 x i32> @dot_nonzero() {
  %res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, <8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>)
  ret <4 x i32> %res
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <4 x i32> @llvm.wasm.dot(<8 x i16>, <8 x i16>) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }