diff --git a/test/Transforms/NewGVN/flags-simplify.ll b/test/Transforms/NewGVN/flags-simplify.ll new file mode 100644 index 00000000000..5ec5f179f8c --- /dev/null +++ b/test/Transforms/NewGVN/flags-simplify.ll @@ -0,0 +1,100 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -newgvn < %s | FileCheck %s + +; Check that we do not use keywords only available for some members of a +; congruence class when simplifying. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@f = external global i64, align 8 +@b = external global i1, align 8 + +define i64 @ashr_lsh_nsw(i64 %tmp) { +; CHECK-LABEL: @ashr_lsh_nsw( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CONV3:%.*]] = shl i64 [[TMP:%.*]], 32 +; CHECK-NEXT: store i64 [[CONV3]], i64* @f, align 8 +; CHECK-NEXT: [[CONV7:%.*]] = ashr exact i64 [[CONV3]], 32 +; CHECK-NEXT: ret i64 [[CONV7]] +; +entry: ; preds = %if.then + %conv3 = shl nsw i64 %tmp, 32 + store i64 %conv3, i64* @f, align 8 + %sext = shl i64 %tmp, 32 + %conv7 = ashr exact i64 %sext, 32 + ret i64 %conv7 +} + +define i64 @ashr_lsh_nuw(i64 %tmp) { +; CHECK-LABEL: @ashr_lsh_nuw( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CONV3:%.*]] = shl i64 [[TMP:%.*]], 32 +; CHECK-NEXT: store i64 [[CONV3]], i64* @f, align 8 +; CHECK-NEXT: [[CONV7:%.*]] = ashr exact i64 [[CONV3]], 32 +; CHECK-NEXT: ret i64 [[CONV7]] +; +entry: ; preds = %if.then + %conv3 = shl nuw i64 %tmp, 32 + store i64 %conv3, i64* @f, align 8 + %sext = shl i64 %tmp, 32 + %conv7 = ashr exact i64 %sext, 32 + ret i64 %conv7 +} + +define i32 @udiv_exact_mul(i32 %x, i32 %y, i1 %arg2) { +; CHECK-LABEL: @udiv_exact_mul( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB2:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[S1:%.*]] = udiv exact i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[S2:%.*]] = mul i32 [[S1]], [[Y]] +; CHECK-NEXT: ret i32 [[S2]] +; CHECK: bb2: +; CHECK-NEXT: [[S1_2:%.*]] = udiv i32 [[X]], [[Y]] +; CHECK-NEXT: [[S2_2:%.*]] = mul i32 [[S1_2]], [[Y]] +; CHECK-NEXT: ret i32 [[S2_2]] +; + br i1 %arg2, label %bb2, label %bb1 +bb1: + %s1 = udiv exact i32 %x, %y + %s2 = mul i32 %s1, %y + ret i32 %s2 + +bb2: + %s1.2 = udiv i32 %x, %y + %s2.2 = mul i32 %s1.2, %y + ret i32 %s2.2 +} + +define i1 @add_nuw_icmp(i32 %x, i32 %y, i1 %arg2) { +; CHECK-LABEL: @add_nuw_icmp( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[Z:%.*]] = add i32 [[Y:%.*]], 1 +; CHECK-NEXT: [[S1:%.*]] = add i32 [[X:%.*]], [[Z]] +; CHECK-NEXT: [[S2:%.*]] = add i32 [[X]], [[Y]] +; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[S1]], [[S2]] +; CHECK-NEXT: ret i1 [[C]] +; CHECK: bb2: +; CHECK-NEXT: [[Z_2:%.*]] = add nuw i32 [[Y]], 1 +; CHECK-NEXT: [[S1_2:%.*]] = add nuw i32 [[X]], [[Z_2]] +; CHECK-NEXT: [[S2_2:%.*]] = add nuw i32 [[X]], [[Y]] +; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[S1_2]], [[S2_2]] +; CHECK-NEXT: ret i1 [[C_2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %z = add i32 %y, 1 + %s1 = add i32 %x, %z + %s2 = add i32 %x, %y + %c = icmp ugt i32 %s1, %s2 + ret i1 %c + +bb2: + %z.2 = add nuw i32 %y, 1 + %s1.2 = add nuw i32 %x, %z.2 + %s2.2 = add nuw i32 %x, %y + %c.2 = icmp ugt i32 %s1.2, %s2.2 + ret i1 %c.2 +} diff --git a/test/Transforms/NewGVN/metadata-simplify.ll b/test/Transforms/NewGVN/metadata-simplify.ll new file mode 100644 index 00000000000..c9827bf26be --- /dev/null +++ b/test/Transforms/NewGVN/metadata-simplify.ll @@ -0,0 +1,160 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py + +; The tests in this file check that we do not simplify based on metadata that is +; not available on all code paths. + +; RUN: opt < %s -S -newgvn | FileCheck %s + +define i1 @test1(i32** %arg, i1 %arg2) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32*, i32** [[ARG:%.*]], !nonnull !0 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* [[LOAD1]], null +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32*, i32** [[ARG]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32* [[LOAD2]], null +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32*, i32** %arg, !nonnull !0 + %cmp1 = icmp eq i32* %load1, null + ret i1 %cmp1 + +bb2: + %load2 = load i32*, i32** %arg + %cmp2 = icmp eq i32* %load2, null + ret i1 %cmp2 +} + +define i1 @test2(i32** %arg, i1 %arg2) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32*, i32** [[ARG:%.*]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* [[LOAD1]], null +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32*, i32** [[ARG]], !nonnull !0 +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32* [[LOAD2]], null +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32*, i32** %arg + %cmp1 = icmp eq i32* %load1, null + ret i1 %cmp1 + +bb2: + %load2 = load i32*, i32** %arg, !nonnull !0 + %cmp2 = icmp eq i32* %load2, null + ret i1 %cmp2 +} + + +define i1 @test3(i32* %ptr, i1 %arg2) { +; CHECK-LABEL: @test3( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[PTR:%.*]], !range !1 +; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[LOAD1]], 999 +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32, i32* [[PTR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[LOAD2]], 999 +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32, i32* %ptr, !range !1 + %cmp1 = icmp ne i32 %load1, 999 + ret i1 %cmp1 + +bb2: + %load2 = load i32, i32* %ptr + %cmp2 = icmp ne i32 %load2, 999 + ret i1 %cmp2 +} + +define i1 @test4(i32* %ptr, i1 %arg2) { +; CHECK-LABEL: @test4( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[PTR:%.*]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[LOAD1]], 999 +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32, i32* [[PTR]], !range !1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[LOAD2]], 999 +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32, i32* %ptr + %cmp1 = icmp ne i32 %load1, 999 + ret i1 %cmp1 + +bb2: + %load2 = load i32, i32* %ptr, !range !1 + %cmp2 = icmp ne i32 %load2, 999 + ret i1 %cmp2 +} + +define i1 @test5(i32* %ptr, i1 %arg2) { +; CHECK-LABEL: @test5( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[PTR:%.*]], !range !1 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[LOAD1]], 999 +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32, i32* [[PTR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[LOAD2]], 999 +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32, i32* %ptr, !range !1 + %cmp1 = icmp slt i32 %load1, 999 + ret i1 %cmp1 + +bb2: + %load2 = load i32, i32* %ptr + %cmp2 = icmp slt i32 %load2, 999 + ret i1 %cmp2 +} + +define i1 @test6(i32* %ptr, i1 %arg2) { +; CHECK-LABEL: @test6( +; CHECK-NEXT: br i1 [[ARG2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[PTR:%.*]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[LOAD1]], 999 +; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK: bb2: +; CHECK-NEXT: [[LOAD2:%.*]] = load i32, i32* [[PTR]], !range !1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[LOAD2]], 999 +; CHECK-NEXT: ret i1 [[CMP2]] +; + br i1 %arg2, label %bb1, label %bb2 + +bb1: + %load1 = load i32, i32* %ptr + %cmp1 = icmp slt i32 %load1, 999 + ret i1 %cmp1 + +bb2: + %load2 = load i32, i32* %ptr, !range !1 + %cmp2 = icmp slt i32 %load2, 999 + ret i1 %cmp2 +} + +!0 = !{} +!1 = !{ i32 10, i32 20 }