Skip to content

[InstCombine] Fold umax(nuw_mul(x, C0), x + 1) into (x == 0 ? 1 : nuw_mul(x, C0)) #123468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 20, 2025

Conversation

Ruhung
Copy link
Contributor

@Ruhung Ruhung commented Jan 18, 2025

This PR introduces the following transformations:

  • If C0 is not 0:
    umax(nuw_shl(x, C0), x + 1) -> x == 0 ? 1 : nuw_shl(x, C0)
  • If C0 is not 0 or 1:
    umax(nuw_mul(x, C0), x + 1) -> x == 0 ? 1 : nuw_mul(x, C0)

Fixes : #122388
Alive2 proof : https://alive2.llvm.org/ce/z/rkp_8U

@llvmbot
Copy link
Member

llvmbot commented Jan 18, 2025

@llvm/pr-subscribers-llvm-transforms

Author: None (Ruhung)

Changes

This PR introduces the following transformations:

  • If C0 is not 0:
    umax(nuw_shl(x, C0), x + 1) -> x == 0 ? 1 : nuw_shl(x, C0)
  • If C0 is not 0 or 1:
    umax(nuw_mul(x, C0), x + 1) -> x == 0 ? 1 : nuw_mul(x, C0)

Fixes : #122388
Alive2 proof : https://alive2.llvm.org/ce/z/rkp_8U


Full diff: https://github.com/llvm/llvm-project/pull/123468.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+31)
  • (added) llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll (+300)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c55c40c88bc845..0db7d8818fbd0b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1847,6 +1847,37 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         return CastInst::Create(Instruction::ZExt, NarrowMaxMin, II->getType());
       }
     }
+    // If C0 is not 0:
+    //   umax(nuw_shl(x, C0), x + 1) -> x == 0 ? 1 : nuw_shl(x, C0)
+    // If C0 is not 0 or 1:
+    //   umax(nuw_mul(x, C0), x + 1) -> x == 0 ? 1 : nuw_mul(x, C0)
+    ConstantInt *C0;
+    bool isShl = false;
+    BinaryOperator *Op = nullptr;
+    auto matchShiftOrMul = [&](Value *I) {
+      if (match(I, m_OneUse(m_NUWShl(m_Value(X), m_ConstantInt(C0))))) {
+        isShl = true;
+        return true;
+      } else if (match(I, m_OneUse(m_NUWMul(m_Value(X), m_ConstantInt(C0)))) &&
+                 C0 && !C0->isOne()) {
+        isShl = false;
+        return true;
+      }
+      return false;
+    };
+    if (((matchShiftOrMul(I0) &&
+          match(I1, m_OneUse(m_Add(m_Specific(X), m_One())))) ||
+         (matchShiftOrMul(I1) &&
+          match(I0, m_OneUse(m_Add(m_Specific(X), m_One()))))) &&
+        C0 && !C0->isZero()) {
+      Op = isShl ? BinaryOperator::CreateNUWShl(X, C0)
+                 : BinaryOperator::CreateNUWMul(X, C0);
+      Builder.Insert(Op);
+      Value *Cmp = Builder.CreateICmpEQ(X, ConstantInt::get(X->getType(), 0));
+      Value *NewSelect =
+          Builder.CreateSelect(Cmp, ConstantInt::get(X->getType(), 1), Op);
+      return replaceInstUsesWith(*II, NewSelect);
+    }
     // If both operands of unsigned min/max are sign-extended, it is still ok
     // to narrow the operation.
     [[fallthrough]];
diff --git a/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
new file mode 100644
index 00000000000000..86ce5dc06ce031
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/add-shl-mul-umax.ll
@@ -0,0 +1,300 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; When C0 is neither 0 nor 1:
+;   umax(nuw_mul(x, C0), x + 1) is optimized to:
+;   x == 0 ? 1 : nuw_mul(x, C0)
+; When C0 is not 0:
+;   umax(nuw_shl(x, C0), x + 1) is optimized to:
+;   x == 0 ? 1 : nuw_shl(x, C0)
+
+; Positive Test Cases for `shl`
+
+define i64 @test_shl_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP3]], i64 1, i64 [[TMP2]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_shl_by_5(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_5(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 5
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP3]], i64 1, i64 [[TMP2]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 5
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+; Commuted Test Cases for `shl`
+
+define i64 @test_shl_umax_commuted(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_umax_commuted(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP2]], i64 1, i64 [[SHL]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %x1, i64 %shl)
+  ret i64 %max
+}
+
+; Negative Test Cases for `shl`
+
+define i64 @test_shl_by_zero(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_by_zero(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 0
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_shl_add_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_add_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 2
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 2
+  %shl = shl nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_shl_without_nuw(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_without_nuw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[X]], 2
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+; Multi-use Test Cases for `shl`
+declare void @use(i64)
+
+define i64 @test_shl_multi_use_add(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_add(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    call void @use(i64 [[X1]])
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 3
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  call void @use(i64 %x1)
+  %shl = shl nuw i64 %x, 3
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_shl_multi_use_shl(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_shl(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i64 [[X]], 2
+; CHECK-NEXT:    call void @use(i64 [[SHL]])
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[SHL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 2
+  call void @use(i64 %shl)
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_shl_multi_use_max(i64 %x) {
+; CHECK-LABEL: define i64 @test_shl_multi_use_max(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 3
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP3]], i64 1, i64 [[TMP2]]
+; CHECK-NEXT:    call void @use(i64 [[MAX]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %shl = shl nuw i64 %x, 3
+  %max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
+  call void @use(i64 %max)
+  ret i64 %max
+}
+
+; Positive Test Cases for `mul`
+
+define i64 @test_mul_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP3]], i64 1, i64 [[TMP2]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_by_5(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_5(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i64 [[X]], 5
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP2]], i64 1, i64 [[MUL]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 5
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+; Commuted Test Cases for `mul`
+
+define i64 @test_mul_max_commuted(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_max_commuted(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP2]], i64 1, i64 [[MUL]]
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %x1, i64 %mul)
+  ret i64 %max
+}
+
+; Negative Test Cases for `mul`
+
+define i64 @test_mul_by_zero(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_zero(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    ret i64 [[X1]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 0
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_by_1(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_by_1(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[X]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 1
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_add_by_2(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_add_by_2(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 2
+; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 2
+  %mul = mul nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_without_nuw(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_without_nuw(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[MUL:%.*]] = shl i64 [[X]], 1
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+; Multi-use Test Cases for `mul`
+
+define i64 @test_mul_multi_use_add(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_add(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    call void @use(i64 [[X1]])
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  call void @use(i64 %x1)
+  %mul = mul nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_multi_use_mul(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_mul(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[X1:%.*]] = add i64 [[X]], 1
+; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    call void @use(i64 [[MUL]])
+; CHECK-NEXT:    [[MAX:%.*]] = call i64 @llvm.umax.i64(i64 [[MUL]], i64 [[X1]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 2
+  call void @use(i64 %mul)
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  ret i64 %max
+}
+
+define i64 @test_mul_multi_use_max(i64 %x) {
+; CHECK-LABEL: define i64 @test_mul_multi_use_max(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i64 [[X]], 1
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP3]], i64 1, i64 [[TMP2]]
+; CHECK-NEXT:    call void @use(i64 [[MAX]])
+; CHECK-NEXT:    ret i64 [[MAX]]
+;
+  %x1 = add i64 %x, 1
+  %mul = mul nuw i64 %x, 2
+  %max = call i64 @llvm.umax.i64(i64 %mul, i64 %x1)
+  call void @use(i64 %max)
+  ret i64 %max
+}

@nikic nikic requested a review from dtcxzyw January 18, 2025 16:57
@Ruhung Ruhung force-pushed the Fix122388 branch 2 times, most recently from a06d9b4 to 1da116b Compare January 18, 2025 19:36
@Ruhung Ruhung force-pushed the Fix122388 branch 2 times, most recently from b5fd430 to 1c4aa09 Compare January 19, 2025 00:01
Copy link

github-actions bot commented Jan 19, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Ruhung Ruhung force-pushed the Fix122388 branch 2 times, most recently from 83cace4 to dfe40a0 Compare January 19, 2025 00:30
return replaceInstUsesWith(*II, NewSelect);
}
return nullptr;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think its easier to read if you use early returns as opposed to mashing it all together into a single condition ie:

auto foldMaxMulShift = [&](Value *A, Value *B) -> Instruction * {
  const APInt *C;
  Value *X;
  if (!(match(A, m_NUWShl(m_Value(X), m_APInt(C)))) &&
      !(match(A, m_NUWMul(m_Value(X), m_APInt(C))) && !C->isOne()))
    return nullptr;
  if (!C->isZero())
    return nullptr;
  if (!match(B, m_OneUse(m_Add(m_Specific(X), m_One()))))
    return nullptr;

  Value *Cmp = Builder.CreateICmpEQ(X, ConstantInt::get(X->getType(), 0));
  Value *NewSelect =
      Builder.CreateSelect(Cmp, ConstantInt::get(X->getType(), 1), A);
  return replaceInstUsesWith(*II, NewSelect);
};

That being said this is purely stylistic, so do as you do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think early returns actually make it more readable. Done. Thanks!

return I;
if (Instruction *I = foldMaxMulShift(I1, I0))
return I;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a possible follow up if you are interested, you can also handle umin: https://alive2.llvm.org/ce/z/DAy-C5

@goldsteinn
Copy link
Contributor

LGTM

@@ -1847,6 +1847,33 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return CastInst::Create(Instruction::ZExt, NarrowMaxMin, II->getType());
}
}
// If C0 is not 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C0 -> C to match the implementation.

auto foldMaxMulShift = [&](Value *A, Value *B) -> Instruction * {
const APInt *C;
Value *X;
if (!(match(A, m_NUWShl(m_Value(X), m_APInt(C)))) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!(match(A, m_NUWShl(m_Value(X), m_APInt(C)))) &&
if (!match(A, m_NUWShl(m_Value(X), m_APInt(C))) &&

%x1 = add i64 %x, 1
%shl = shl nuw i64 %x, 3
%max = call i64 @llvm.umax.i64(i64 %shl, i64 %x1)
call void @use(i64 %max)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to test multi-use on the root instruction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add one test using vector types?

@Ruhung Ruhung force-pushed the Fix122388 branch 2 times, most recently from f19e485 to 712c2a0 Compare January 20, 2025 12:39
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nikic nikic merged commit 9c7e02d into llvm:main Jan 20, 2025
8 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jan 20, 2025

LLVM Buildbot has detected a new failure on builder openmp-offload-libc-amdgpu-runtime running on omp-vega20-1 while building llvm at step 7 "Add check check-offload".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/12031

Here is the relevant piece of the build log for the reference
Step 7 (Add check check-offload) failure: test (failure)
******************** TEST 'libomptarget :: amdgcn-amd-amdhsa :: offloading/pgo1.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang -fopenmp    -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib  -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c -o /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/pgo1.c.tmp -Xoffload-linker -lc -Xoffload-linker -lm /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a -fprofile-instr-generate      -Xclang "-fprofile-instrument=clang"
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c -o /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/pgo1.c.tmp -Xoffload-linker -lc -Xoffload-linker -lm /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a -fprofile-instr-generate -Xclang -fprofile-instrument=clang
# RUN: at line 3
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/pgo1.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c      --check-prefix="CLANG-PGO"
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/offloading/Output/pgo1.c.tmp
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c --check-prefix=CLANG-PGO
# .---command stderr------------
# | /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c:32:20: error: CLANG-PGO-NEXT: expected string not found in input
# | // CLANG-PGO-NEXT: [ 0 11 20 ]
# |                    ^
# | <stdin>:3:28: note: scanning from here
# | ======== Counters =========
# |                            ^
# | <stdin>:4:1: note: possible intended match here
# | [ 0 12 20 ]
# | ^
# | 
# | Input file: <stdin>
# | Check file: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/offloading/pgo1.c
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |            1: ======= GPU Profile ======= 
# |            2: Target: amdgcn-amd-amdhsa 
# |            3: ======== Counters ========= 
# | next:32'0                                X error: no match found
# |            4: [ 0 12 20 ] 
# | next:32'0     ~~~~~~~~~~~~
# | next:32'1     ?            possible intended match
# |            5: [ 10 ] 
# | next:32'0     ~~~~~~~
# |            6: [ 20 ] 
# | next:32'0     ~~~~~~~
# |            7: ========== Data =========== 
# | next:32'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            8: { 9515997471539760012 4749112401 0xffffffffffffffd8 0x0 0x0 0x0 3 [...] 0 } 
# | next:32'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            9: { 3666282617048535130 24 0xffffffffffffffb0 0x0 0x0 0x0 1 [...] 0 } 
# | next:32'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |            .
# |            .
# |            .
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[InstCombine] Missed fold: umax(x *nuw 2, x + 1) => x == 0 ? 1 : x *nuw 2
5 participants