From d897a14c2ef756d99344f4fae8864108e0131007 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Thu, 2 Jun 2022 13:42:49 -0400 Subject: [PATCH] [SystemZ] Fix check for zero size when lowering memcmp. During lowering of memcmp/bcmp, the check for a size of 0 is done in 2 different ways. In rare cases this can lead to a crash in SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp(). The root cause is that SelectionDAGBuilder::visitMemCmpBCmpCall() checks for a constant int value which is not yet evaluated. When the value is turned into a SDValue, then the evaluation is done and results in a ConstantSDNode. But EmitTargetCodeForMemcmp() expects the special case of 0 length to be handled, which results in an assertion. The fix is to turn the value into a SDValue, so that both functions use the same check. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D126900 --- .../SelectionDAG/SelectionDAGBuilder.cpp | 2 +- llvm/test/CodeGen/SystemZ/memcmp-03.ll | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/SystemZ/memcmp-03.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index bf4e6a6751c35..a1293d3edab46 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -7902,7 +7902,7 @@ void SelectionDAGBuilder::processIntegerCallValue(const Instruction &I, bool SelectionDAGBuilder::visitMemCmpBCmpCall(const CallInst &I) { const Value *LHS = I.getArgOperand(0), *RHS = I.getArgOperand(1); const Value *Size = I.getArgOperand(2); - const ConstantInt *CSize = dyn_cast(Size); + const ConstantSDNode *CSize = dyn_cast(getValue(Size)); if (CSize && CSize->getZExtValue() == 0) { EVT CallVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(), I.getType(), true); diff --git a/llvm/test/CodeGen/SystemZ/memcmp-03.ll b/llvm/test/CodeGen/SystemZ/memcmp-03.ll new file mode 100644 index 0000000000000..eb11cb187e7d1 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/memcmp-03.ll @@ -0,0 +1,20 @@ +; Test memcmp with 0 size. + +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s +; REQUIRES: asserts + +declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) + +define hidden void @fun() { +; CHECK-LABEL: fun +entry: + %len = extractvalue [2 x i64] zeroinitializer, 1 + br i1 undef, label %end, label %call + +call: + %res = tail call signext i32 @memcmp(i8* noundef undef, i8* noundef undef, i64 noundef %len) + unreachable + +end: + unreachable +}