diff --git a/llvm/test/Transforms/SimplifyCFG/speculate-div.ll b/llvm/test/Transforms/SimplifyCFG/speculate-div.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/speculate-div.ll @@ -0,0 +1,265 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S --passes='simplifycfg' %s | FileCheck %s + +declare void @side_effects0() +declare void @side_effects1() + +define void @f_sdiv_not_okay(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_sdiv_not_okay( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = sdiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = sdiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %x = or i16 %xx, 1 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %div.0 = sdiv i16 %0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %div.1 = sdiv i16 %1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +} + +define void @f_srem_okay(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_srem_okay( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = or i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: [[N0:%.*]] = or i16 [[TMP0]], 1 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = srem i16 [[N0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = srem i16 [[N0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %x = or i16 %xx, 1 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %n0 = or i16 %0, 1 + %div.0 = srem i16 %n0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %n1 = or i16 %1, 1 + %div.1 = srem i16 %n1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +} + +define void @f_srem_okay_todo(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_srem_okay_todo( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = add nuw i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: [[N0:%.*]] = or i16 [[TMP0]], 1 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = srem i16 [[N0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = srem i16 [[N0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %x = add nuw i16 %xx, 1 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %n0 = or i16 %0, 1 + %div.0 = srem i16 %n0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %n1 = or i16 %1, 1 + %div.1 = srem i16 %n1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +} + +define void @f_sdiv_okay2(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_sdiv_okay2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[XO:%.*]] = or i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[X:%.*]] = and i16 [[XO]], 123 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = sdiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = sdiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %xo = or i16 %xx, 1 + %x = and i16 %xo, 123 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %div.0 = sdiv i16 %0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %div.1 = sdiv i16 %1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +} + +define void @f_udiv_okay(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_udiv_okay( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = add nuw i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = udiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = udiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %x = add nuw i16 %xx, 1 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %div.0 = udiv i16 %0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %div.1 = udiv i16 %1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +} + +define void @f_udiv_not_okay(i1 %c, ptr %d, ptr %m, ptr %b, i16 %xx) { +; CHECK-LABEL: @f_udiv_not_okay( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = xor i16 [[XX:%.*]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @side_effects0() +; CHECK-NEXT: [[DIV_0:%.*]] = udiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[U:%.*]] = add i16 [[DIV_0]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: call void @side_effects1() +; CHECK-NEXT: [[DIV_1:%.*]] = udiv i16 [[TMP0]], [[X]] +; CHECK-NEXT: [[V:%.*]] = add i16 [[DIV_1]], [[TMP0]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] +; CHECK-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 +; CHECK-NEXT: ret void +; +entry: + %x = xor i16 %xx, 1 + br i1 %c, label %if.then, label %if.else +if.then: + %0 = load i16, ptr %b, align 2 + call void @side_effects0() + %div.0 = udiv i16 %0, %x + %u = add i16 %div.0, %0 + br label %if.end +if.else: + %1 = load i16, ptr %b, align 2 + call void @side_effects1() + %div.1 = udiv i16 %1, %x + %v = add i16 %div.1, %1 + br label %if.end +if.end: + %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] + store i16 %uv, ptr %d, align 2 + ret void +}