From c9540fe59bbf53223368c18e457f79d3e981a3a5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 16 Feb 2020 11:00:22 +0100 Subject: [PATCH] [InstCombine] Fix multi-use handling in cttz transform The select-of-cttz transform can currently duplicate cttz intrinsics and zext/trunc ops. The cause is that it unnecessarily duplicates the intrinsic and the zext/trunc when setting the "undef_on_zero" flag to false. However, it's always legal to set the flag from true to false, so we can make this replacement even if there are extra users. Differential Revision: https://reviews.llvm.org/D74685 --- .../InstCombine/InstCombineSelect.cpp | 21 +-- .../InstCombine/select-cmp-cttz-ctlz.ll | 173 +++++++++--------- 2 files changed, 92 insertions(+), 102 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index c9baa8b87fafb..343ee24bb327d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -857,16 +857,16 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal, if (!ICI->isEquality() || !match(CmpRHS, m_Zero())) return nullptr; - Value *Count = FalseVal; + Value *SelectArg = FalseVal; Value *ValueOnZero = TrueVal; if (Pred == ICmpInst::ICMP_NE) - std::swap(Count, ValueOnZero); + std::swap(SelectArg, ValueOnZero); // Skip zero extend/truncate. - Value *V = nullptr; - if (match(Count, m_ZExt(m_Value(V))) || - match(Count, m_Trunc(m_Value(V)))) - Count = V; + Value *Count = nullptr; + if (!match(SelectArg, m_ZExt(m_Value(Count))) && + !match(SelectArg, m_Trunc(m_Value(Count)))) + Count = SelectArg; // Check that 'Count' is a call to intrinsic cttz/ctlz. Also check that the // input to the cttz/ctlz is used as LHS for the compare instruction. @@ -880,11 +880,10 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal, // sizeof in bits of 'Count'. unsigned SizeOfInBits = Count->getType()->getScalarSizeInBits(); if (match(ValueOnZero, m_SpecificInt(SizeOfInBits))) { - // Explicitly clear the 'undef_on_zero' flag. - IntrinsicInst *NewI = cast(II->clone()); - NewI->setArgOperand(1, ConstantInt::getFalse(NewI->getContext())); - Builder.Insert(NewI); - return Builder.CreateZExtOrTrunc(NewI, ValueOnZero->getType()); + // Explicitly clear the 'undef_on_zero' flag. It's always valid to go from + // true to false on this flag, so we can replace it for all users. + II->setArgOperand(1, ConstantInt::getFalse(II->getContext())); + return SelectArg; } // If the ValueOnZero is not the bitwidth, we can at least make use of the diff --git a/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll b/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll index f145c2b8c2dea..9c2af9f14d149 100644 --- a/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll +++ b/llvm/test/Transforms/InstCombine/select-cmp-cttz-ctlz.ll @@ -7,8 +7,8 @@ define i16 @test1(i16 %x) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: ret i16 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: ret i16 [[CT]] ; %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true) %tobool = icmp ne i16 %x, 0 @@ -18,8 +18,8 @@ define i16 @test1(i16 %x) { define i32 @test2(i32 %x) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: ret i32 [[CT]] ; %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) %tobool = icmp ne i32 %x, 0 @@ -29,8 +29,8 @@ define i32 @test2(i32 %x) { define i64 @test3(i64 %x) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: ret i64 [[CT]] ; %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true) %tobool = icmp ne i64 %x, 0 @@ -40,8 +40,8 @@ define i64 @test3(i64 %x) { define i16 @test4(i16 %x) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: ret i16 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: ret i16 [[CT]] ; %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true) %tobool = icmp eq i16 %x, 0 @@ -51,8 +51,8 @@ define i16 @test4(i16 %x) { define i32 @test5(i32 %x) { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: ret i32 [[CT]] ; %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) %tobool = icmp eq i32 %x, 0 @@ -62,8 +62,8 @@ define i32 @test5(i32 %x) { define i64 @test6(i64 %x) { ; CHECK-LABEL: @test6( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: ret i64 [[CT]] ; %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true) %tobool = icmp eq i64 %x, 0 @@ -73,8 +73,8 @@ define i64 @test6(i64 %x) { define i16 @test1b(i16 %x) { ; CHECK-LABEL: @test1b( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: ret i16 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: ret i16 [[CT]] ; %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true) %tobool = icmp ne i16 %x, 0 @@ -84,8 +84,8 @@ define i16 @test1b(i16 %x) { define i32 @test2b(i32 %x) { ; CHECK-LABEL: @test2b( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: ret i32 [[CT]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true) %tobool = icmp ne i32 %x, 0 @@ -95,8 +95,8 @@ define i32 @test2b(i32 %x) { define i64 @test3b(i64 %x) { ; CHECK-LABEL: @test3b( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: ret i64 [[CT]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true) %tobool = icmp ne i64 %x, 0 @@ -106,8 +106,8 @@ define i64 @test3b(i64 %x) { define i16 @test4b(i16 %x) { ; CHECK-LABEL: @test4b( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: ret i16 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: ret i16 [[CT]] ; %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true) %tobool = icmp eq i16 %x, 0 @@ -118,8 +118,8 @@ define i16 @test4b(i16 %x) { define i32 @test5b(i32 %x) { ; CHECK-LABEL: @test5b( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: ret i32 [[TMP0]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: ret i32 [[CT]] ; entry: %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true) @@ -130,8 +130,8 @@ entry: define i64 @test6b(i64 %x) { ; CHECK-LABEL: @test6b( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: ret i64 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: ret i64 [[CT]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true) %tobool = icmp eq i64 %x, 0 @@ -141,9 +141,9 @@ define i64 @test6b(i64 %x) { define i32 @test1c(i16 %x) { ; CHECK-LABEL: @test1c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32 -; CHECK-NEXT: ret i32 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: [[CAST2:%.*]] = zext i16 [[CT]] to i32 +; CHECK-NEXT: ret i32 [[CAST2]] ; %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true) %cast2 = zext i16 %ct to i32 @@ -154,9 +154,9 @@ define i32 @test1c(i16 %x) { define i64 @test2c(i16 %x) { ; CHECK-LABEL: @test2c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i64 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[CT]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true) %conv = zext i16 %ct to i64 @@ -167,9 +167,9 @@ define i64 @test2c(i16 %x) { define i64 @test3c(i32 %x) { ; CHECK-LABEL: @test3c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[CT]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true) %conv = zext i32 %ct to i64 @@ -180,9 +180,9 @@ define i64 @test3c(i32 %x) { define i32 @test4c(i16 %x) { ; CHECK-LABEL: @test4c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32 -; CHECK-NEXT: ret i32 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: [[CAST:%.*]] = zext i16 [[CT]] to i32 +; CHECK-NEXT: ret i32 [[CAST]] ; %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true) %cast = zext i16 %ct to i32 @@ -193,9 +193,9 @@ define i32 @test4c(i16 %x) { define i64 @test5c(i16 %x) { ; CHECK-LABEL: @test5c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 -; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i64 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range !0 +; CHECK-NEXT: [[CAST:%.*]] = zext i16 [[CT]] to i64 +; CHECK-NEXT: ret i64 [[CAST]] ; %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true) %cast = zext i16 %ct to i64 @@ -206,9 +206,9 @@ define i64 @test5c(i16 %x) { define i64 @test6c(i32 %x) { ; CHECK-LABEL: @test6c( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CAST:%.*]] = zext i32 [[CT]] to i64 +; CHECK-NEXT: ret i64 [[CAST]] ; %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) %cast = zext i32 %ct to i64 @@ -219,9 +219,9 @@ define i64 @test6c(i32 %x) { define i16 @test1d(i64 %x) { ; CHECK-LABEL: @test1d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[CT]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true) %conv = trunc i64 %ct to i16 @@ -232,9 +232,9 @@ define i16 @test1d(i64 %x) { define i32 @test2d(i64 %x) { ; CHECK-LABEL: @test2d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; CHECK-NEXT: ret i32 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: [[CAST:%.*]] = trunc i64 [[CT]] to i32 +; CHECK-NEXT: ret i32 [[CAST]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true) %cast = trunc i64 %ct to i32 @@ -245,9 +245,9 @@ define i32 @test2d(i64 %x) { define i16 @test3d(i32 %x) { ; CHECK-LABEL: @test3d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CAST:%.*]] = trunc i32 [[CT]] to i16 +; CHECK-NEXT: ret i16 [[CAST]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true) %cast = trunc i32 %ct to i16 @@ -258,9 +258,9 @@ define i16 @test3d(i32 %x) { define i16 @test4d(i64 %x) { ; CHECK-LABEL: @test4d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: [[CAST:%.*]] = trunc i64 [[CT]] to i16 +; CHECK-NEXT: ret i16 [[CAST]] ; %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true) %cast = trunc i64 %ct to i16 @@ -271,9 +271,9 @@ define i16 @test4d(i64 %x) { define i32 @test5d(i64 %x) { ; CHECK-LABEL: @test5d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; CHECK-NEXT: ret i32 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false), !range !2 +; CHECK-NEXT: [[CAST:%.*]] = trunc i64 [[CT]] to i32 +; CHECK-NEXT: ret i32 [[CAST]] ; %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true) %cast = trunc i64 %ct to i32 @@ -284,9 +284,9 @@ define i32 @test5d(i64 %x) { define i16 @test6d(i32 %x) { ; CHECK-LABEL: @test6d( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CAST:%.*]] = trunc i32 [[CT]] to i16 +; CHECK-NEXT: ret i16 [[CAST]] ; %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) %cast = trunc i32 %ct to i16 @@ -297,9 +297,9 @@ define i16 @test6d(i32 %x) { define i64 @select_bug1(i32 %x) { ; CHECK-LABEL: @select_bug1( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[CT]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false) %conv = zext i32 %ct to i64 @@ -310,9 +310,9 @@ define i64 @select_bug1(i32 %x) { define i16 @select_bug2(i32 %x) { ; CHECK-LABEL: @select_bug2( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 +; CHECK-NEXT: [[CONV:%.*]] = trunc i32 [[CT]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false) %conv = trunc i32 %ct to i16 @@ -323,8 +323,8 @@ define i16 @select_bug2(i32 %x) { define i128 @test7(i128 %x) { ; CHECK-LABEL: @test7( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i128 @llvm.ctlz.i128(i128 [[X:%.*]], i1 false), !range !3 -; CHECK-NEXT: ret i128 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i128 @llvm.ctlz.i128(i128 [[X:%.*]], i1 false), !range !3 +; CHECK-NEXT: ret i128 [[CT]] ; %ct = tail call i128 @llvm.ctlz.i128(i128 %x, i1 true) %tobool = icmp ne i128 %x, 0 @@ -334,8 +334,8 @@ define i128 @test7(i128 %x) { define i128 @test8(i128 %x) { ; CHECK-LABEL: @test8( -; CHECK-NEXT: [[TMP1:%.*]] = tail call i128 @llvm.cttz.i128(i128 [[X:%.*]], i1 false), !range !3 -; CHECK-NEXT: ret i128 [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call i128 @llvm.cttz.i128(i128 [[X:%.*]], i1 false), !range !3 +; CHECK-NEXT: ret i128 [[CT]] ; %ct = tail call i128 @llvm.cttz.i128(i128 %x, i1 true) %tobool = icmp ne i128 %x, 0 @@ -401,8 +401,8 @@ define i32 @test_cttz_not_bw_multiuse(i32 %x) { define <2 x i32> @test_ctlz_bw_vec(<2 x i32> %x) { ; CHECK-LABEL: @test_ctlz_bw_vec( -; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 false) -; CHECK-NEXT: ret <2 x i32> [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 false) +; CHECK-NEXT: ret <2 x i32> [[CT]] ; %ct = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 true) %cmp = icmp ne <2 x i32> %x, zeroinitializer @@ -425,8 +425,8 @@ define <2 x i32> @test_ctlz_not_bw_vec(<2 x i32> %x) { define <2 x i32> @test_cttz_bw_vec(<2 x i32> %x) { ; CHECK-LABEL: @test_cttz_bw_vec( -; CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 false) -; CHECK-NEXT: ret <2 x i32> [[TMP1]] +; CHECK-NEXT: [[CT:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 false) +; CHECK-NEXT: ret <2 x i32> [[CT]] ; %ct = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %x, i1 true) %cmp = icmp ne <2 x i32> %x, zeroinitializer @@ -462,10 +462,9 @@ define i32 @test_multiuse_def(i32 %x, i32* %p) { define i32 @test_multiuse_undef(i32 %x, i32* %p) { ; CHECK-LABEL: @test_multiuse_undef( -; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), !range !1 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 false), !range !1 +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false), !range !1 ; CHECK-NEXT: store i32 [[CT]], i32* [[P:%.*]], align 4 -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: ret i32 [[CT]] ; %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) %tobool = icmp ne i32 %x, 0 @@ -478,10 +477,8 @@ define i64 @test_multiuse_zext_def(i32 %x, i64* %p) { ; CHECK-LABEL: @test_multiuse_zext_def( ; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[CT]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 ; CHECK-NEXT: store i64 [[CONV]], i64* [[P:%.*]], align 4 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: ret i64 [[CONV]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false) %conv = zext i32 %ct to i64 @@ -493,12 +490,10 @@ define i64 @test_multiuse_zext_def(i32 %x, i64* %p) { define i64 @test_multiuse_zext_undef(i32 %x, i64* %p) { ; CHECK-LABEL: @test_multiuse_zext_undef( -; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true), !range !1 +; CHECK-NEXT: [[CT:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false), !range !1 ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[CT]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 false), !range !1 -; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 ; CHECK-NEXT: store i64 [[CONV]], i64* [[P:%.*]], align 4 -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: ret i64 [[CONV]] ; %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true) %conv = zext i32 %ct to i64 @@ -512,10 +507,8 @@ define i16 @test_multiuse_trunc_def(i64 %x, i16 *%p) { ; CHECK-LABEL: @test_multiuse_trunc_def( ; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[CT]] to i16 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i16 ; CHECK-NEXT: store i16 [[CONV]], i16* [[P:%.*]], align 2 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: ret i16 [[CONV]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 false) %conv = trunc i64 %ct to i16 @@ -527,12 +520,10 @@ define i16 @test_multiuse_trunc_def(i64 %x, i16 *%p) { define i16 @test_multiuse_trunc_undef(i64 %x, i16 *%p) { ; CHECK-LABEL: @test_multiuse_trunc_undef( -; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 true), !range !2 +; CHECK-NEXT: [[CT:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false), !range !2 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[CT]] to i16 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 false), !range !2 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i16 ; CHECK-NEXT: store i16 [[CONV]], i16* [[P:%.*]], align 2 -; CHECK-NEXT: ret i16 [[TMP2]] +; CHECK-NEXT: ret i16 [[CONV]] ; %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true) %conv = trunc i64 %ct to i16