[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