diff options
author | Sudharsan Veeravalli <quic_svs@quicinc.com> | 2024-03-29 09:52:05 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-28 21:22:05 -0700 |
commit | e005a09df5b5c7d210ac7cd8cbddb3a4a8663173 (patch) | |
tree | 3547f9bb46bc8bcb8feefb97cf4a9118a3617476 | |
parent | c64a328cb4a32e81f8b694162750ec1b8823994c (diff) |
[RISCV][TypePromotion] Dont generate truncs if PromotedType is greater than Source Type (#86941)
We currently check if the source and promoted types are not equal before
generating truncate instructions. This does not work for RV64 where the
promoted type is i64 and this lead to a crash due to the generation of
truncate instructions from i32 to i64.
Fixes #86400
-rw-r--r-- | llvm/lib/CodeGen/TypePromotion.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/rv64-typepromotion.ll | 27 |
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp index b0830308908d..89aea3a29161 100644 --- a/llvm/lib/CodeGen/TypePromotion.cpp +++ b/llvm/lib/CodeGen/TypePromotion.cpp @@ -643,7 +643,7 @@ void IRPromoter::ConvertTruncs() { ConstantInt *Mask = ConstantInt::get(SrcTy, APInt::getMaxValue(NumBits).getZExtValue()); Value *Masked = Builder.CreateAnd(Trunc->getOperand(0), Mask); - if (SrcTy != ExtTy) + if (SrcTy->getBitWidth() > ExtTy->getBitWidth()) Masked = Builder.CreateTrunc(Masked, ExtTy); if (auto *I = dyn_cast<Instruction>(Masked)) diff --git a/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll b/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll new file mode 100644 index 000000000000..23eae33739c9 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -mtriple=riscv64 -passes=typepromotion -S %s | FileCheck %s + +; Test that this does not crash +define i16 @test(i8 %a, i32 %b) { +; CHECK-LABEL: define i16 @test( +; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[A]] to i32 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i16 +; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i64 +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64 +; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], [[TMP2]] +; CHECK-NEXT: [[TMP7:%.*]] = trunc i64 [[TMP6]] to i16 +; CHECK-NEXT: ret i16 [[TMP7]] +; +entry: + %0 = zext i8 %a to i32 + %1 = trunc i32 %b to i16 + %2 = icmp eq i16 %1, 0 + %3 = trunc i32 %0 to i8 + %4 = zext i8 %3 to i16 + %5 = xor i16 %4, %1 + ret i16 %5 +} |