From a860a0729a2eae2079be1fa5813e73aa18441f6b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 12 Aug 2017 20:19:44 +0000 Subject: [PATCH] [X86] When handling addcarry intrinsic, create the flag result with the correct type so we don't crash if we use a memory instruction Summary: Previously we were creating the flag result with MVT::Other which is interpretted as a Chain node. If we used a memory form of the instruction we would end up with a copyToReg that consumed the chain result of the adcx instruction instead of the flag result. Pretty sure we should be using MVT::i32 here, that's what we do other places we create these node types. We should probably consider this for 5.0 as well. Reviewers: RKSimon, zvi, spatel Reviewed By: RKSimon Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D36645 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310784 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 4 ++-- test/CodeGen/X86/adx-intrinsics.ll | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 5109b742949..23f27002120 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -20618,8 +20618,8 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget &Subtarget, } // ADC/ADCX/SBB case ADX: { - SDVTList CFVTs = DAG.getVTList(Op->getValueType(0), MVT::Other); - SDVTList VTs = DAG.getVTList(Op.getOperand(3)->getValueType(0), MVT::Other); + SDVTList CFVTs = DAG.getVTList(Op->getValueType(0), MVT::i32); + SDVTList VTs = DAG.getVTList(Op.getOperand(3)->getValueType(0), MVT::i32); SDValue GenCF = DAG.getNode(X86ISD::ADD, dl, CFVTs, Op.getOperand(2), DAG.getConstant(-1, dl, MVT::i8)); SDValue Res = DAG.getNode(IntrData->Opc0, dl, VTs, Op.getOperand(3), diff --git a/test/CodeGen/X86/adx-intrinsics.ll b/test/CodeGen/X86/adx-intrinsics.ll index 0498177a9c1..819a5df14e6 100644 --- a/test/CodeGen/X86/adx-intrinsics.ll +++ b/test/CodeGen/X86/adx-intrinsics.ll @@ -75,3 +75,30 @@ define i8 @test_subborrow_u64(i8 %c, i64 %a, i64 %b, i8* %ptr) { ret i8 %ret; } +; Try a version with loads. Previously we crashed on this. +define i32 @load_crash(i64* nocapture readonly %a, i64* nocapture readonly %b, i64* %res) { +; CHECK-LABEL: load_crash +; CHECK: addb +; ADX: adcxq +; CHECK: setb +; CHECK: retq + %1 = load i64, i64* %a, align 8 + %2 = load i64, i64* %b, align 8 + %3 = bitcast i64* %res to i8* + %4 = tail call i8 @llvm.x86.addcarryx.u64(i8 0, i64 %1, i64 %2, i8* %3) + %conv = zext i8 %4 to i32 + ret i32 %conv +} + +; Try a really simple all zero input case, which also used to crash +define void @allzeros() { +; CHECK-LABEL: allzeros +; CHECK: xorl +; CHECK: addb +; CHECK: sbbq +; CHECK: andl +; CHECK: retq +entry: + %0 = tail call i8 @llvm.x86.addcarryx.u64(i8 0, i64 0, i64 0, i8* null) + ret void +} -- 2.50.1