From 20bf0cf2f020ce3b344838b88d8a86e156c05443 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Wed, 23 Oct 2019 11:58:50 +0300 Subject: [PATCH] [TargetLowering] optimizeSetCCToComparisonWithZero(): add extra sanity checks (PR43769) We should do the fold only if both constants are plain, non-opaque constants, at least that is the DAG.FoldConstantArithmetic() requirement. And if the constant we are comparing with is zero - we shouldn't be trying to do this fold in the first place. Fixes https://bugs.llvm.org/show_bug.cgi?id=43769 --- .../CodeGen/SelectionDAG/TargetLowering.cpp | 8 ++- llvm/test/CodeGen/X86/pr43769.ll | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/pr43769.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index c0b846adc040..5af2663d29e5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3052,6 +3052,10 @@ SDValue TargetLowering::optimizeSetCCToComparisonWithZero( assert((Cond == ISD::SETEQ || Cond == ISD::SETNE) && "Only for equality-comparisons."); + // The constant we are comparing with must be a non-zero, non-opaque constant. + if (N1C->isNullValue() || N1C->isOpaque()) + return SDValue(); + // LHS should not be used elsewhere, to avoid creating an extra node. if (!N0.hasOneUse()) return SDValue(); @@ -3072,9 +3076,9 @@ SDValue TargetLowering::optimizeSetCCToComparisonWithZero( break; } - // Second operand must be a constant. + // Second operand must be a non-opaque constant. ConstantSDNode *N01C = isConstOrConstSplat(N0.getOperand(1)); - if (!N01C) + if (!N01C || N01C->isOpaque()) return SDValue(); // And let's be even more specific for now, it must be a zero constant. diff --git a/llvm/test/CodeGen/X86/pr43769.ll b/llvm/test/CodeGen/X86/pr43769.ll new file mode 100644 index 000000000000..fb6cd95c5325 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr43769.ll @@ -0,0 +1,54 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=i686-w64-windows-gnu %s -o - | FileCheck %s + +; Reduced from https://bugs.llvm.org/show_bug.cgi?id=43769 + +define i32 @b(i32 %a, i32* %c, i32 %d) { +; CHECK-LABEL: b: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpl $0, {{[0-9]+}}(%esp) +; CHECK-NEXT: je LBB0_4 +; CHECK-NEXT: # %bb.1: # %for.body.lr.ph +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: movl %eax, %ecx +; CHECK-NEXT: sarl $31, %ecx +; CHECK-NEXT: addl $-2147483647, %eax # imm = 0x80000001 +; CHECK-NEXT: adcl $0, %ecx +; CHECK-NEXT: jne LBB0_4 +; CHECK-NEXT: # %bb.2: # %for.body.lr.ph.peel.newph +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: movl $-2147483647, %edx # imm = 0x80000001 +; CHECK-NEXT: movl %ecx, %eax +; CHECK-NEXT: sarl $31, %eax +; CHECK-NEXT: addl %ecx, %edx +; CHECK-NEXT: adcl $0, %eax +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: LBB0_3: # %for.body +; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: testl %eax, %eax +; CHECK-NEXT: je LBB0_3 +; CHECK-NEXT: LBB0_4: # %for.end +; CHECK-NEXT: retl +entry: + %tobool3 = icmp eq i32 %a, 0 + br i1 %tobool3, label %for.end, label %for.body.lr.ph + +for.body.lr.ph: ; preds = %entry + %0 = ptrtoint i32* %c to i32 + %conv.peel = sext i32 %d to i64 + %add.peel = add nsw i64 %conv.peel, 2147483649 + %tobool1.peel = icmp ugt i64 %add.peel, 4294967295 + br i1 %tobool1.peel, label %for.end, label %for.body.lr.ph.peel.newph + +for.body.lr.ph.peel.newph: ; preds = %for.body.lr.ph + %conv = sext i32 %0 to i64 + %add = add nsw i64 %conv, 2147483649 + %tobool1 = icmp ugt i64 %add, 4294967295 + br label %for.body + +for.body: ; preds = %for.body, %for.body.lr.ph.peel.newph + br i1 %tobool1, label %for.end, label %for.body + +for.end: ; preds = %for.body.lr.ph, %for.body, %entry + ret i32 undef +}