From: Ahmed Bougacha Date: Tue, 17 Jan 2017 03:31:00 +0000 (+0000) Subject: Revert "[TLI] Robustize SDAG proto checking by merging it into TLI." X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce7126af56f3e8dbe955e2ee4eb5b35e76e3ac7d;p=llvm Revert "[TLI] Robustize SDAG proto checking by merging it into TLI." This reverts commit r292189, as it causes issues on SystemZ bots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292191 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 5cd2159b189..c1eef4dced0 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5976,7 +5976,16 @@ void SelectionDAGBuilder::processIntegerCallValue(const Instruction &I, /// If so, return true and lower it, otherwise return false and it will be /// lowered like a normal call. bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) { + // Verify that the prototype makes sense. int memcmp(void*,void*,size_t) + if (I.getNumArgOperands() != 3) + return false; + const Value *LHS = I.getArgOperand(0), *RHS = I.getArgOperand(1); + if (!LHS->getType()->isPointerTy() || !RHS->getType()->isPointerTy() || + !I.getArgOperand(2)->getType()->isIntegerTy() || + !I.getType()->isIntegerTy()) + return false; + const Value *Size = I.getArgOperand(2); const ConstantInt *CSize = dyn_cast(Size); if (CSize && CSize->getZExtValue() == 0) { @@ -6070,9 +6079,18 @@ bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) { /// form. If so, return true and lower it, otherwise return false and it /// will be lowered like a normal call. bool SelectionDAGBuilder::visitMemChrCall(const CallInst &I) { + // Verify that the prototype makes sense. void *memchr(void *, int, size_t) + if (I.getNumArgOperands() != 3) + return false; + const Value *Src = I.getArgOperand(0); const Value *Char = I.getArgOperand(1); const Value *Length = I.getArgOperand(2); + if (!Src->getType()->isPointerTy() || + !Char->getType()->isIntegerTy() || + !Length->getType()->isIntegerTy() || + !I.getType()->isPointerTy()) + return false; const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo(); std::pair Res = @@ -6092,6 +6110,11 @@ bool SelectionDAGBuilder::visitMemChrCall(const CallInst &I) { /// visitMemPCpyCall -- lower a mempcpy call as a memcpy followed by code to /// to adjust the dst pointer by the size of the copied memory. bool SelectionDAGBuilder::visitMemPCpyCall(const CallInst &I) { + + // Verify argument count: void *mempcpy(void *, const void *, size_t) + if (I.getNumArgOperands() != 3) + return false; + SDValue Dst = getValue(I.getArgOperand(0)); SDValue Src = getValue(I.getArgOperand(1)); SDValue Size = getValue(I.getArgOperand(2)); @@ -6130,7 +6153,15 @@ bool SelectionDAGBuilder::visitMemPCpyCall(const CallInst &I) { /// optimized form. If so, return true and lower it, otherwise return false /// and it will be lowered like a normal call. bool SelectionDAGBuilder::visitStrCpyCall(const CallInst &I, bool isStpcpy) { + // Verify that the prototype makes sense. char *strcpy(char *, char *) + if (I.getNumArgOperands() != 2) + return false; + const Value *Arg0 = I.getArgOperand(0), *Arg1 = I.getArgOperand(1); + if (!Arg0->getType()->isPointerTy() || + !Arg1->getType()->isPointerTy() || + !I.getType()->isPointerTy()) + return false; const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo(); std::pair Res = @@ -6151,7 +6182,15 @@ bool SelectionDAGBuilder::visitStrCpyCall(const CallInst &I, bool isStpcpy) { /// If so, return true and lower it, otherwise return false and it will be /// lowered like a normal call. bool SelectionDAGBuilder::visitStrCmpCall(const CallInst &I) { + // Verify that the prototype makes sense. int strcmp(void*,void*) + if (I.getNumArgOperands() != 2) + return false; + const Value *Arg0 = I.getArgOperand(0), *Arg1 = I.getArgOperand(1); + if (!Arg0->getType()->isPointerTy() || + !Arg1->getType()->isPointerTy() || + !I.getType()->isIntegerTy()) + return false; const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo(); std::pair Res = @@ -6172,7 +6211,13 @@ bool SelectionDAGBuilder::visitStrCmpCall(const CallInst &I) { /// form. If so, return true and lower it, otherwise return false and it /// will be lowered like a normal call. bool SelectionDAGBuilder::visitStrLenCall(const CallInst &I) { + // Verify that the prototype makes sense. size_t strlen(char *) + if (I.getNumArgOperands() != 1) + return false; + const Value *Arg0 = I.getArgOperand(0); + if (!Arg0->getType()->isPointerTy() || !I.getType()->isIntegerTy()) + return false; const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo(); std::pair Res = @@ -6191,7 +6236,15 @@ bool SelectionDAGBuilder::visitStrLenCall(const CallInst &I) { /// form. If so, return true and lower it, otherwise return false and it /// will be lowered like a normal call. bool SelectionDAGBuilder::visitStrNLenCall(const CallInst &I) { + // Verify that the prototype makes sense. size_t strnlen(char *, size_t) + if (I.getNumArgOperands() != 2) + return false; + const Value *Arg0 = I.getArgOperand(0), *Arg1 = I.getArgOperand(1); + if (!Arg0->getType()->isPointerTy() || + !Arg1->getType()->isIntegerTy() || + !I.getType()->isIntegerTy()) + return false; const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo(); std::pair Res = @@ -6212,8 +6265,11 @@ bool SelectionDAGBuilder::visitStrNLenCall(const CallInst &I) { /// and return true. bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I, unsigned Opcode) { - // We already checked this call's prototype; verify it doesn't modify errno. - if (!I.onlyReadsMemory()) + // Sanity check that it really is a unary floating-point call. + if (I.getNumArgOperands() != 1 || + !I.getArgOperand(0)->getType()->isFloatingPointTy() || + I.getType() != I.getArgOperand(0)->getType() || + !I.onlyReadsMemory()) return false; SDValue Tmp = getValue(I.getArgOperand(0)); @@ -6226,8 +6282,12 @@ bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I, /// and return true. bool SelectionDAGBuilder::visitBinaryFloatCall(const CallInst &I, unsigned Opcode) { - // We already checked this call's prototype; verify it doesn't modify errno. - if (!I.onlyReadsMemory()) + // Sanity check that it really is a binary floating-point call. + if (I.getNumArgOperands() != 2 || + !I.getArgOperand(0)->getType()->isFloatingPointTy() || + I.getType() != I.getArgOperand(0)->getType() || + I.getType() != I.getArgOperand(1)->getType() || + !I.onlyReadsMemory()) return false; SDValue Tmp0 = getValue(I.getArgOperand(0)); @@ -6269,16 +6329,18 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { // some reason. LibFunc::Func Func; if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() && - LibInfo->getLibFunc(*F, Func) && + LibInfo->getLibFunc(F->getName(), Func) && LibInfo->hasOptimizedCodeGen(Func)) { switch (Func) { default: break; case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl: - // We already checked this call's prototype; verify it doesn't modify - // errno. - if (I.onlyReadsMemory()) { + if (I.getNumArgOperands() == 2 && // Basic sanity checks. + I.getArgOperand(0)->getType()->isFloatingPointTy() && + I.getType() == I.getArgOperand(0)->getType() && + I.getType() == I.getArgOperand(1)->getType() && + I.onlyReadsMemory()) { SDValue LHS = getValue(I.getArgOperand(0)); SDValue RHS = getValue(I.getArgOperand(1)); setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurSDLoc(), diff --git a/test/CodeGen/X86/memcmp.ll b/test/CodeGen/X86/memcmp.ll index 02e2e1be547..6a51d60f636 100644 --- a/test/CodeGen/X86/memcmp.ll +++ b/test/CodeGen/X86/memcmp.ll @@ -7,11 +7,11 @@ @.str = private constant [23 x i8] c"fooooooooooooooooooooo\00", align 1 ; <[23 x i8]*> [#uses=1] -declare i32 @memcmp(i8*, i8*, i64) +declare i32 @memcmp(...) define void @memcmp2(i8* %X, i8* %Y, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* %Y, i32 2) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -30,7 +30,7 @@ return: ; preds = %entry define void @memcmp2a(i8* %X, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 1), i64 2) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 1), i32 2) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -47,7 +47,7 @@ return: ; preds = %entry define void @memcmp2nb(i8* %X, i8* %Y, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* %Y, i64 2) nounwind nobuiltin ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* %Y, i32 2) nounwind nobuiltin ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -63,7 +63,7 @@ return: ; preds = %entry define void @memcmp4(i8* %X, i8* %Y, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* %Y, i64 4) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* %Y, i32 4) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -80,7 +80,7 @@ return: ; preds = %entry define void @memcmp4a(i8* %X, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 1), i64 4) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 1), i32 4) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -96,7 +96,7 @@ return: ; preds = %entry define void @memcmp8(i8* %X, i8* %Y, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* %Y, i64 8) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* %Y, i32 8) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb @@ -113,7 +113,7 @@ return: ; preds = %entry define void @memcmp8a(i8* %X, i32* nocapture %P) nounwind { entry: - %0 = tail call i32 @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), i64 8) nounwind ; [#uses=1] + %0 = tail call i32 (...) @memcmp(i8* %X, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), i32 8) nounwind ; [#uses=1] %1 = icmp eq i32 %0, 0 ; [#uses=1] br i1 %1, label %return, label %bb diff --git a/test/CodeGen/X86/mempcpy-32.ll b/test/CodeGen/X86/mempcpy-32.ll deleted file mode 100644 index 108442f6b64..00000000000 --- a/test/CodeGen/X86/mempcpy-32.ll +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: llc < %s -mtriple=i686-unknown-linux -O2 | FileCheck %s - -; This tests the i686 lowering of mempcpy. -; Also see mempcpy.ll - -@G = common global i8* null, align 8 - -; CHECK-LABEL: RET_MEMPCPY: -; CHECK: movl [[REG:%e[a-z0-9]+]], {{.*}}G -; CHECK: calll {{.*}}memcpy -; CHECK: movl [[REG]], %eax -; -define i8* @RET_MEMPCPY(i8* %DST, i8* %SRC, i32 %N) { - %add.ptr = getelementptr inbounds i8, i8* %DST, i32 %N - store i8* %add.ptr, i8** @G, align 8 - %call = tail call i8* @mempcpy(i8* %DST, i8* %SRC, i32 %N) - ret i8* %call -} - -declare i8* @mempcpy(i8*, i8*, i32) diff --git a/test/CodeGen/X86/mempcpy.ll b/test/CodeGen/X86/mempcpy.ll index f8db255c1a4..1c737b64402 100644 --- a/test/CodeGen/X86/mempcpy.ll +++ b/test/CodeGen/X86/mempcpy.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=x86_64-unknown-linux -O2 | FileCheck %s +; RUN: llc < %s -mtriple=i686-unknown-linux -O2 | FileCheck %s ; This test checks that: ; (1) mempcpy is lowered as memcpy, and @@ -10,15 +11,12 @@ ; the first instance to be reused as the return value. This allows the check for ; (2) to be expressed as verifying that the MOV to store DST+N to G and ; the MOV to copy DST+N to %rax use the same source register. - -; Also see mempcpy-32.ll - @G = common global i8* null, align 8 ; CHECK-LABEL: RET_MEMPCPY: -; CHECK: movq [[REG:%r[a-z0-9]+]], {{.*}}G -; CHECK: callq {{.*}}memcpy -; CHECK: movq [[REG]], %rax +; CHECK: mov{{.*}} [[REG:%[er][a-z0-9]+]], {{.*}}G +; CHECK: call{{.*}} {{.*}}memcpy +; CHECK: mov{{.*}} [[REG]], %{{[er]}}ax ; define i8* @RET_MEMPCPY(i8* %DST, i8* %SRC, i64 %N) { %add.ptr = getelementptr inbounds i8, i8* %DST, i64 %N