[llvm] r354746 - [CGP] add special-cases to form unsigned add with overflow (PR40486)
Jordan Rupprecht via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 11:13:02 PST 2019
Hi Sanjay,
Looks like this commit is causing an ICE (reduced test case attached):
$ bin/clang++ -c -O1 -fexperimental-new-pass-manager /tmp/repro.cc
...
Instruction does not dominate all uses!
%ov = extractvalue { i64, i1 } %0, 1
%cmp.i.i.i.phi = phi i1 [ %cmp.i.i.i.0, %_ZN2ac2abEv.exit.i.i.i.i.i
], [ %ov, %entry._Z2bqI2acPFvvEEvT_T0_.exit_crit_edge ]
in function _Z2btv
(That's the debug+assertions clang error; in release mode, it fails
later during the "Live Variable Analysis" pass)
On Sun, Feb 24, 2019 at 7:30 AM Sanjay Patel via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: spatel
> Date: Sun Feb 24 07:31:27 2019
> New Revision: 354746
>
> URL: http://llvm.org/viewvc/llvm-project?rev=354746&view=rev
> Log:
> [CGP] add special-cases to form unsigned add with overflow (PR40486)
>
> There's likely a missed IR canonicalization for at least 1 of these
> patterns. Otherwise, we wouldn't have needed the pattern-matching
> enhancement in D57516.
>
> Note that -- unlike usubo added with D57789 -- the TLI hook for
> this transform defaults to 'on'. So if there's any perf fallout
> from this, targets should look at how they're lowering the uaddo
> node in SDAG and/or override that hook.
>
> The x86 diffs suggest that there's some missing pattern-matching
> for forming inc/dec.
>
> This should fix the remaining known problems in:
> https://bugs.llvm.org/show_bug.cgi?id=40486
> https://bugs.llvm.org/show_bug.cgi?id=31754
>
> Modified:
> llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
> llvm/trunk/test/CodeGen/AArch64/uaddo.ll
> llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll
> llvm/trunk/test/CodeGen/X86/rd-mod-wr-eflags.ll
> llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
>
> Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=354746&r1=354745&r2=354746&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
> +++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Sun Feb 24 07:31:27 2019
> @@ -1197,6 +1197,31 @@ static bool replaceMathCmpWithIntrinsic(
> return true;
> }
>
> +/// Match special-case patterns that check for unsigned add overflow.
> +static bool matchUAddWithOverflowConstantEdgeCases(CmpInst *Cmp,
> + BinaryOperator *&Add) {
> + // Add = add A, 1; Cmp = icmp eq A,-1 (overflow if A is max val)
> + // Add = add A,-1; Cmp = icmp ne A, 0 (overflow if A is non-zero)
> + Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1);
> + ICmpInst::Predicate Pred = Cmp->getPredicate();
> + if (Pred == ICmpInst::ICMP_EQ && match(B, m_AllOnes()))
> + B = ConstantInt::get(B->getType(), 1);
> + else if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt()))
> + B = ConstantInt::get(B->getType(), -1);
> + else
> + return false;
> +
> + // Check the users of the variable operand of the compare looking for an add
> + // with the adjusted constant.
> + for (User *U : A->users()) {
> + if (match(U, m_Add(m_Specific(A), m_Specific(B)))) {
> + Add = cast<BinaryOperator>(U);
> + return true;
> + }
> + }
> + return false;
> +}
> +
> /// Try to combine the compare into a call to the llvm.uadd.with.overflow
> /// intrinsic. Return true if any changes were made.
> static bool combineToUAddWithOverflow(CmpInst *Cmp, const TargetLowering &TLI,
> @@ -1204,7 +1229,8 @@ static bool combineToUAddWithOverflow(Cm
> Value *A, *B;
> BinaryOperator *Add;
> if (!match(Cmp, m_UAddWithOverflow(m_Value(A), m_Value(B), m_BinOp(Add))))
> - return false;
> + if (!matchUAddWithOverflowConstantEdgeCases(Cmp, Add))
> + return false;
>
> if (!TLI.shouldFormOverflowOp(ISD::UADDO,
> TLI.getValueType(DL, Add->getType())))
> @@ -1216,13 +1242,6 @@ static bool combineToUAddWithOverflow(Cm
> if (Add->getParent() != Cmp->getParent() && !Add->hasOneUse())
> return false;
>
> -#ifndef NDEBUG
> - // Someday m_UAddWithOverflow may get smarter, but this is a safe assumption
> - // for now:
> - if (Add->hasOneUse())
> - assert(*Add->user_begin() == Cmp && "expected!");
> -#endif
> -
> if (!replaceMathCmpWithIntrinsic(Add, Cmp, Intrinsic::uadd_with_overflow))
> return false;
>
>
> Modified: llvm/trunk/test/CodeGen/AArch64/uaddo.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/uaddo.ll?rev=354746&r1=354745&r2=354746&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/uaddo.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/uaddo.ll Sun Feb 24 07:31:27 2019
> @@ -8,9 +8,8 @@
> define i1 @uaddo_i64_increment_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_increment_alt:
> ; CHECK: // %bb.0:
> -; CHECK-NEXT: cmn x0, #1 // =1
> -; CHECK-NEXT: add x8, x0, #1 // =1
> -; CHECK-NEXT: cset w0, eq
> +; CHECK-NEXT: adds x8, x0, #1 // =1
> +; CHECK-NEXT: cset w0, hs
> ; CHECK-NEXT: str x8, [x1]
> ; CHECK-NEXT: ret
> %a = add i64 %x, 1
> @@ -24,11 +23,9 @@ define i1 @uaddo_i64_increment_alt(i64 %
> define i1 @uaddo_i64_increment_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_increment_alt_dom:
> ; CHECK: // %bb.0:
> -; CHECK-NEXT: cmn x0, #1 // =1
> -; CHECK-NEXT: cset w8, eq
> -; CHECK-NEXT: add x9, x0, #1 // =1
> -; CHECK-NEXT: mov w0, w8
> -; CHECK-NEXT: str x9, [x1]
> +; CHECK-NEXT: adds x8, x0, #1 // =1
> +; CHECK-NEXT: cset w0, hs
> +; CHECK-NEXT: str x8, [x1]
> ; CHECK-NEXT: ret
> %ov = icmp eq i64 %x, -1
> %a = add i64 %x, 1
> @@ -41,9 +38,8 @@ define i1 @uaddo_i64_increment_alt_dom(i
> define i1 @uaddo_i64_decrement_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_decrement_alt:
> ; CHECK: // %bb.0:
> -; CHECK-NEXT: cmp x0, #0 // =0
> -; CHECK-NEXT: sub x8, x0, #1 // =1
> -; CHECK-NEXT: cset w0, ne
> +; CHECK-NEXT: subs x8, x0, #1 // =1
> +; CHECK-NEXT: cset w0, hs
> ; CHECK-NEXT: str x8, [x1]
> ; CHECK-NEXT: ret
> %a = add i64 %x, -1
> @@ -57,11 +53,9 @@ define i1 @uaddo_i64_decrement_alt(i64 %
> define i1 @uaddo_i64_decrement_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_decrement_alt_dom:
> ; CHECK: // %bb.0:
> -; CHECK-NEXT: cmp x0, #0 // =0
> -; CHECK-NEXT: cset w8, ne
> -; CHECK-NEXT: sub x9, x0, #1 // =1
> -; CHECK-NEXT: mov w0, w8
> -; CHECK-NEXT: str x9, [x1]
> +; CHECK-NEXT: subs x8, x0, #1 // =1
> +; CHECK-NEXT: cset w0, hs
> +; CHECK-NEXT: str x8, [x1]
> ; CHECK-NEXT: ret
> %ov = icmp ne i64 %x, 0
> %a = add i64 %x, -1
>
> Modified: llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll?rev=354746&r1=354745&r2=354746&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll Sun Feb 24 07:31:27 2019
> @@ -229,12 +229,7 @@ define void @test_18446744073709551614(i
> define void @test_18446744073709551615(i64*, i64*) {
> ; CHECK-LABEL: test_18446744073709551615:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: movq (%rdi), %rax
> -; CHECK-NEXT: leaq -1(%rax), %rcx
> -; CHECK-NEXT: movq %rcx, (%rdi)
> -; CHECK-NEXT: testq %rax, %rax
> -; CHECK-NEXT: setne %al
> -; CHECK-NEXT: addb $-1, %al
> +; CHECK-NEXT: addq $-1, (%rdi)
> ; CHECK-NEXT: adcq $0, (%rsi)
> ; CHECK-NEXT: retq
> %3 = load i64, i64* %0, align 8
> @@ -272,10 +267,9 @@ define i1 @illegal_type(i17 %x, i17* %p)
> define i1 @uaddo_i64_increment_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_increment_alt:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: leaq 1(%rdi), %rax
> -; CHECK-NEXT: movq %rax, (%rsi)
> -; CHECK-NEXT: cmpq $-1, %rdi
> +; CHECK-NEXT: incq %rdi
> ; CHECK-NEXT: sete %al
> +; CHECK-NEXT: movq %rdi, (%rsi)
> ; CHECK-NEXT: retq
> %a = add i64 %x, 1
> store i64 %a, i64* %p
> @@ -288,9 +282,8 @@ define i1 @uaddo_i64_increment_alt(i64 %
> define i1 @uaddo_i64_increment_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_increment_alt_dom:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: cmpq $-1, %rdi
> -; CHECK-NEXT: sete %al
> ; CHECK-NEXT: incq %rdi
> +; CHECK-NEXT: sete %al
> ; CHECK-NEXT: movq %rdi, (%rsi)
> ; CHECK-NEXT: retq
> %ov = icmp eq i64 %x, -1
> @@ -304,10 +297,9 @@ define i1 @uaddo_i64_increment_alt_dom(i
> define i1 @uaddo_i64_decrement_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_decrement_alt:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: leaq -1(%rdi), %rax
> -; CHECK-NEXT: movq %rax, (%rsi)
> -; CHECK-NEXT: testq %rdi, %rdi
> -; CHECK-NEXT: setne %al
> +; CHECK-NEXT: addq $-1, %rdi
> +; CHECK-NEXT: setb %al
> +; CHECK-NEXT: movq %rdi, (%rsi)
> ; CHECK-NEXT: retq
> %a = add i64 %x, -1
> store i64 %a, i64* %p
> @@ -320,9 +312,8 @@ define i1 @uaddo_i64_decrement_alt(i64 %
> define i1 @uaddo_i64_decrement_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: uaddo_i64_decrement_alt_dom:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: testq %rdi, %rdi
> -; CHECK-NEXT: setne %al
> -; CHECK-NEXT: decq %rdi
> +; CHECK-NEXT: addq $-1, %rdi
> +; CHECK-NEXT: setb %al
> ; CHECK-NEXT: movq %rdi, (%rsi)
> ; CHECK-NEXT: retq
> %ov = icmp ne i64 %x, 0
>
> Modified: llvm/trunk/test/CodeGen/X86/rd-mod-wr-eflags.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/rd-mod-wr-eflags.ll?rev=354746&r1=354745&r2=354746&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/rd-mod-wr-eflags.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/rd-mod-wr-eflags.ll Sun Feb 24 07:31:27 2019
> @@ -68,13 +68,12 @@ define i32 @test2() nounwind uwtable ssp
> ; CHECK: # %bb.0: # %entry
> ; CHECK-NEXT: pushq %rax
> ; CHECK-NEXT: .cfi_def_cfa_offset 16
> -; CHECK-NEXT: movq {{.*}}(%rip), %rax
> -; CHECK-NEXT: leaq -1(%rax), %rsi
> +; CHECK-NEXT: movq {{.*}}(%rip), %rsi
> +; CHECK-NEXT: xorl %eax, %eax
> +; CHECK-NEXT: addq $-1, %rsi
> +; CHECK-NEXT: setb %al
> ; CHECK-NEXT: movq %rsi, {{.*}}(%rip)
> -; CHECK-NEXT: xorl %ecx, %ecx
> -; CHECK-NEXT: testq %rax, %rax
> -; CHECK-NEXT: setne %cl
> -; CHECK-NEXT: movl %ecx, {{.*}}(%rip)
> +; CHECK-NEXT: movl %eax, {{.*}}(%rip)
> ; CHECK-NEXT: movl $.L.str, %edi
> ; CHECK-NEXT: xorl %eax, %eax
> ; CHECK-NEXT: callq printf
>
> Modified: llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll?rev=354746&r1=354745&r2=354746&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll (original)
> +++ llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll Sun Feb 24 07:31:27 2019
> @@ -162,10 +162,11 @@ define i1 @uaddo_i16_increment_noncanoni
>
> define i1 @uaddo_i64_increment_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: @uaddo_i64_increment_alt(
> -; CHECK-NEXT: [[A:%.*]] = add i64 [[X:%.*]], 1
> -; CHECK-NEXT: store i64 [[A]], i64* [[P:%.*]]
> -; CHECK-NEXT: [[OV:%.*]] = icmp eq i64 [[X]], -1
> -; CHECK-NEXT: ret i1 [[OV]]
> +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)
> +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
> +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
> +; CHECK-NEXT: store i64 [[MATH]], i64* [[P:%.*]]
> +; CHECK-NEXT: ret i1 [[OV1]]
> ;
> %a = add i64 %x, 1
> store i64 %a, i64* %p
> @@ -177,10 +178,11 @@ define i1 @uaddo_i64_increment_alt(i64 %
>
> define i1 @uaddo_i64_increment_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: @uaddo_i64_increment_alt_dom(
> -; CHECK-NEXT: [[OV:%.*]] = icmp eq i64 [[X:%.*]], -1
> -; CHECK-NEXT: [[A:%.*]] = add i64 [[X]], 1
> -; CHECK-NEXT: store i64 [[A]], i64* [[P:%.*]]
> -; CHECK-NEXT: ret i1 [[OV]]
> +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)
> +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
> +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
> +; CHECK-NEXT: store i64 [[MATH]], i64* [[P:%.*]]
> +; CHECK-NEXT: ret i1 [[OV1]]
> ;
> %ov = icmp eq i64 %x, -1
> %a = add i64 %x, 1
> @@ -192,10 +194,11 @@ define i1 @uaddo_i64_increment_alt_dom(i
>
> define i1 @uaddo_i64_decrement_alt(i64 %x, i64* %p) {
> ; CHECK-LABEL: @uaddo_i64_decrement_alt(
> -; CHECK-NEXT: [[A:%.*]] = add i64 [[X:%.*]], -1
> -; CHECK-NEXT: store i64 [[A]], i64* [[P:%.*]]
> -; CHECK-NEXT: [[OV:%.*]] = icmp ne i64 [[X]], 0
> -; CHECK-NEXT: ret i1 [[OV]]
> +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)
> +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
> +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
> +; CHECK-NEXT: store i64 [[MATH]], i64* [[P:%.*]]
> +; CHECK-NEXT: ret i1 [[OV1]]
> ;
> %a = add i64 %x, -1
> store i64 %a, i64* %p
> @@ -207,10 +210,11 @@ define i1 @uaddo_i64_decrement_alt(i64 %
>
> define i1 @uaddo_i64_decrement_alt_dom(i64 %x, i64* %p) {
> ; CHECK-LABEL: @uaddo_i64_decrement_alt_dom(
> -; CHECK-NEXT: [[OV:%.*]] = icmp ne i64 [[X:%.*]], 0
> -; CHECK-NEXT: [[A:%.*]] = add i64 [[X]], -1
> -; CHECK-NEXT: store i64 [[A]], i64* [[P:%.*]]
> -; CHECK-NEXT: ret i1 [[OV]]
> +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)
> +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
> +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
> +; CHECK-NEXT: store i64 [[MATH]], i64* [[P:%.*]]
> +; CHECK-NEXT: ret i1 [[OV1]]
> ;
> %ov = icmp ne i64 %x, 0
> %a = add i64 %x, -1
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: repro.cc
Type: text/x-c-code
Size: 4037 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190304/f7ac46b8/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4849 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190304/f7ac46b8/attachment-0001.bin>
More information about the llvm-commits
mailing list