diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -1892,12 +1892,9 @@ switch (Constraint[1]) { default: return false; - case 'm': - // 'Ym' is synonymous with 'y'. case 'k': return Size <= 64; case 'z': - case '0': // XMM0/YMM/ZMM0 if (FeatureMap.lookup("avx512f")) // ZMM0 can be used if target supports AVX512F. @@ -1908,15 +1905,8 @@ else if (FeatureMap.lookup("sse")) return Size <= 128U; return false; - case 'i': - case 't': - case '2': - // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled. - if (SSELevel < SSE2) - return false; - break; } - LLVM_FALLTHROUGH; + break; case 'v': case 'x': if (FeatureMap.lookup("avx512f")) @@ -1926,7 +1916,6 @@ // 256-bit ymm registers can be used if target supports AVX. return Size <= 256U; return Size <= 128U; - } return true; @@ -1967,12 +1956,7 @@ // the return string. break; case 'k': - case 'm': - case 'i': - case 't': case 'z': - case '0': - case '2': // "^" hints llvm that this is a 2 letter constraint. // "Constraint++" is used to promote the string iterator // to the next constraint. diff --git a/clang/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c b/clang/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c --- a/clang/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c +++ b/clang/test/CodeGen/x86-GCC-inline-asm-Y-constraints.c @@ -4,65 +4,14 @@ // At this level we can only check if the constarints are passed correctly // from inline asm to llvm IR. -// CHECK-LABEL: @f_Ym -void f_Ym(__m64 m) - { - // CHECK: movq $0, %mm1 - // CHECK-SAME: "=^Ym,~{dirflag},~{fpsr},~{flags}" - __asm__ volatile ("movq %0, %%mm1\n\t" - :"=Ym" (m)); -} - -// CHECK-LABEL: f_Yi -void f_Yi(__m128 x, __m128 y, __m128 z) - { - // CHECK: vpaddq - // CHECK-SAME: "=^Yi,^Yi,^Yi,~{dirflag},~{fpsr},~{flags}" - __asm__ volatile ("vpaddq %0, %1, %2\n\t" - :"=Yi" (x) - :"Yi" (y),"Yi"(z)); -} - -// CHECK-LABEL: f_Yt -void f_Yt(__m128 x, __m128 y, __m128 z) - { - // CHECK: vpaddq - // CHECK-SAME: "=^Yt,^Yt,^Yt,~{dirflag},~{fpsr},~{flags}" - __asm__ volatile ("vpaddq %0, %1, %2\n\t" - :"=Yt" (x) - :"Yt" (y),"Yt"(z)); -} - -// CHECK-LABEL: f_Y2 -void f_Y2(__m128 x, __m128 y, __m128 z) - { - // CHECK: vpaddq - // CHECK-SAME: "=^Y2,^Y2,^Y2,~{dirflag},~{fpsr},~{flags}" - __asm__ volatile ("vpaddq %0, %1, %2\n\t" - :"=Y2" (x) - :"Y2" (y),"Y2"(z)); -} - // CHECK-LABEL: f_Yz void f_Yz(__m128 x, __m128 y, __m128 z) { // CHECK: vpaddq // CHECK-SAME: vpaddq - // CHECK-SAME: "=^Yi,=^Yz,^Yi,0,~{dirflag},~{fpsr},~{flags}" + // CHECK-SAME: "=x,=^Yz,x,0,~{dirflag},~{fpsr},~{flags}" __asm__ volatile ("vpaddq %0,%2,%1\n\t" "vpaddq %1,%0,%2\n\t" - :"+Yi"(z),"=Yz" (x) - :"Yi" (y) ); -} - -// CHECK-LABEL: f_Y0 -void f_Y0(__m128 x, __m128 y, __m128 z) - { - // CHECK: vpaddq - // CHECK-SAME: "=^Yi,=^Y0,^Yi,0,~{dirflag},~{fpsr},~{flags}" - __asm__ volatile ("vpaddq %0,%2,%1\n\t" - "vpaddq %1,%0,%2\n\t" - :"+Yi"(z),"=Y0" (x) - :"Yi" (y) ); + :"+x"(z),"=Yz" (x) + :"x" (y) ); } - diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -47941,7 +47941,6 @@ case 'y': case 'x': case 'v': - case 'Y': case 'l': case 'k': // AVX512 masking registers. return C_RegisterClass; @@ -47978,13 +47977,8 @@ default: break; case 'z': - case '0': return C_Register; - case 'i': - case 'm': case 'k': - case 't': - case '2': return C_RegisterClass; } } @@ -48035,17 +48029,13 @@ weight = CW_SpecificReg; break; case 'Y': { - unsigned Size = StringRef(constraint).size(); - // Pick 'i' as the next char as 'Yi' and 'Y' are synonymous, when matching 'Y' - char NextChar = Size == 2 ? constraint[1] : 'i'; - if (Size > 2) + if (StringRef(constraint).size() != 2) break; - switch (NextChar) { + switch (constraint[1]) { default: return CW_Invalid; // XMM0 case 'z': - case '0': if (((type->getPrimitiveSizeInBits() == 128) && Subtarget.hasSSE1()) || ((type->getPrimitiveSizeInBits() == 256) && Subtarget.hasAVX()) || ((type->getPrimitiveSizeInBits() == 512) && Subtarget.hasAVX512())) @@ -48056,21 +48046,8 @@ if ((type->getPrimitiveSizeInBits() == 64) && Subtarget.hasAVX512()) return CW_Register; return CW_Invalid; - // Any MMX reg - case 'm': - if (type->isX86_MMXTy() && Subtarget.hasMMX()) - return weight; - return CW_Invalid; - // Any SSE reg when ISA >= SSE2, same as 'Y' - case 'i': - case 't': - case '2': - if (!Subtarget.hasSSE2()) - return CW_Invalid; - break; } - // Fall through (handle "Y" constraint). - LLVM_FALLTHROUGH; + break; } case 'v': if ((type->getPrimitiveSizeInBits() == 512) && Subtarget.hasAVX512()) @@ -48153,8 +48130,6 @@ // FP X constraints get lowered to SSE1/2 registers if available, otherwise // 'f' like normal targets. if (ConstraintVT.isFloatingPoint()) { - if (Subtarget.hasSSE2()) - return "Y"; if (Subtarget.hasSSE1()) return "x"; } @@ -48453,9 +48428,6 @@ case 'y': // MMX_REGS if MMX allowed. if (!Subtarget.hasMMX()) break; return std::make_pair(0U, &X86::VR64RegClass); - case 'Y': // SSE_REGS if SSE2 allowed - if (!Subtarget.hasSSE2()) break; - LLVM_FALLTHROUGH; case 'v': case 'x': // SSE_REGS if SSE1 allowed or AVX_REGS if AVX allowed if (!Subtarget.hasSSE1()) break; @@ -48515,15 +48487,7 @@ switch (Constraint[1]) { default: break; - case 'i': - case 't': - case '2': - return getRegForInlineAsmConstraint(TRI, "Y", VT); - case 'm': - if (!Subtarget.hasMMX()) break; - return std::make_pair(0U, &X86::VR64RegClass); case 'z': - case '0': if (!Subtarget.hasSSE1()) break; switch (VT.SimpleTy) { default: break; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -151,6 +151,10 @@ if (!AI.hasOneUse()) { // New is the allocation instruction, pointer typed. AI is the original // allocation instruction, also pointer typed. Thus, cast to use is BitCast. + BasicBlock::iterator It(New); + while (isa(*It) || isa(*It)) + ++It; + Value *NewCast = Builder.CreateBitCast(New, AI.getType(), "tmpcast"); replaceInstUsesWith(AI, NewCast); eraseInstFromFunction(AI); diff --git a/llvm/test/MC/X86/x86-GCC-inline-asm-Y-constraints.ll b/llvm/test/MC/X86/x86-GCC-inline-asm-Y-constraints.ll --- a/llvm/test/MC/X86/x86-GCC-inline-asm-Y-constraints.ll +++ b/llvm/test/MC/X86/x86-GCC-inline-asm-Y-constraints.ll @@ -2,58 +2,6 @@ ; This test compliments the .c test under clang/test/CodeGen/. We check ; if the inline asm constraints are respected in the generated code. -; Function Attrs: nounwind -define void @f_Ym(i64 %m.coerce) { -; Any mmx regiter constraint -; CHECK-LABEL: f_Ym: -; CHECK: ## InlineAsm Start -; CHECK-NEXT: movq %mm{{[0-9]+}}, %mm1 -; CHECK: ## InlineAsm End - -entry: - %0 = tail call x86_mmx asm sideeffect "movq $0, %mm1\0A\09", "=^Ym,~{dirflag},~{fpsr},~{flags}"() - ret void -} - -; Function Attrs: nounwind -define void @f_Yi(<4 x float> %x, <4 x float> %y, <4 x float> %z) { -; Any SSE register when SSE2 is enabled (GCC when inter-unit moves enabled) -; CHECK-LABEL: f_Yi: -; CHECK: ## InlineAsm Start -; CHECK-NEXT: vpaddq %xmm{{[0-9]+}}, %xmm{{[0-9]+}}, %xmm{{[0-9]+}} -; CHECK: ## InlineAsm End - -entry: - %0 = tail call <4 x float> asm sideeffect "vpaddq $0, $1, $2\0A\09", "=^Yi,^Yi,^Yi,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) - ret void -} - -; Function Attrs: nounwind -define void @f_Yt(<4 x float> %x, <4 x float> %y, <4 x float> %z) { -; Any SSE register when SSE2 is enabled -; CHECK-LABEL: f_Yt: -; CHECK: ## InlineAsm Start -; CHECK-NEXT: vpaddq %xmm{{[0-9]+}}, %xmm{{[0-9]+}}, %xmm{{[0-9]+}} -; CHECK: ## InlineAsm End - -entry: - %0 = tail call <4 x float> asm sideeffect "vpaddq $0, $1, $2\0A\09", "=^Yt,^Yt,^Yt,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) - ret void -} - -; Function Attrs: nounwind -define void @f_Y2(<4 x float> %x, <4 x float> %y, <4 x float> %z) { -; Any SSE register when SSE2 is enabled -; CHECK-LABEL: f_Y2: -; CHECK: ## InlineAsm Start -; CHECK-NEXT: vpaddq %xmm{{[0-9]+}}, %xmm{{[0-9]+}}, %xmm{{[0-9]+}} -; CHECK: ## InlineAsm End - -entry: - %0 = tail call <4 x float> asm sideeffect "vpaddq $0, $1, $2\0A\09", "=^Y2,^Y2,^Y2,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) - ret void -} - ; Function Attrs: nounwind define void @f_Yz(<4 x float> %x, <4 x float> %y, <4 x float> %z) { ; xmm0 SSE register(GCC) @@ -63,21 +11,6 @@ ; CHECK-NEXT: vpaddq %xmm0, %xmm{{[0-9]+}}, %xmm{{[0-9]+}} ; CHECK: ## InlineAsm End entry: - %0 = tail call { <4 x float>, <4 x float> } asm sideeffect "vpaddq $0,$2,$1\0A\09vpaddq $1,$0,$2\0A\09", "=^Yi,=^Yz,^Yi,0,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) + %0 = tail call { <4 x float>, <4 x float> } asm sideeffect "vpaddq $0,$2,$1\0A\09vpaddq $1,$0,$2\0A\09", "=x,=^Yz,x,0,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) ret void } - -; Function Attrs: nounwind -define void @f_Y0(<4 x float> %x, <4 x float> %y, <4 x float> %z) { -; xmm0 SSE register -; CHECK-LABEL: f_Y0: -; CHECK: ## InlineAsm Start -; CHECK-NEXT: vpaddq %xmm{{[0-9]+}}, %xmm{{[0-9]+}}, %xmm0 -; CHECK-NEXT: vpaddq %xmm0, %xmm{{[0-9]+}}, %xmm{{[0-9]+}} -; CHECK: ## InlineAsm End - -entry: - %0 = tail call { <4 x float>, <4 x float> } asm sideeffect "vpaddq $0,$2,$1\0A\09vpaddq $1,$0,$2\0A\09", "=^Yi,=^Y0,^Yi,0,~{dirflag},~{fpsr},~{flags}"(<4 x float> %y, <4 x float> %z) - ret void -} -