diff options
Diffstat (limited to 'test/CodeGen')
565 files changed, 30034 insertions, 1918 deletions
diff --git a/test/CodeGen/AArch64/adc.ll b/test/CodeGen/AArch64/adc.ll new file mode 100644 index 0000000000..7cb373232a --- /dev/null +++ b/test/CodeGen/AArch64/adc.ll @@ -0,0 +1,54 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i128 @test_simple(i128 %a, i128 %b, i128 %c) { +; CHECK: test_simple: + + %valadd = add i128 %a, %b +; CHECK: adds [[ADDLO:x[0-9]+]], x0, x2 +; CHECK-NEXT: adcs [[ADDHI:x[0-9]+]], x1, x3 + + %valsub = sub i128 %valadd, %c +; CHECK: subs x0, [[ADDLO]], x4 +; CHECK: sbcs x1, [[ADDHI]], x5 + + ret i128 %valsub +; CHECK: ret +} + +define i128 @test_imm(i128 %a) { +; CHECK: test_imm: + + %val = add i128 %a, 12 +; CHECK: adds x0, x0, #12 +; CHECK: adcs x1, x1, {{x[0-9]|xzr}} + + ret i128 %val +; CHECK: ret +} + +define i128 @test_shifted(i128 %a, i128 %b) { +; CHECK: test_shifted: + + %rhs = shl i128 %b, 45 + + %val = add i128 %a, %rhs +; CHECK: adds x0, x0, x2, lsl #45 +; CHECK: adcs x1, x1, {{x[0-9]}} + + ret i128 %val +; CHECK: ret +} + +define i128 @test_extended(i128 %a, i16 %b) { +; CHECK: test_extended: + + %ext = sext i16 %b to i128 + %rhs = shl i128 %ext, 3 + + %val = add i128 %a, %rhs +; CHECK: adds x0, x0, w2, sxth #3 +; CHECK: adcs x1, x1, {{x[0-9]}} + + ret i128 %val +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/addsub-shifted.ll b/test/CodeGen/AArch64/addsub-shifted.ll new file mode 100644 index 0000000000..f2c74f6952 --- /dev/null +++ b/test/CodeGen/AArch64/addsub-shifted.ll @@ -0,0 +1,295 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_lsl_arith(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) { +; CHECK: test_lsl_arith: + + %rhs1 = load volatile i32* @var32 + %shift1 = shl i32 %rhs1, 18 + %val1 = add i32 %lhs32, %shift1 + store volatile i32 %val1, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #18 + + %rhs2 = load volatile i32* @var32 + %shift2 = shl i32 %rhs2, 31 + %val2 = add i32 %shift2, %lhs32 + store volatile i32 %val2, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + + %rhs3 = load volatile i32* @var32 + %shift3 = shl i32 %rhs3, 5 + %val3 = sub i32 %lhs32, %shift3 + store volatile i32 %val3, i32* @var32 +; CHECK: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #5 + +; Subtraction is not commutative! + %rhs4 = load volatile i32* @var32 + %shift4 = shl i32 %rhs4, 19 + %val4 = sub i32 %shift4, %lhs32 + store volatile i32 %val4, i32* @var32 +; CHECK-NOT: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #19 + + %lhs4a = load volatile i32* @var32 + %shift4a = shl i32 %lhs4a, 15 + %val4a = sub i32 0, %shift4a + store volatile i32 %val4a, i32* @var32 +; CHECK: sub {{w[0-9]+}}, wzr, {{w[0-9]+}}, lsl #15 + + %rhs5 = load volatile i64* @var64 + %shift5 = shl i64 %rhs5, 18 + %val5 = add i64 %lhs64, %shift5 + store volatile i64 %val5, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #18 + + %rhs6 = load volatile i64* @var64 + %shift6 = shl i64 %rhs6, 31 + %val6 = add i64 %shift6, %lhs64 + store volatile i64 %val6, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #31 + + %rhs7 = load volatile i64* @var64 + %shift7 = shl i64 %rhs7, 5 + %val7 = sub i64 %lhs64, %shift7 + store volatile i64 %val7, i64* @var64 +; CHECK: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #5 + +; Subtraction is not commutative! + %rhs8 = load volatile i64* @var64 + %shift8 = shl i64 %rhs8, 19 + %val8 = sub i64 %shift8, %lhs64 + store volatile i64 %val8, i64* @var64 +; CHECK-NOT: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #19 + + %lhs8a = load volatile i64* @var64 + %shift8a = shl i64 %lhs8a, 60 + %val8a = sub i64 0, %shift8a + store volatile i64 %val8a, i64* @var64 +; CHECK: sub {{x[0-9]+}}, xzr, {{x[0-9]+}}, lsl #60 + + ret void +; CHECK: ret +} + +define void @test_lsr_arith(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) { +; CHECK: test_lsr_arith: + + %shift1 = lshr i32 %rhs32, 18 + %val1 = add i32 %lhs32, %shift1 + store volatile i32 %val1, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #18 + + %shift2 = lshr i32 %rhs32, 31 + %val2 = add i32 %shift2, %lhs32 + store volatile i32 %val2, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #31 + + %shift3 = lshr i32 %rhs32, 5 + %val3 = sub i32 %lhs32, %shift3 + store volatile i32 %val3, i32* @var32 +; CHECK: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #5 + +; Subtraction is not commutative! + %shift4 = lshr i32 %rhs32, 19 + %val4 = sub i32 %shift4, %lhs32 + store volatile i32 %val4, i32* @var32 +; CHECK-NOT: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #19 + + %shift4a = lshr i32 %lhs32, 15 + %val4a = sub i32 0, %shift4a + store volatile i32 %val4a, i32* @var32 +; CHECK: sub {{w[0-9]+}}, wzr, {{w[0-9]+}}, lsr #15 + + %shift5 = lshr i64 %rhs64, 18 + %val5 = add i64 %lhs64, %shift5 + store volatile i64 %val5, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #18 + + %shift6 = lshr i64 %rhs64, 31 + %val6 = add i64 %shift6, %lhs64 + store volatile i64 %val6, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #31 + + %shift7 = lshr i64 %rhs64, 5 + %val7 = sub i64 %lhs64, %shift7 + store volatile i64 %val7, i64* @var64 +; CHECK: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #5 + +; Subtraction is not commutative! + %shift8 = lshr i64 %rhs64, 19 + %val8 = sub i64 %shift8, %lhs64 + store volatile i64 %val8, i64* @var64 +; CHECK-NOT: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #19 + + %shift8a = lshr i64 %lhs64, 45 + %val8a = sub i64 0, %shift8a + store volatile i64 %val8a, i64* @var64 +; CHECK: sub {{x[0-9]+}}, xzr, {{x[0-9]+}}, lsr #45 + + ret void +; CHECK: ret +} + +define void @test_asr_arith(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) { +; CHECK: test_asr_arith: + + %shift1 = ashr i32 %rhs32, 18 + %val1 = add i32 %lhs32, %shift1 + store volatile i32 %val1, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #18 + + %shift2 = ashr i32 %rhs32, 31 + %val2 = add i32 %shift2, %lhs32 + store volatile i32 %val2, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #31 + + %shift3 = ashr i32 %rhs32, 5 + %val3 = sub i32 %lhs32, %shift3 + store volatile i32 %val3, i32* @var32 +; CHECK: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #5 + +; Subtraction is not commutative! + %shift4 = ashr i32 %rhs32, 19 + %val4 = sub i32 %shift4, %lhs32 + store volatile i32 %val4, i32* @var32 +; CHECK-NOT: sub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #19 + + %shift4a = ashr i32 %lhs32, 15 + %val4a = sub i32 0, %shift4a + store volatile i32 %val4a, i32* @var32 +; CHECK: sub {{w[0-9]+}}, wzr, {{w[0-9]+}}, asr #15 + + %shift5 = ashr i64 %rhs64, 18 + %val5 = add i64 %lhs64, %shift5 + store volatile i64 %val5, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #18 + + %shift6 = ashr i64 %rhs64, 31 + %val6 = add i64 %shift6, %lhs64 + store volatile i64 %val6, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #31 + + %shift7 = ashr i64 %rhs64, 5 + %val7 = sub i64 %lhs64, %shift7 + store volatile i64 %val7, i64* @var64 +; CHECK: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #5 + +; Subtraction is not commutative! + %shift8 = ashr i64 %rhs64, 19 + %val8 = sub i64 %shift8, %lhs64 + store volatile i64 %val8, i64* @var64 +; CHECK-NOT: sub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #19 + + %shift8a = ashr i64 %lhs64, 45 + %val8a = sub i64 0, %shift8a + store volatile i64 %val8a, i64* @var64 +; CHECK: sub {{x[0-9]+}}, xzr, {{x[0-9]+}}, asr #45 + + ret void +; CHECK: ret +} + +define i32 @test_cmp(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) { +; CHECK: test_cmp: + + %shift1 = shl i32 %rhs32, 13 + %tst1 = icmp uge i32 %lhs32, %shift1 + br i1 %tst1, label %t2, label %end +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, lsl #13 + +t2: + %shift2 = lshr i32 %rhs32, 20 + %tst2 = icmp ne i32 %lhs32, %shift2 + br i1 %tst2, label %t3, label %end +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, lsr #20 + +t3: + %shift3 = ashr i32 %rhs32, 9 + %tst3 = icmp ne i32 %lhs32, %shift3 + br i1 %tst3, label %t4, label %end +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, asr #9 + +t4: + %shift4 = shl i64 %rhs64, 43 + %tst4 = icmp uge i64 %lhs64, %shift4 + br i1 %tst4, label %t5, label %end +; CHECK: cmp {{x[0-9]+}}, {{x[0-9]+}}, lsl #43 + +t5: + %shift5 = lshr i64 %rhs64, 20 + %tst5 = icmp ne i64 %lhs64, %shift5 + br i1 %tst5, label %t6, label %end +; CHECK: cmp {{x[0-9]+}}, {{x[0-9]+}}, lsr #20 + +t6: + %shift6 = ashr i64 %rhs64, 59 + %tst6 = icmp ne i64 %lhs64, %shift6 + br i1 %tst6, label %t7, label %end +; CHECK: cmp {{x[0-9]+}}, {{x[0-9]+}}, asr #59 + +t7: + ret i32 1 +end: + + ret i32 0 +; CHECK: ret +} + +define i32 @test_cmn(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) { +; CHECK: test_cmn: + + %shift1 = shl i32 %rhs32, 13 + %val1 = sub i32 0, %shift1 + %tst1 = icmp uge i32 %lhs32, %val1 + br i1 %tst1, label %t2, label %end + ; Important that this isn't lowered to a cmn instruction because if %rhs32 == + ; 0 then the results will differ. +; CHECK: sub [[RHS:w[0-9]+]], wzr, {{w[0-9]+}}, lsl #13 +; CHECK: cmp {{w[0-9]+}}, [[RHS]] + +t2: + %shift2 = lshr i32 %rhs32, 20 + %val2 = sub i32 0, %shift2 + %tst2 = icmp ne i32 %lhs32, %val2 + br i1 %tst2, label %t3, label %end +; CHECK: cmn {{w[0-9]+}}, {{w[0-9]+}}, lsr #20 + +t3: + %shift3 = ashr i32 %rhs32, 9 + %val3 = sub i32 0, %shift3 + %tst3 = icmp eq i32 %lhs32, %val3 + br i1 %tst3, label %t4, label %end +; CHECK: cmn {{w[0-9]+}}, {{w[0-9]+}}, asr #9 + +t4: + %shift4 = shl i64 %rhs64, 43 + %val4 = sub i64 0, %shift4 + %tst4 = icmp slt i64 %lhs64, %val4 + br i1 %tst4, label %t5, label %end + ; Again, it's important that cmn isn't used here in case %rhs64 == 0. +; CHECK: sub [[RHS:x[0-9]+]], xzr, {{x[0-9]+}}, lsl #43 +; CHECK: cmp {{x[0-9]+}}, [[RHS]] + +t5: + %shift5 = lshr i64 %rhs64, 20 + %val5 = sub i64 0, %shift5 + %tst5 = icmp ne i64 %lhs64, %val5 + br i1 %tst5, label %t6, label %end +; CHECK: cmn {{x[0-9]+}}, {{x[0-9]+}}, lsr #20 + +t6: + %shift6 = ashr i64 %rhs64, 59 + %val6 = sub i64 0, %shift6 + %tst6 = icmp ne i64 %lhs64, %val6 + br i1 %tst6, label %t7, label %end +; CHECK: cmn {{x[0-9]+}}, {{x[0-9]+}}, asr #59 + +t7: + ret i32 1 +end: + + ret i32 0 +; CHECK: ret +} + diff --git a/test/CodeGen/AArch64/addsub.ll b/test/CodeGen/AArch64/addsub.ll new file mode 100644 index 0000000000..5148807163 --- /dev/null +++ b/test/CodeGen/AArch64/addsub.ll @@ -0,0 +1,127 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +; Note that this should be refactored (for efficiency if nothing else) +; when the PCS is implemented so we don't have to worry about the +; loads and stores. + +@var_i32 = global i32 42 +@var_i64 = global i64 0 + +; Add pure 12-bit immediates: +define void @add_small() { +; CHECK: add_small: + +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, #4095 + %val32 = load i32* @var_i32 + %newval32 = add i32 %val32, 4095 + store i32 %newval32, i32* @var_i32 + +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #52 + %val64 = load i64* @var_i64 + %newval64 = add i64 %val64, 52 + store i64 %newval64, i64* @var_i64 + + ret void +} + +; Add 12-bit immediates, shifted left by 12 bits +define void @add_med() { +; CHECK: add_med: + +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, #3567, lsl #12 + %val32 = load i32* @var_i32 + %newval32 = add i32 %val32, 14610432 ; =0xdef000 + store i32 %newval32, i32* @var_i32 + +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #4095, lsl #12 + %val64 = load i64* @var_i64 + %newval64 = add i64 %val64, 16773120 ; =0xfff000 + store i64 %newval64, i64* @var_i64 + + ret void +} + +; Subtract 12-bit immediates +define void @sub_small() { +; CHECK: sub_small: + +; CHECK: sub {{w[0-9]+}}, {{w[0-9]+}}, #4095 + %val32 = load i32* @var_i32 + %newval32 = sub i32 %val32, 4095 + store i32 %newval32, i32* @var_i32 + +; CHECK: sub {{x[0-9]+}}, {{x[0-9]+}}, #52 + %val64 = load i64* @var_i64 + %newval64 = sub i64 %val64, 52 + store i64 %newval64, i64* @var_i64 + + ret void +} + +; Subtract 12-bit immediates, shifted left by 12 bits +define void @sub_med() { +; CHECK: sub_med: + +; CHECK: sub {{w[0-9]+}}, {{w[0-9]+}}, #3567, lsl #12 + %val32 = load i32* @var_i32 + %newval32 = sub i32 %val32, 14610432 ; =0xdef000 + store i32 %newval32, i32* @var_i32 + +; CHECK: sub {{x[0-9]+}}, {{x[0-9]+}}, #4095, lsl #12 + %val64 = load i64* @var_i64 + %newval64 = sub i64 %val64, 16773120 ; =0xfff000 + store i64 %newval64, i64* @var_i64 + + ret void +} + +define void @testing() { +; CHECK: testing: + %val = load i32* @var_i32 + +; CHECK: cmp {{w[0-9]+}}, #4095 +; CHECK: b.ne .LBB4_6 + %cmp_pos_small = icmp ne i32 %val, 4095 + br i1 %cmp_pos_small, label %ret, label %test2 + +test2: +; CHECK: cmp {{w[0-9]+}}, #3567, lsl #12 +; CHECK: b.lo .LBB4_6 + %newval2 = add i32 %val, 1 + store i32 %newval2, i32* @var_i32 + %cmp_pos_big = icmp ult i32 %val, 14610432 + br i1 %cmp_pos_big, label %ret, label %test3 + +test3: +; CHECK: cmp {{w[0-9]+}}, #123 +; CHECK: b.lt .LBB4_6 + %newval3 = add i32 %val, 2 + store i32 %newval3, i32* @var_i32 + %cmp_pos_slt = icmp slt i32 %val, 123 + br i1 %cmp_pos_slt, label %ret, label %test4 + +test4: +; CHECK: cmp {{w[0-9]+}}, #321 +; CHECK: b.gt .LBB4_6 + %newval4 = add i32 %val, 3 + store i32 %newval4, i32* @var_i32 + %cmp_pos_sgt = icmp sgt i32 %val, 321 + br i1 %cmp_pos_sgt, label %ret, label %test5 + +test5: +; CHECK: cmn {{w[0-9]+}}, #444 +; CHECK: b.gt .LBB4_6 + %newval5 = add i32 %val, 4 + store i32 %newval5, i32* @var_i32 + %cmp_neg_uge = icmp sgt i32 %val, -444 + br i1 %cmp_neg_uge, label %ret, label %test6 + +test6: + %newval6 = add i32 %val, 5 + store i32 %newval6, i32* @var_i32 + ret void + +ret: + ret void +} +; TODO: adds/subs diff --git a/test/CodeGen/AArch64/addsub_ext.ll b/test/CodeGen/AArch64/addsub_ext.ll new file mode 100644 index 0000000000..2dd16626ea --- /dev/null +++ b/test/CodeGen/AArch64/addsub_ext.ll @@ -0,0 +1,189 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var8 = global i8 0 +@var16 = global i16 0 +@var32 = global i32 0 +@var64 = global i64 0 + +define void @addsub_i8rhs() { +; CHECK: addsub_i8rhs: + %val8_tmp = load i8* @var8 + %lhs32 = load i32* @var32 + %lhs64 = load i64* @var64 + + ; Need this to prevent extension upon load and give a vanilla i8 operand. + %val8 = add i8 %val8_tmp, 123 + + +; Zero-extending to 32-bits + %rhs32_zext = zext i8 %val8 to i32 + %res32_zext = add i32 %lhs32, %rhs32_zext + store volatile i32 %res32_zext, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxtb + + %rhs32_zext_shift = shl i32 %rhs32_zext, 3 + %res32_zext_shift = add i32 %lhs32, %rhs32_zext_shift + store volatile i32 %res32_zext_shift, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxtb #3 + + +; Zero-extending to 64-bits + %rhs64_zext = zext i8 %val8 to i64 + %res64_zext = add i64 %lhs64, %rhs64_zext + store volatile i64 %res64_zext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtb + + %rhs64_zext_shift = shl i64 %rhs64_zext, 1 + %res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift + store volatile i64 %res64_zext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtb #1 + +; Sign-extending to 32-bits + %rhs32_sext = sext i8 %val8 to i32 + %res32_sext = add i32 %lhs32, %rhs32_sext + store volatile i32 %res32_sext, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxtb + + %rhs32_sext_shift = shl i32 %rhs32_sext, 1 + %res32_sext_shift = add i32 %lhs32, %rhs32_sext_shift + store volatile i32 %res32_sext_shift, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxtb #1 + +; Sign-extending to 64-bits + %rhs64_sext = sext i8 %val8 to i64 + %res64_sext = add i64 %lhs64, %rhs64_sext + store volatile i64 %res64_sext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtb + + %rhs64_sext_shift = shl i64 %rhs64_sext, 4 + %res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift + store volatile i64 %res64_sext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtb #4 + + +; CMP variants + %tst = icmp slt i32 %lhs32, %rhs32_zext + br i1 %tst, label %end, label %test2 +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, uxtb + +test2: + %cmp_sext = sext i8 %val8 to i64 + %tst2 = icmp eq i64 %lhs64, %cmp_sext + br i1 %tst2, label %other, label %end +; CHECK: cmp {{x[0-9]+}}, {{w[0-9]+}}, sxtb + +other: + store volatile i32 %lhs32, i32* @var32 + ret void + +end: + ret void +} + +define void @addsub_i16rhs() { +; CHECK: addsub_i16rhs: + %val16_tmp = load i16* @var16 + %lhs32 = load i32* @var32 + %lhs64 = load i64* @var64 + + ; Need this to prevent extension upon load and give a vanilla i16 operand. + %val16 = add i16 %val16_tmp, 123 + + +; Zero-extending to 32-bits + %rhs32_zext = zext i16 %val16 to i32 + %res32_zext = add i32 %lhs32, %rhs32_zext + store volatile i32 %res32_zext, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxth + + %rhs32_zext_shift = shl i32 %rhs32_zext, 3 + %res32_zext_shift = add i32 %lhs32, %rhs32_zext_shift + store volatile i32 %res32_zext_shift, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, uxth #3 + + +; Zero-extending to 64-bits + %rhs64_zext = zext i16 %val16 to i64 + %res64_zext = add i64 %lhs64, %rhs64_zext + store volatile i64 %res64_zext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxth + + %rhs64_zext_shift = shl i64 %rhs64_zext, 1 + %res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift + store volatile i64 %res64_zext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxth #1 + +; Sign-extending to 32-bits + %rhs32_sext = sext i16 %val16 to i32 + %res32_sext = add i32 %lhs32, %rhs32_sext + store volatile i32 %res32_sext, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxth + + %rhs32_sext_shift = shl i32 %rhs32_sext, 1 + %res32_sext_shift = add i32 %lhs32, %rhs32_sext_shift + store volatile i32 %res32_sext_shift, i32* @var32 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxth #1 + +; Sign-extending to 64-bits + %rhs64_sext = sext i16 %val16 to i64 + %res64_sext = add i64 %lhs64, %rhs64_sext + store volatile i64 %res64_sext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxth + + %rhs64_sext_shift = shl i64 %rhs64_sext, 4 + %res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift + store volatile i64 %res64_sext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxth #4 + + +; CMP variants + %tst = icmp slt i32 %lhs32, %rhs32_zext + br i1 %tst, label %end, label %test2 +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}, uxth + +test2: + %cmp_sext = sext i16 %val16 to i64 + %tst2 = icmp eq i64 %lhs64, %cmp_sext + br i1 %tst2, label %other, label %end +; CHECK: cmp {{x[0-9]+}}, {{w[0-9]+}}, sxth + +other: + store volatile i32 %lhs32, i32* @var32 + ret void + +end: + ret void +} + +; N.b. we could probably check more here ("add w2, w3, w1, uxtw" for +; example), but the remaining instructions are probably not idiomatic +; in the face of "add/sub (shifted register)" so I don't intend to. +define void @addsub_i32rhs() { +; CHECK: addsub_i32rhs: + %val32_tmp = load i32* @var32 + %lhs64 = load i64* @var64 + + %val32 = add i32 %val32_tmp, 123 + + %rhs64_zext = zext i32 %val32 to i64 + %res64_zext = add i64 %lhs64, %rhs64_zext + store volatile i64 %res64_zext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtw + + %rhs64_zext_shift = shl i64 %rhs64_zext, 2 + %res64_zext_shift = add i64 %lhs64, %rhs64_zext_shift + store volatile i64 %res64_zext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, uxtw #2 + + %rhs64_sext = sext i32 %val32 to i64 + %res64_sext = add i64 %lhs64, %rhs64_sext + store volatile i64 %res64_sext, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtw + + %rhs64_sext_shift = shl i64 %rhs64_sext, 2 + %res64_sext_shift = add i64 %lhs64, %rhs64_sext_shift + store volatile i64 %res64_sext_shift, i64* @var64 +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtw #2 + + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/adrp-relocation.ll b/test/CodeGen/AArch64/adrp-relocation.ll new file mode 100644 index 0000000000..c33b442624 --- /dev/null +++ b/test/CodeGen/AArch64/adrp-relocation.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -filetype=obj < %s | elf-dump | FileCheck %s + +define i64 @testfn() nounwind { +entry: + ret i64 0 +} + +define i64 @foo() nounwind { +entry: + %bar = alloca i64 ()*, align 8 + store i64 ()* @testfn, i64 ()** %bar, align 8 + %call = call i64 @testfn() + ret i64 %call +} + +; The above should produce an ADRP/ADD pair to calculate the address of +; testfn. The important point is that LLVM shouldn't think it can deal with the +; relocation on the ADRP itself (even though it knows everything about the +; relative offsets of testfn and foo) because its value depends on where this +; object file's .text section gets relocated in memory. + +; CHECK: .rela.text + +; CHECK: # Relocation 0 +; CHECK-NEXT: (('r_offset', 0x0000000000000010) +; CHECK-NEXT: ('r_sym', 0x00000007) +; CHECK-NEXT: ('r_type', 0x00000113) +; CHECK-NEXT: ('r_addend', 0x0000000000000000) +; CHECK-NEXT: ), +; CHECK-NEXT: Relocation 1 +; CHECK-NEXT: (('r_offset', 0x0000000000000014) +; CHECK-NEXT: ('r_sym', 0x00000007) +; CHECK-NEXT: ('r_type', 0x00000115) +; CHECK-NEXT: ('r_addend', 0x0000000000000000) +; CHECK-NEXT: ), diff --git a/test/CodeGen/AArch64/alloca.ll b/test/CodeGen/AArch64/alloca.ll new file mode 100644 index 0000000000..64217695d8 --- /dev/null +++ b/test/CodeGen/AArch64/alloca.ll @@ -0,0 +1,134 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +declare void @use_addr(i8*) + +define void @test_simple_alloca(i64 %n) { +; CHECK: test_simple_alloca: + + %buf = alloca i8, i64 %n + ; Make sure we align the stack change to 16 bytes: +; CHECK: add [[SPDELTA:x[0-9]+]], x0, #15 +; CHECK: and x0, [[SPDELTA]], #0xfffffffffffffff0 + + ; Make sure we change SP. It would be surprising if anything but x0 were used + ; for the final sp, but it could be if it was then moved into x0. +; CHECK: mov [[TMP:x[0-9]+]], sp +; CHECK: sub x0, [[TMP]], [[SPDELTA]] +; CHECK: mov sp, x0 + + call void @use_addr(i8* %buf) +; CHECK: bl use_addr + + ret void + ; Make sure epilogue restores sp from fp +; CHECK: sub sp, x29, #16 +; CHECK: ldp x29, x30, [sp, #16] +; CHECK: add sp, sp, #32 +; CHECK: ret +} + +declare void @use_addr_loc(i8*, i64*) + +define i64 @test_alloca_with_local(i64 %n) { +; CHECK: test_alloca_with_local: +; CHECK: sub sp, sp, #32 +; CHECK: stp x29, x30, [sp, #16] + + %loc = alloca i64 + %buf = alloca i8, i64 %n + ; Make sure we align the stack change to 16 bytes: +; CHECK: add [[SPDELTA:x[0-9]+]], x0, #15 +; CHECK: and x0, [[SPDELTA]], #0xfffffffffffffff0 + + ; Make sure we change SP. It would be surprising if anything but x0 were used + ; for the final sp, but it could be if it was then moved into x0. +; CHECK: mov [[TMP:x[0-9]+]], sp +; CHECK: sub x0, [[TMP]], [[SPDELTA]] +; CHECK: mov sp, x0 + + ; Obviously suboptimal code here, but it to get &local in x1 +; CHECK: sub [[TMP:x[0-9]+]], x29, [[LOC_FROM_FP:#[0-9]+]] +; CHECK: add x1, [[TMP]], #0 + + call void @use_addr_loc(i8* %buf, i64* %loc) +; CHECK: bl use_addr + + %val = load i64* %loc +; CHECK: sub x[[TMP:[0-9]+]], x29, [[LOC_FROM_FP]] +; CHECK: ldr x0, [x[[TMP]]] + + ret i64 %val + ; Make sure epilogue restores sp from fp +; CHECK: sub sp, x29, #16 +; CHECK: ldp x29, x30, [sp, #16] +; CHECK: add sp, sp, #32 +; CHECK: ret +} + +define void @test_variadic_alloca(i64 %n, ...) { +; CHECK: test_variadic_alloca: + +; CHECK: sub sp, sp, #208 +; CHECK: stp x29, x30, [sp, #192] +; CHECK: add x29, sp, #192 +; CHECK: sub x9, x29, #192 +; CHECK: add x8, x9, #0 +; CHECK: str q7, [x8, #112] +; [...] +; CHECK: str q1, [x8, #16] + + %addr = alloca i8, i64 %n + + call void @use_addr(i8* %addr) +; CHECK: bl use_addr + + ret void +; CHECK: sub sp, x29, #192 +; CHECK: ldp x29, x30, [sp, #192] +; CHECK: add sp, sp, #208 +} + +define void @test_alloca_large_frame(i64 %n) { +; CHECK: test_alloca_large_frame: + +; CHECK: sub sp, sp, #496 +; CHECK: stp x29, x30, [sp, #480] +; CHECK: add x29, sp, #480 +; CHECK: sub sp, sp, #48 +; CHECK: sub sp, sp, #1953, lsl #12 + + %addr1 = alloca i8, i64 %n + %addr2 = alloca i64, i64 1000000 + + call void @use_addr_loc(i8* %addr1, i64* %addr2) + + ret void +; CHECK: sub sp, x29, #480 +; CHECK: ldp x29, x30, [sp, #480] +; CHECK: add sp, sp, #496 +} + +declare i8* @llvm.stacksave() +declare void @llvm.stackrestore(i8*) + +define void @test_scoped_alloca(i64 %n) { +; CHECK: test_scoped_alloca +; CHECK: sub sp, sp, #32 + + %sp = call i8* @llvm.stacksave() +; CHECK: mov [[SAVED_SP:x[0-9]+]], sp + + %addr = alloca i8, i64 %n +; CHECK: and [[SPDELTA:x[0-9]+]], {{x[0-9]+}}, #0xfffffffffffffff0 +; CHECK: mov [[OLDSP:x[0-9]+]], sp +; CHECK: sub [[NEWSP:x[0-9]+]], [[OLDSP]], [[SPDELTA]] +; CHECK: mov sp, [[NEWSP]] + + call void @use_addr(i8* %addr) +; CHECK: bl use_addr + + call void @llvm.stackrestore(i8* %sp) +; CHECK: mov sp, [[SAVED_SP]] + + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/analyze-branch.ll b/test/CodeGen/AArch64/analyze-branch.ll new file mode 100644 index 0000000000..e10bbb0f86 --- /dev/null +++ b/test/CodeGen/AArch64/analyze-branch.ll @@ -0,0 +1,231 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +; This test checks that LLVM can do basic stripping and reapplying of branches +; to basic blocks. + +declare void @test_true() +declare void @test_false() + +; !0 corresponds to a branch being taken, !1 to not being takne. +!0 = metadata !{metadata !"branch_weights", i32 64, i32 4} +!1 = metadata !{metadata !"branch_weights", i32 4, i32 64} + +define void @test_Bcc_fallthrough_taken(i32 %in) nounwind { +; CHECK: test_Bcc_fallthrough_taken: + %tst = icmp eq i32 %in, 42 + br i1 %tst, label %true, label %false, !prof !0 + +; CHECK: cmp {{w[0-9]+}}, #42 + +; CHECK: b.ne [[FALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_true + +; CHECK: [[FALSE]]: +; CHECK: bl test_false + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_Bcc_fallthrough_nottaken(i32 %in) nounwind { +; CHECK: test_Bcc_fallthrough_nottaken: + %tst = icmp eq i32 %in, 42 + br i1 %tst, label %true, label %false, !prof !1 + +; CHECK: cmp {{w[0-9]+}}, #42 + +; CHECK: b.eq [[TRUE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_false + +; CHECK: [[TRUE]]: +; CHECK: bl test_true + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_CBZ_fallthrough_taken(i32 %in) nounwind { +; CHECK: test_CBZ_fallthrough_taken: + %tst = icmp eq i32 %in, 0 + br i1 %tst, label %true, label %false, !prof !0 + +; CHECK: cbnz {{w[0-9]+}}, [[FALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_true + +; CHECK: [[FALSE]]: +; CHECK: bl test_false + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_CBZ_fallthrough_nottaken(i64 %in) nounwind { +; CHECK: test_CBZ_fallthrough_nottaken: + %tst = icmp eq i64 %in, 0 + br i1 %tst, label %true, label %false, !prof !1 + +; CHECK: cbz {{x[0-9]+}}, [[TRUE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_false + +; CHECK: [[TRUE]]: +; CHECK: bl test_true + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_CBNZ_fallthrough_taken(i32 %in) nounwind { +; CHECK: test_CBNZ_fallthrough_taken: + %tst = icmp ne i32 %in, 0 + br i1 %tst, label %true, label %false, !prof !0 + +; CHECK: cbz {{w[0-9]+}}, [[FALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_true + +; CHECK: [[FALSE]]: +; CHECK: bl test_false + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_CBNZ_fallthrough_nottaken(i64 %in) nounwind { +; CHECK: test_CBNZ_fallthrough_nottaken: + %tst = icmp ne i64 %in, 0 + br i1 %tst, label %true, label %false, !prof !1 + +; CHECK: cbnz {{x[0-9]+}}, [[TRUE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_false + +; CHECK: [[TRUE]]: +; CHECK: bl test_true + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_TBZ_fallthrough_taken(i32 %in) nounwind { +; CHECK: test_TBZ_fallthrough_taken: + %bit = and i32 %in, 32768 + %tst = icmp eq i32 %bit, 0 + br i1 %tst, label %true, label %false, !prof !0 + +; CHECK: tbnz {{w[0-9]+}}, #15, [[FALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_true + +; CHECK: [[FALSE]]: +; CHECK: bl test_false + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_TBZ_fallthrough_nottaken(i64 %in) nounwind { +; CHECK: test_TBZ_fallthrough_nottaken: + %bit = and i64 %in, 32768 + %tst = icmp eq i64 %bit, 0 + br i1 %tst, label %true, label %false, !prof !1 + +; CHECK: tbz {{x[0-9]+}}, #15, [[TRUE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_false + +; CHECK: [[TRUE]]: +; CHECK: bl test_true + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + + +define void @test_TBNZ_fallthrough_taken(i32 %in) nounwind { +; CHECK: test_TBNZ_fallthrough_taken: + %bit = and i32 %in, 32768 + %tst = icmp ne i32 %bit, 0 + br i1 %tst, label %true, label %false, !prof !0 + +; CHECK: tbz {{w[0-9]+}}, #15, [[FALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_true + +; CHECK: [[FALSE]]: +; CHECK: bl test_false + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + +define void @test_TBNZ_fallthrough_nottaken(i64 %in) nounwind { +; CHECK: test_TBNZ_fallthrough_nottaken: + %bit = and i64 %in, 32768 + %tst = icmp ne i64 %bit, 0 + br i1 %tst, label %true, label %false, !prof !1 + +; CHECK: tbnz {{x[0-9]+}}, #15, [[TRUE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: // BB# +; CHECK-NEXT: bl test_false + +; CHECK: [[TRUE]]: +; CHECK: bl test_true + +true: + call void @test_true() + ret void + +false: + call void @test_false() + ret void +} + diff --git a/test/CodeGen/AArch64/atomic-ops-not-barriers.ll b/test/CodeGen/AArch64/atomic-ops-not-barriers.ll new file mode 100644 index 0000000000..3c03e47147 --- /dev/null +++ b/test/CodeGen/AArch64/atomic-ops-not-barriers.ll @@ -0,0 +1,24 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +define i32 @foo(i32* %var, i1 %cond) { +; CHECK: foo: + br i1 %cond, label %atomic_ver, label %simple_ver +simple_ver: + %oldval = load i32* %var + %newval = add nsw i32 %oldval, -1 + store i32 %newval, i32* %var + br label %somewhere +atomic_ver: + %val = atomicrmw add i32* %var, i32 -1 seq_cst + br label %somewhere +; CHECK: dmb +; CHECK: ldxr +; CHECK: dmb + ; The key point here is that the second dmb isn't immediately followed by the + ; simple_ver basic block, which LLVM attempted to do when DMB had been marked + ; with isBarrier. For now, look for something that looks like "somewhere". +; CHECK-NEXT: mov +somewhere: + %combined = phi i32 [ %val, %atomic_ver ], [ %newval, %simple_ver] + ret i32 %combined +} diff --git a/test/CodeGen/AArch64/atomic-ops.ll b/test/CodeGen/AArch64/atomic-ops.ll new file mode 100644 index 0000000000..f3c16171cc --- /dev/null +++ b/test/CodeGen/AArch64/atomic-ops.ll @@ -0,0 +1,1055 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +@var8 = global i8 0 +@var16 = global i16 0 +@var32 = global i32 0 +@var64 = global i64 0 + +define i8 @test_atomic_load_add_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_add_i8: + %old = atomicrmw add i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_add_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_add_i16: + %old = atomicrmw add i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_add_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_add_i32: + %old = atomicrmw add i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_add_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_add_i64: + %old = atomicrmw add i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: add [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_sub_i8: + %old = atomicrmw sub i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_sub_i16: + %old = atomicrmw sub i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_sub_i32: + %old = atomicrmw sub i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_sub_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_sub_i64: + %old = atomicrmw sub i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_and_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_and_i8: + %old = atomicrmw and i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_and_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_and_i16: + %old = atomicrmw and i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_and_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_and_i32: + %old = atomicrmw and i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_and_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_and_i64: + %old = atomicrmw and i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_or_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_or_i8: + %old = atomicrmw or i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_or_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_or_i16: + %old = atomicrmw or i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_or_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_or_i32: + %old = atomicrmw or i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_or_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_or_i64: + %old = atomicrmw or i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_xor_i8: + %old = atomicrmw xor i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_xor_i16: + %old = atomicrmw xor i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_xor_i32: + %old = atomicrmw xor i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_xor_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_xor_i64: + %old = atomicrmw xor i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_xchg_i8: + %old = atomicrmw xchg i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_xchg_i16: + %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_xchg_i32: + %old = atomicrmw xchg i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_xchg_i64: + %old = atomicrmw xchg i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + + +define i8 @test_atomic_load_min_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_min_i8: + %old = atomicrmw min i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], sxtb +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_min_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_min_i16: + %old = atomicrmw min i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], sxth +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_min_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_min_i32: + %old = atomicrmw min i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]] +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_min_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_min_i64: + %old = atomicrmw min i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp x0, x[[OLD]] +; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_max_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_max_i8: + %old = atomicrmw max i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], sxtb +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_max_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_max_i16: + %old = atomicrmw max i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], sxth +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_max_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_max_i32: + %old = atomicrmw max i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]] +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_max_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_max_i64: + %old = atomicrmw max i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp x0, x[[OLD]] +; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lt +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_umin_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_umin_i8: + %old = atomicrmw umin i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], uxtb +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_umin_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_umin_i16: + %old = atomicrmw umin i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], uxth +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_umin_i32: + %old = atomicrmw umin i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]] +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_umin_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_umin_i64: + %old = atomicrmw umin i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp x0, x[[OLD]] +; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_umax_i8(i8 %offset) nounwind { +; CHECK: test_atomic_load_umax_i8: + %old = atomicrmw umax i8* @var8, i8 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], uxtb +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_load_umax_i16(i16 %offset) nounwind { +; CHECK: test_atomic_load_umax_i16: + %old = atomicrmw umax i16* @var16, i16 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]], uxth +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind { +; CHECK: test_atomic_load_umax_i32: + %old = atomicrmw umax i32* @var32, i32 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w0, w[[OLD]] +; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_load_umax_i64(i64 %offset) nounwind { +; CHECK: test_atomic_load_umax_i64: + %old = atomicrmw umax i64* @var64, i64 %offset seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: .LBB{{[0-9]+}}_1: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; x0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp x0, x[[OLD]] +; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lo +; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind { +; CHECK: test_atomic_cmpxchg_i8: + %old = cmpxchg i8* @var8, i8 %wanted, i8 %new seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]: +; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w[[OLD]], w0 +; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] + ; As above, w1 is a reasonable guess. +; CHECK: stxrb [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i8 %old +} + +define i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind { +; CHECK: test_atomic_cmpxchg_i16: + %old = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var16 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16 + +; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]: +; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w[[OLD]], w0 +; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] + ; As above, w1 is a reasonable guess. +; CHECK: stxrh [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i16 %old +} + +define i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind { +; CHECK: test_atomic_cmpxchg_i32: + %old = cmpxchg i32* @var32, i32 %wanted, i32 %new seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32 + +; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]: +; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp w[[OLD]], w0 +; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] + ; As above, w1 is a reasonable guess. +; CHECK: stxr [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i32 %old +} + +define i64 @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind { +; CHECK: test_atomic_cmpxchg_i64: + %old = cmpxchg i64* @var64, i64 %wanted, i64 %new seq_cst +; CHECK: dmb ish +; CHECK: adrp [[TMPADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64 + +; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]: +; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]] + ; w0 below is a reasonable guess but could change: it certainly comes into the + ; function there. +; CHECK-NEXT: cmp x[[OLD]], x0 +; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] + ; As above, w1 is a reasonable guess. +; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]] +; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] +; CHECK: dmb ish + +; CHECK: mov x0, x[[OLD]] + ret i64 %old +} + +define i8 @test_atomic_load_monotonic_i8() nounwind { +; CHECK: test_atomic_load_monotonic_i8: + %val = load atomic i8* @var8 monotonic, align 1 +; CHECK-NOT: dmb +; CHECK: adrp x[[HIADDR:[0-9]+]], var8 +; CHECK: ldrb w0, [x[[HIADDR]], #:lo12:var8] +; CHECK-NOT: dmb + + ret i8 %val +} + +define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind { +; CHECK: test_atomic_load_monotonic_regoff_i8: + %addr_int = add i64 %base, %off + %addr = inttoptr i64 %addr_int to i8* + + %val = load atomic i8* %addr monotonic, align 1 +; CHECK-NOT: dmb +; CHECK: ldrb w0, [x0, x1] +; CHECK-NOT: dmb + + ret i8 %val +} + +define i8 @test_atomic_load_acquire_i8() nounwind { +; CHECK: test_atomic_load_acquire_i8: + %val = load atomic i8* @var8 acquire, align 1 +; CHECK: adrp [[TMPADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8 + +; CHECK: ldarb w0, [x[[ADDR]]] + ret i8 %val +} + +define i8 @test_atomic_load_seq_cst_i8() nounwind { +; CHECK: test_atomic_load_seq_cst_i8: + %val = load atomic i8* @var8 seq_cst, align 1 +; CHECK: adrp x[[HIADDR:[0-9]+]], var8 +; CHECK: ldrb w0, [x[[HIADDR]], #:lo12:var8] +; CHECK: dmb ish + ret i8 %val +} + +define i16 @test_atomic_load_monotonic_i16() nounwind { +; CHECK: test_atomic_load_monotonic_i16: + %val = load atomic i16* @var16 monotonic, align 2 +; CHECK-NOT: dmb +; CHECK: adrp x[[HIADDR:[0-9]+]], var16 +; CHECK: ldrh w0, [x[[HIADDR]], #:lo12:var16] +; CHECK-NOT: dmb + + ret i16 %val +} + +define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind { +; CHECK: test_atomic_load_monotonic_regoff_i32: + %addr_int = add i64 %base, %off + %addr = inttoptr i64 %addr_int to i32* + + %val = load atomic i32* %addr monotonic, align 4 +; CHECK-NOT: dmb +; CHECK: ldr w0, [x0, x1] +; CHECK-NOT: dmb + + ret i32 %val +} + +define i64 @test_atomic_load_seq_cst_i64() nounwind { +; CHECK: test_atomic_load_seq_cst_i64: + %val = load atomic i64* @var64 seq_cst, align 8 +; CHECK: adrp x[[HIADDR:[0-9]+]], var64 +; CHECK: ldr x0, [x[[HIADDR]], #:lo12:var64] +; CHECK: dmb ish + ret i64 %val +} + +define void @test_atomic_store_monotonic_i8(i8 %val) nounwind { +; CHECK: test_atomic_store_monotonic_i8: + store atomic i8 %val, i8* @var8 monotonic, align 1 +; CHECK: adrp x[[HIADDR:[0-9]+]], var8 +; CHECK: strb w0, [x[[HIADDR]], #:lo12:var8] + + ret void +} + +define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind { +; CHECK: test_atomic_store_monotonic_regoff_i8: + + %addr_int = add i64 %base, %off + %addr = inttoptr i64 %addr_int to i8* + + store atomic i8 %val, i8* %addr monotonic, align 1 +; CHECK: strb w2, [x0, x1] + + ret void +} +define void @test_atomic_store_release_i8(i8 %val) nounwind { +; CHECK: test_atomic_store_release_i8: + store atomic i8 %val, i8* @var8 release, align 1 +; CHECK: adrp [[HIADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8 +; CHECK: stlrb w0, [x[[ADDR]]] + + ret void +} + +define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind { +; CHECK: test_atomic_store_seq_cst_i8: + store atomic i8 %val, i8* @var8 seq_cst, align 1 +; CHECK: adrp [[HIADDR:x[0-9]+]], var8 +; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8 +; CHECK: stlrb w0, [x[[ADDR]]] +; CHECK: dmb ish + + ret void +} + +define void @test_atomic_store_monotonic_i16(i16 %val) nounwind { +; CHECK: test_atomic_store_monotonic_i16: + store atomic i16 %val, i16* @var16 monotonic, align 2 +; CHECK: adrp x[[HIADDR:[0-9]+]], var16 +; CHECK: strh w0, [x[[HIADDR]], #:lo12:var16] + + ret void +} + +define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind { +; CHECK: test_atomic_store_monotonic_regoff_i32: + + %addr_int = add i64 %base, %off + %addr = inttoptr i64 %addr_int to i32* + + store atomic i32 %val, i32* %addr monotonic, align 4 +; CHECK: str w2, [x0, x1] + + ret void +} + +define void @test_atomic_store_release_i64(i64 %val) nounwind { +; CHECK: test_atomic_store_release_i64: + store atomic i64 %val, i64* @var64 release, align 8 +; CHECK: adrp [[HIADDR:x[0-9]+]], var64 +; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var64 +; CHECK: stlr x0, [x[[ADDR]]] + + ret void +} diff --git a/test/CodeGen/AArch64/basic-pic.ll b/test/CodeGen/AArch64/basic-pic.ll new file mode 100644 index 0000000000..da94041c95 --- /dev/null +++ b/test/CodeGen/AArch64/basic-pic.ll @@ -0,0 +1,70 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -relocation-model=pic %s -o - | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -relocation-model=pic -filetype=obj %s -o -| llvm-objdump -r - | FileCheck --check-prefix=CHECK-ELF %s + +@var = global i32 0 + +; CHECK-ELF: RELOCATION RECORDS FOR [.text] + +define i32 @get_globalvar() { +; CHECK: get_globalvar: + + %val = load i32* @var +; CHECK: adrp x[[GOTHI:[0-9]+]], :got:var +; CHECK: ldr x[[GOTLOC:[0-9]+]], [x[[GOTHI]], #:got_lo12:var] +; CHECK: ldr w0, [x[[GOTLOC]]] + +; CHECK-ELF: R_AARCH64_ADR_GOT_PAGE var +; CHECK-ELF: R_AARCH64_LD64_GOT_LO12_NC var + ret i32 %val +} + +define i32* @get_globalvaraddr() { +; CHECK: get_globalvaraddr: + + %val = load i32* @var +; CHECK: adrp x[[GOTHI:[0-9]+]], :got:var +; CHECK: ldr x0, [x[[GOTHI]], #:got_lo12:var] + +; CHECK-ELF: R_AARCH64_ADR_GOT_PAGE var +; CHECK-ELF: R_AARCH64_LD64_GOT_LO12_NC var + ret i32* @var +} + +@hiddenvar = hidden global i32 0 + +define i32 @get_hiddenvar() { +; CHECK: get_hiddenvar: + + %val = load i32* @hiddenvar +; CHECK: adrp x[[HI:[0-9]+]], hiddenvar +; CHECK: ldr w0, [x[[HI]], #:lo12:hiddenvar] + +; CHECK-ELF: R_AARCH64_ADR_PREL_PG_HI21 hiddenvar +; CHECK-ELF: R_AARCH64_LDST32_ABS_LO12_NC hiddenvar + ret i32 %val +} + +define i32* @get_hiddenvaraddr() { +; CHECK: get_hiddenvaraddr: + + %val = load i32* @hiddenvar +; CHECK: adrp [[HI:x[0-9]+]], hiddenvar +; CHECK: add x0, [[HI]], #:lo12:hiddenvar + +; CHECK-ELF: R_AARCH64_ADR_PREL_PG_HI21 hiddenvar +; CHECK-ELF: R_AARCH64_ADD_ABS_LO12_NC hiddenvar + ret i32* @hiddenvar +} + +define void()* @get_func() { +; CHECK: get_func: + + ret void()* bitcast(void()*()* @get_func to void()*) +; CHECK: adrp x[[GOTHI:[0-9]+]], :got:get_func +; CHECK: ldr x0, [x[[GOTHI]], #:got_lo12:get_func] + + ; Particularly important that the ADRP gets a relocation, LLVM tends to think + ; it can relax it because it knows where get_func is. It can't! +; CHECK-ELF: R_AARCH64_ADR_GOT_PAGE get_func +; CHECK-ELF: R_AARCH64_LD64_GOT_LO12_NC get_func +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/bitfield-insert-0.ll b/test/CodeGen/AArch64/bitfield-insert-0.ll new file mode 100644 index 0000000000..d1191f6aaa --- /dev/null +++ b/test/CodeGen/AArch64/bitfield-insert-0.ll @@ -0,0 +1,19 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -filetype=obj < %s | llvm-objdump -disassemble - | FileCheck %s + +; The encoding of lsb -> immr in the CGed bitfield instructions was wrong at one +; point, in the edge case where lsb = 0. Just make sure. + +define void @test_bfi0(i32* %existing, i32* %new) { +; CHECK: bfxil {{w[0-9]+}}, {{w[0-9]+}}, #0, #18 + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 4294705152 ; 0xfffc_0000 + + %newval = load volatile i32* %new + %newval_masked = and i32 %newval, 262143 ; = 0x0003_ffff + + %combined = or i32 %newval_masked, %oldval_keep + store volatile i32 %combined, i32* %existing + + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/bitfield-insert.ll b/test/CodeGen/AArch64/bitfield-insert.ll new file mode 100644 index 0000000000..3e871b9a6d --- /dev/null +++ b/test/CodeGen/AArch64/bitfield-insert.ll @@ -0,0 +1,193 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +; First, a simple example from Clang. The registers could plausibly be +; different, but probably won't be. + +%struct.foo = type { i8, [2 x i8], i8 } + +define [1 x i64] @from_clang([1 x i64] %f.coerce, i32 %n) nounwind readnone { +; CHECK: from_clang: +; CHECK: bfi w0, w1, #3, #4 +; CHECK-NEXT: ret + +entry: + %f.coerce.fca.0.extract = extractvalue [1 x i64] %f.coerce, 0 + %tmp.sroa.0.0.extract.trunc = trunc i64 %f.coerce.fca.0.extract to i32 + %bf.value = shl i32 %n, 3 + %0 = and i32 %bf.value, 120 + %f.sroa.0.0.insert.ext.masked = and i32 %tmp.sroa.0.0.extract.trunc, 135 + %1 = or i32 %f.sroa.0.0.insert.ext.masked, %0 + %f.sroa.0.0.extract.trunc = zext i32 %1 to i64 + %tmp1.sroa.1.1.insert.insert = and i64 %f.coerce.fca.0.extract, 4294967040 + %tmp1.sroa.0.0.insert.insert = or i64 %f.sroa.0.0.extract.trunc, %tmp1.sroa.1.1.insert.insert + %.fca.0.insert = insertvalue [1 x i64] undef, i64 %tmp1.sroa.0.0.insert.insert, 0 + ret [1 x i64] %.fca.0.insert +} + +define void @test_whole32(i32* %existing, i32* %new) { +; CHECK: test_whole32: +; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #26, #5 + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 2214592511 ; =0x83ffffff + + %newval = load volatile i32* %new + %newval_shifted = shl i32 %newval, 26 + %newval_masked = and i32 %newval_shifted, 2080374784 ; = 0x7c000000 + + %combined = or i32 %oldval_keep, %newval_masked + store volatile i32 %combined, i32* %existing + + ret void +} + +define void @test_whole64(i64* %existing, i64* %new) { +; CHECK: test_whole64: +; CHECK: bfi {{x[0-9]+}}, {{x[0-9]+}}, #26, #14 +; CHECK-NOT: and +; CHECK: ret + + %oldval = load volatile i64* %existing + %oldval_keep = and i64 %oldval, 18446742974265032703 ; = 0xffffff0003ffffffL + + %newval = load volatile i64* %new + %newval_shifted = shl i64 %newval, 26 + %newval_masked = and i64 %newval_shifted, 1099444518912 ; = 0xfffc000000 + + %combined = or i64 %oldval_keep, %newval_masked + store volatile i64 %combined, i64* %existing + + ret void +} + +define void @test_whole32_from64(i64* %existing, i64* %new) { +; CHECK: test_whole32_from64: +; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #{{0|16}}, #16 +; CHECK-NOT: and +; CHECK: ret + + %oldval = load volatile i64* %existing + %oldval_keep = and i64 %oldval, 4294901760 ; = 0xffff0000 + + %newval = load volatile i64* %new + %newval_masked = and i64 %newval, 65535 ; = 0xffff + + %combined = or i64 %oldval_keep, %newval_masked + store volatile i64 %combined, i64* %existing + + ret void +} + +define void @test_32bit_masked(i32 *%existing, i32 *%new) { +; CHECK: test_32bit_masked: +; CHECK: bfi [[INSERT:w[0-9]+]], {{w[0-9]+}}, #3, #4 +; CHECK: and {{w[0-9]+}}, [[INSERT]], #0xff + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 135 ; = 0x87 + + %newval = load volatile i32* %new + %newval_shifted = shl i32 %newval, 3 + %newval_masked = and i32 %newval_shifted, 120 ; = 0x78 + + %combined = or i32 %oldval_keep, %newval_masked + store volatile i32 %combined, i32* %existing + + ret void +} + +define void @test_64bit_masked(i64 *%existing, i64 *%new) { +; CHECK: test_64bit_masked: +; CHECK: bfi [[INSERT:x[0-9]+]], {{x[0-9]+}}, #40, #8 +; CHECK: and {{x[0-9]+}}, [[INSERT]], #0xffff00000000 + + %oldval = load volatile i64* %existing + %oldval_keep = and i64 %oldval, 1095216660480 ; = 0xff_0000_0000 + + %newval = load volatile i64* %new + %newval_shifted = shl i64 %newval, 40 + %newval_masked = and i64 %newval_shifted, 280375465082880 ; = 0xff00_0000_0000 + + %combined = or i64 %newval_masked, %oldval_keep + store volatile i64 %combined, i64* %existing + + ret void +} + +; Mask is too complicated for literal ANDwwi, make sure other avenues are tried. +define void @test_32bit_complexmask(i32 *%existing, i32 *%new) { +; CHECK: test_32bit_complexmask: +; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 647 ; = 0x287 + + %newval = load volatile i32* %new + %newval_shifted = shl i32 %newval, 3 + %newval_masked = and i32 %newval_shifted, 120 ; = 0x278 + + %combined = or i32 %oldval_keep, %newval_masked + store volatile i32 %combined, i32* %existing + + ret void +} + +; Neither mask is is a contiguous set of 1s. BFI can't be used +define void @test_32bit_badmask(i32 *%existing, i32 *%new) { +; CHECK: test_32bit_badmask: +; CHECK-NOT: bfi +; CHECK: ret + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 135 ; = 0x87 + + %newval = load volatile i32* %new + %newval_shifted = shl i32 %newval, 3 + %newval_masked = and i32 %newval_shifted, 632 ; = 0x278 + + %combined = or i32 %oldval_keep, %newval_masked + store volatile i32 %combined, i32* %existing + + ret void +} + +; Ditto +define void @test_64bit_badmask(i64 *%existing, i64 *%new) { +; CHECK: test_64bit_badmask: +; CHECK-NOT: bfi +; CHECK: ret + + %oldval = load volatile i64* %existing + %oldval_keep = and i64 %oldval, 135 ; = 0x87 + + %newval = load volatile i64* %new + %newval_shifted = shl i64 %newval, 3 + %newval_masked = and i64 %newval_shifted, 664 ; = 0x278 + + %combined = or i64 %oldval_keep, %newval_masked + store volatile i64 %combined, i64* %existing + + ret void +} + +; Bitfield insert where there's a left-over shr needed at the beginning +; (e.g. result of str.bf1 = str.bf2) +define void @test_32bit_with_shr(i32* %existing, i32* %new) { +; CHECK: test_32bit_with_shr: + + %oldval = load volatile i32* %existing + %oldval_keep = and i32 %oldval, 2214592511 ; =0x83ffffff + + %newval = load i32* %new + %newval_shifted = shl i32 %newval, 12 + %newval_masked = and i32 %newval_shifted, 2080374784 ; = 0x7c000000 + + %combined = or i32 %oldval_keep, %newval_masked + store volatile i32 %combined, i32* %existing +; CHECK: lsr [[BIT:w[0-9]+]], {{w[0-9]+}}, #14 +; CHECK: bfi {{w[0-9]}}, [[BIT]], #26, #5 + + ret void +} + diff --git a/test/CodeGen/AArch64/bitfield.ll b/test/CodeGen/AArch64/bitfield.ll new file mode 100644 index 0000000000..36d337ef05 --- /dev/null +++ b/test/CodeGen/AArch64/bitfield.ll @@ -0,0 +1,218 @@ + +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_extendb(i8 %var) { +; CHECK: test_extendb: + + %sxt32 = sext i8 %var to i32 + store volatile i32 %sxt32, i32* @var32 +; CHECK: sxtb {{w[0-9]+}}, {{w[0-9]+}} + + %sxt64 = sext i8 %var to i64 + store volatile i64 %sxt64, i64* @var64 +; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}} + +; N.b. this doesn't actually produce a bitfield instruction at the +; moment, but it's still a good test to have and the semantics are +; correct. + %uxt32 = zext i8 %var to i32 + store volatile i32 %uxt32, i32* @var32 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xff + + %uxt64 = zext i8 %var to i64 + store volatile i64 %uxt64, i64* @var64 +; CHECK: uxtb {{x[0-9]+}}, {{w[0-9]+}} + ret void +} + +define void @test_extendh(i16 %var) { +; CHECK: test_extendh: + + %sxt32 = sext i16 %var to i32 + store volatile i32 %sxt32, i32* @var32 +; CHECK: sxth {{w[0-9]+}}, {{w[0-9]+}} + + %sxt64 = sext i16 %var to i64 + store volatile i64 %sxt64, i64* @var64 +; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}} + +; N.b. this doesn't actually produce a bitfield instruction at the +; moment, but it's still a good test to have and the semantics are +; correct. + %uxt32 = zext i16 %var to i32 + store volatile i32 %uxt32, i32* @var32 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xffff + + %uxt64 = zext i16 %var to i64 + store volatile i64 %uxt64, i64* @var64 +; CHECK: uxth {{x[0-9]+}}, {{w[0-9]+}} + ret void +} + +define void @test_extendw(i32 %var) { +; CHECK: test_extendw: + + %sxt64 = sext i32 %var to i64 + store volatile i64 %sxt64, i64* @var64 +; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}} + + %uxt64 = zext i32 %var to i64 + store volatile i64 %uxt64, i64* @var64 +; CHECK: ubfx {{w[0-9]+}}, {{w[0-9]+}}, #0, #32 + ret void +} + +define void @test_shifts(i32 %val32, i64 %val64) { +; CHECK: test_shifts: + + %shift1 = ashr i32 %val32, 31 + store volatile i32 %shift1, i32* @var32 +; CHECK: asr {{w[0-9]+}}, {{w[0-9]+}}, #31 + + %shift2 = lshr i32 %val32, 8 + store volatile i32 %shift2, i32* @var32 +; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #8 + + %shift3 = shl i32 %val32, 1 + store volatile i32 %shift3, i32* @var32 +; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #1 + + %shift4 = ashr i64 %val64, 31 + store volatile i64 %shift4, i64* @var64 +; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #31 + + %shift5 = lshr i64 %val64, 8 + store volatile i64 %shift5, i64* @var64 +; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #8 + + %shift6 = shl i64 %val64, 63 + store volatile i64 %shift6, i64* @var64 +; CHECK: lsl {{x[0-9]+}}, {{x[0-9]+}}, #63 + + %shift7 = ashr i64 %val64, 63 + store volatile i64 %shift7, i64* @var64 +; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #63 + + %shift8 = lshr i64 %val64, 63 + store volatile i64 %shift8, i64* @var64 +; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #63 + + %shift9 = lshr i32 %val32, 31 + store volatile i32 %shift9, i32* @var32 +; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #31 + + %shift10 = shl i32 %val32, 31 + store volatile i32 %shift10, i32* @var32 +; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #31 + + ret void +} + +; LLVM can produce in-register extensions taking place entirely with +; 64-bit registers too. +define void @test_sext_inreg_64(i64 %in) { +; CHECK: test_sext_inreg_64: + +; i1 doesn't have an official alias, but crops up and is handled by +; the bitfield ops. + %trunc_i1 = trunc i64 %in to i1 + %sext_i1 = sext i1 %trunc_i1 to i64 + store volatile i64 %sext_i1, i64* @var64 +; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #1 + + %trunc_i8 = trunc i64 %in to i8 + %sext_i8 = sext i8 %trunc_i8 to i64 + store volatile i64 %sext_i8, i64* @var64 +; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}} + + %trunc_i16 = trunc i64 %in to i16 + %sext_i16 = sext i16 %trunc_i16 to i64 + store volatile i64 %sext_i16, i64* @var64 +; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}} + + %trunc_i32 = trunc i64 %in to i32 + %sext_i32 = sext i32 %trunc_i32 to i64 + store volatile i64 %sext_i32, i64* @var64 +; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}} + ret void +} + +; These instructions don't actually select to official bitfield +; operations, but it's important that we select them somehow: +define void @test_zext_inreg_64(i64 %in) { +; CHECK: test_zext_inreg_64: + + %trunc_i8 = trunc i64 %in to i8 + %zext_i8 = zext i8 %trunc_i8 to i64 + store volatile i64 %zext_i8, i64* @var64 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xff + + %trunc_i16 = trunc i64 %in to i16 + %zext_i16 = zext i16 %trunc_i16 to i64 + store volatile i64 %zext_i16, i64* @var64 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffff + + %trunc_i32 = trunc i64 %in to i32 + %zext_i32 = zext i32 %trunc_i32 to i64 + store volatile i64 %zext_i32, i64* @var64 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffffffff + + ret void +} + +define i64 @test_sext_inreg_from_32(i32 %in) { +; CHECK: test_sext_inreg_from_32: + + %small = trunc i32 %in to i1 + %ext = sext i1 %small to i64 + + ; Different registers are of course, possible, though suboptimal. This is + ; making sure that a 64-bit "(sext_inreg (anyext GPR32), i1)" uses the 64-bit + ; sbfx rather than just 32-bits. +; CHECK: sbfx x0, x0, #0, #1 + ret i64 %ext +} + + +define i32 @test_ubfx32(i32* %addr) { +; CHECK: test_ubfx32: +; CHECK: ubfx {{w[0-9]+}}, {{w[0-9]+}}, #23, #3 + + %fields = load i32* %addr + %shifted = lshr i32 %fields, 23 + %masked = and i32 %shifted, 7 + ret i32 %masked +} + +define i64 @test_ubfx64(i64* %addr) { +; CHECK: test_ubfx64: +; CHECK: ubfx {{x[0-9]+}}, {{x[0-9]+}}, #25, #10 + + %fields = load i64* %addr + %shifted = lshr i64 %fields, 25 + %masked = and i64 %shifted, 1023 + ret i64 %masked +} + +define i32 @test_sbfx32(i32* %addr) { +; CHECK: test_sbfx32: +; CHECK: sbfx {{w[0-9]+}}, {{w[0-9]+}}, #6, #3 + + %fields = load i32* %addr + %shifted = shl i32 %fields, 23 + %extended = ashr i32 %shifted, 29 + ret i32 %extended +} + +define i64 @test_sbfx64(i64* %addr) { +; CHECK: test_sbfx64: +; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #63 + + %fields = load i64* %addr + %shifted = shl i64 %fields, 1 + %extended = ashr i64 %shifted, 1 + ret i64 %extended +} diff --git a/test/CodeGen/AArch64/blockaddress.ll b/test/CodeGen/AArch64/blockaddress.ll new file mode 100644 index 0000000000..3d0a5cf96b --- /dev/null +++ b/test/CodeGen/AArch64/blockaddress.ll @@ -0,0 +1,18 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +@addr = global i8* null + +define void @test_blockaddress() { +; CHECK: test_blockaddress: + store volatile i8* blockaddress(@test_blockaddress, %block), i8** @addr + %val = load volatile i8** @addr + indirectbr i8* %val, [label %block] +; CHECK: adrp [[DEST_HI:x[0-9]+]], [[DEST_LBL:.Ltmp[0-9]+]] +; CHECK: add [[DEST:x[0-9]+]], [[DEST_HI]], #:lo12:[[DEST_LBL]] +; CHECK: str [[DEST]], +; CHECK: ldr [[NEWDEST:x[0-9]+]] +; CHECK: br [[NEWDEST]] + +block: + ret void +} diff --git a/test/CodeGen/AArch64/bool-loads.ll b/test/CodeGen/AArch64/bool-loads.ll new file mode 100644 index 0000000000..5c7640bc42 --- /dev/null +++ b/test/CodeGen/AArch64/bool-loads.ll @@ -0,0 +1,55 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +@var = global i1 0 + +define i32 @test_sextloadi32() { +; CHECK: test_sextloadi32 + + %val = load i1* @var + %ret = sext i1 %val to i32 +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var] +; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #1 + + ret i32 %ret +; CHECK: ret +} + +define i64 @test_sextloadi64() { +; CHECK: test_sextloadi64 + + %val = load i1* @var + %ret = sext i1 %val to i64 +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var] +; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #1 + + ret i64 %ret +; CHECK: ret +} + +define i32 @test_zextloadi32() { +; CHECK: test_zextloadi32 + +; It's not actually necessary that "ret" is next, but as far as LLVM +; is concerned only 0 or 1 should be loadable so no extension is +; necessary. + %val = load i1* @var + %ret = zext i1 %val to i32 +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var] + + ret i32 %ret +; CHECK-NEXT: ret +} + +define i64 @test_zextloadi64() { +; CHECK: test_zextloadi64 + +; It's not actually necessary that "ret" is next, but as far as LLVM +; is concerned only 0 or 1 should be loadable so no extension is +; necessary. + %val = load i1* @var + %ret = zext i1 %val to i64 +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var] + + ret i64 %ret +; CHECK-NEXT: ret +} diff --git a/test/CodeGen/AArch64/breg.ll b/test/CodeGen/AArch64/breg.ll new file mode 100644 index 0000000000..38ed4734e1 --- /dev/null +++ b/test/CodeGen/AArch64/breg.ll @@ -0,0 +1,17 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@stored_label = global i8* null + +define void @foo() { +; CHECK: foo: + %lab = load i8** @stored_label + indirectbr i8* %lab, [label %otherlab, label %retlab] +; CHECK: adrp {{x[0-9]+}}, stored_label +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:stored_label] +; CHECK: br {{x[0-9]+}} + +otherlab: + ret void +retlab: + ret void +} diff --git a/test/CodeGen/AArch64/callee-save.ll b/test/CodeGen/AArch64/callee-save.ll new file mode 100644 index 0000000000..c66aa5bfc5 --- /dev/null +++ b/test/CodeGen/AArch64/callee-save.ll @@ -0,0 +1,86 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var = global float 0.0 + +define void @foo() { +; CHECK: foo: + +; CHECK: stp d14, d15, [sp +; CHECK: stp d12, d13, [sp +; CHECK: stp d10, d11, [sp +; CHECK: stp d8, d9, [sp + + ; Create lots of live variables to exhaust the supply of + ; caller-saved registers + %val1 = load volatile float* @var + %val2 = load volatile float* @var + %val3 = load volatile float* @var + %val4 = load volatile float* @var + %val5 = load volatile float* @var + %val6 = load volatile float* @var + %val7 = load volatile float* @var + %val8 = load volatile float* @var + %val9 = load volatile float* @var + %val10 = load volatile float* @var + %val11 = load volatile float* @var + %val12 = load volatile float* @var + %val13 = load volatile float* @var + %val14 = load volatile float* @var + %val15 = load volatile float* @var + %val16 = load volatile float* @var + %val17 = load volatile float* @var + %val18 = load volatile float* @var + %val19 = load volatile float* @var + %val20 = load volatile float* @var + %val21 = load volatile float* @var + %val22 = load volatile float* @var + %val23 = load volatile float* @var + %val24 = load volatile float* @var + %val25 = load volatile float* @var + %val26 = load volatile float* @var + %val27 = load volatile float* @var + %val28 = load volatile float* @var + %val29 = load volatile float* @var + %val30 = load volatile float* @var + %val31 = load volatile float* @var + %val32 = load volatile float* @var + + store volatile float %val1, float* @var + store volatile float %val2, float* @var + store volatile float %val3, float* @var + store volatile float %val4, float* @var + store volatile float %val5, float* @var + store volatile float %val6, float* @var + store volatile float %val7, float* @var + store volatile float %val8, float* @var + store volatile float %val9, float* @var + store volatile float %val10, float* @var + store volatile float %val11, float* @var + store volatile float %val12, float* @var + store volatile float %val13, float* @var + store volatile float %val14, float* @var + store volatile float %val15, float* @var + store volatile float %val16, float* @var + store volatile float %val17, float* @var + store volatile float %val18, float* @var + store volatile float %val19, float* @var + store volatile float %val20, float* @var + store volatile float %val21, float* @var + store volatile float %val22, float* @var + store volatile float %val23, float* @var + store volatile float %val24, float* @var + store volatile float %val25, float* @var + store volatile float %val26, float* @var + store volatile float %val27, float* @var + store volatile float %val28, float* @var + store volatile float %val29, float* @var + store volatile float %val30, float* @var + store volatile float %val31, float* @var + store volatile float %val32, float* @var + +; CHECK: ldp d8, d9, [sp +; CHECK: ldp d10, d11, [sp +; CHECK: ldp d12, d13, [sp +; CHECK: ldp d14, d15, [sp + ret void +} diff --git a/test/CodeGen/AArch64/compare-branch.ll b/test/CodeGen/AArch64/compare-branch.ll new file mode 100644 index 0000000000..4213110497 --- /dev/null +++ b/test/CodeGen/AArch64/compare-branch.ll @@ -0,0 +1,38 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @foo() { +; CHECK: foo: + + %val1 = load volatile i32* @var32 + %tst1 = icmp eq i32 %val1, 0 + br i1 %tst1, label %end, label %test2 +; CHECK: cbz {{w[0-9]+}}, .LBB + +test2: + %val2 = load volatile i32* @var32 + %tst2 = icmp ne i32 %val2, 0 + br i1 %tst2, label %end, label %test3 +; CHECK: cbnz {{w[0-9]+}}, .LBB + +test3: + %val3 = load volatile i64* @var64 + %tst3 = icmp eq i64 %val3, 0 + br i1 %tst3, label %end, label %test4 +; CHECK: cbz {{x[0-9]+}}, .LBB + +test4: + %val4 = load volatile i64* @var64 + %tst4 = icmp ne i64 %val4, 0 + br i1 %tst4, label %end, label %test5 +; CHECK: cbnz {{x[0-9]+}}, .LBB + +test5: + store volatile i64 %val4, i64* @var64 + ret void + +end: + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/cond-sel.ll b/test/CodeGen/AArch64/cond-sel.ll new file mode 100644 index 0000000000..3051cf53fd --- /dev/null +++ b/test/CodeGen/AArch64/cond-sel.ll @@ -0,0 +1,213 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_csel(i32 %lhs32, i32 %rhs32, i64 %lhs64) { +; CHECK: test_csel: + + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %val1 = select i1 %tst1, i32 42, i32 52 + store i32 %val1, i32* @var32 +; CHECK: movz [[W52:w[0-9]+]], #52 +; CHECK: movz [[W42:w[0-9]+]], #42 +; CHECK: csel {{w[0-9]+}}, [[W42]], [[W52]], hi + + %rhs64 = sext i32 %rhs32 to i64 + %tst2 = icmp sle i64 %lhs64, %rhs64 + %val2 = select i1 %tst2, i64 %lhs64, i64 %rhs64 + store i64 %val2, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], [[RHS:w[0-9]+]], sxtw +; CHECK: sxtw [[EXT_RHS:x[0-9]+]], [[RHS]] +; CHECK: csel {{x[0-9]+}}, [[LHS]], [[EXT_RHS]], le + + ret void +; CHECK: ret +} + +define void @test_floatcsel(float %lhs32, float %rhs32, double %lhs64, double %rhs64) { +; CHECK: test_floatcsel: + + %tst1 = fcmp one float %lhs32, %rhs32 +; CHECK: fcmp {{s[0-9]+}}, {{s[0-9]+}} + %val1 = select i1 %tst1, i32 42, i32 52 + store i32 %val1, i32* @var32 +; CHECK: movz [[W52:w[0-9]+]], #52 +; CHECK: movz [[W42:w[0-9]+]], #42 +; CHECK: csel [[MAYBETRUE:w[0-9]+]], [[W42]], [[W52]], mi +; CHECK: csel {{w[0-9]+}}, [[W42]], [[MAYBETRUE]], gt + + + %tst2 = fcmp ueq double %lhs64, %rhs64 +; CHECK: fcmp {{d[0-9]+}}, {{d[0-9]+}} + %val2 = select i1 %tst2, i64 9, i64 15 + store i64 %val2, i64* @var64 +; CHECK: movz [[CONST15:x[0-9]+]], #15 +; CHECK: movz [[CONST9:x[0-9]+]], #9 +; CHECK: csel [[MAYBETRUE:x[0-9]+]], [[CONST9]], [[CONST15]], eq +; CHECK: csel {{x[0-9]+}}, [[CONST9]], [[MAYBETRUE]], vs + + ret void +; CHECK: ret +} + + +define void @test_csinc(i32 %lhs32, i32 %rhs32, i64 %lhs64) { +; CHECK: test_csinc: + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %inc1 = add i32 %rhs32, 1 + %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32 + store volatile i32 %val1, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]] +; CHECK: csinc {{w[0-9]+}}, [[LHS]], [[RHS]], ls + + %rhs2 = add i32 %rhs32, 42 + %tst2 = icmp sle i32 %lhs32, %rhs2 + %inc2 = add i32 %rhs32, 1 + %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2 + store volatile i32 %val2, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}} +; CHECK: csinc {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %rhs3 = sext i32 %rhs32 to i64 + %tst3 = icmp ugt i64 %lhs64, %rhs3 + %inc3 = add i64 %rhs3, 1 + %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64 + store volatile i64 %val3, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csinc {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls + + %rhs4 = zext i32 %rhs32 to i64 + %tst4 = icmp sle i64 %lhs64, %rhs4 + %inc4 = add i64 %rhs4, 1 + %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4 + store volatile i64 %val4, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csinc {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le + + ret void +; CHECK: ret +} + +define void @test_csinv(i32 %lhs32, i32 %rhs32, i64 %lhs64) { +; CHECK: test_csinv: + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %inc1 = xor i32 -1, %rhs32 + %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32 + store volatile i32 %val1, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]] +; CHECK: csinv {{w[0-9]+}}, [[LHS]], [[RHS]], ls + + %rhs2 = add i32 %rhs32, 42 + %tst2 = icmp sle i32 %lhs32, %rhs2 + %inc2 = xor i32 -1, %rhs32 + %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2 + store volatile i32 %val2, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}} +; CHECK: csinv {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %rhs3 = sext i32 %rhs32 to i64 + %tst3 = icmp ugt i64 %lhs64, %rhs3 + %inc3 = xor i64 -1, %rhs3 + %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64 + store volatile i64 %val3, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csinv {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls + + %rhs4 = zext i32 %rhs32 to i64 + %tst4 = icmp sle i64 %lhs64, %rhs4 + %inc4 = xor i64 -1, %rhs4 + %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4 + store volatile i64 %val4, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csinv {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le + + ret void +; CHECK: ret +} + +define void @test_csneg(i32 %lhs32, i32 %rhs32, i64 %lhs64) { +; CHECK: test_csneg: + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %inc1 = sub i32 0, %rhs32 + %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32 + store volatile i32 %val1, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]] +; CHECK: csneg {{w[0-9]+}}, [[LHS]], [[RHS]], ls + + %rhs2 = add i32 %rhs32, 42 + %tst2 = icmp sle i32 %lhs32, %rhs2 + %inc2 = sub i32 0, %rhs32 + %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2 + store volatile i32 %val2, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}} +; CHECK: csneg {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %rhs3 = sext i32 %rhs32 to i64 + %tst3 = icmp ugt i64 %lhs64, %rhs3 + %inc3 = sub i64 0, %rhs3 + %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64 + store volatile i64 %val3, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csneg {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls + + %rhs4 = zext i32 %rhs32 to i64 + %tst4 = icmp sle i64 %lhs64, %rhs4 + %inc4 = sub i64 0, %rhs4 + %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4 + store volatile i64 %val4, i64* @var64 +; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}} +; CHECK: csneg {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le + + ret void +; CHECK: ret +} + +define void @test_cset(i32 %lhs, i32 %rhs, i64 %lhs64) { +; CHECK: test_cset: + +; N.b. code is not optimal here (32-bit csinc would be better) but +; incoming DAG is too complex + %tst1 = icmp eq i32 %lhs, %rhs + %val1 = zext i1 %tst1 to i32 + store i32 %val1, i32* @var32 +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}} +; CHECK: csinc {{w[0-9]+}}, wzr, wzr, ne + + %rhs64 = sext i32 %rhs to i64 + %tst2 = icmp ule i64 %lhs64, %rhs64 + %val2 = zext i1 %tst2 to i64 + store i64 %val2, i64* @var64 +; CHECK: csinc {{w[0-9]+}}, wzr, wzr, hi + + ret void +; CHECK: ret +} + +define void @test_csetm(i32 %lhs, i32 %rhs, i64 %lhs64) { +; CHECK: test_csetm: + + %tst1 = icmp eq i32 %lhs, %rhs + %val1 = sext i1 %tst1 to i32 + store i32 %val1, i32* @var32 +; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}} +; CHECK: csinv {{w[0-9]+}}, wzr, wzr, ne + + %rhs64 = sext i32 %rhs to i64 + %tst2 = icmp ule i64 %lhs64, %rhs64 + %val2 = sext i1 %tst2 to i64 + store i64 %val2, i64* @var64 +; CHECK: csinv {{x[0-9]+}}, xzr, xzr, hi + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/directcond.ll b/test/CodeGen/AArch64/directcond.ll new file mode 100644 index 0000000000..f5d57593bf --- /dev/null +++ b/test/CodeGen/AArch64/directcond.ll @@ -0,0 +1,84 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i32 @test_select_i32(i1 %bit, i32 %a, i32 %b) { +; CHECK: test_select_i32: + %val = select i1 %bit, i32 %a, i32 %b +; CHECK: movz [[ONE:w[0-9]+]], #1 +; CHECK: tst w0, [[ONE]] +; CHECK-NEXT: csel w0, w1, w2, ne + + ret i32 %val +} + +define i64 @test_select_i64(i1 %bit, i64 %a, i64 %b) { +; CHECK: test_select_i64: + %val = select i1 %bit, i64 %a, i64 %b +; CHECK: movz [[ONE:w[0-9]+]], #1 +; CHECK: tst w0, [[ONE]] +; CHECK-NEXT: csel x0, x1, x2, ne + + ret i64 %val +} + +define float @test_select_float(i1 %bit, float %a, float %b) { +; CHECK: test_select_float: + %val = select i1 %bit, float %a, float %b +; CHECK: movz [[ONE:w[0-9]+]], #1 +; CHECK: tst w0, [[ONE]] +; CHECK-NEXT: fcsel s0, s0, s1, ne + + ret float %val +} + +define double @test_select_double(i1 %bit, double %a, double %b) { +; CHECK: test_select_double: + %val = select i1 %bit, double %a, double %b +; CHECK: movz [[ONE:w[0-9]+]], #1 +; CHECK: tst w0, [[ONE]] +; CHECK-NEXT: fcsel d0, d0, d1, ne + + ret double %val +} + +define i32 @test_brcond(i1 %bit) { +; CHECK: test_brcond: + br i1 %bit, label %true, label %false +; CHECK: tbz {{w[0-9]+}}, #0, .LBB + +true: + ret i32 0 +false: + ret i32 42 +} + +define i1 @test_setcc_float(float %lhs, float %rhs) { +; CHECK: test_setcc_float + %val = fcmp oeq float %lhs, %rhs +; CHECK: fcmp s0, s1 +; CHECK: csinc w0, wzr, wzr, ne + ret i1 %val +} + +define i1 @test_setcc_double(double %lhs, double %rhs) { +; CHECK: test_setcc_double + %val = fcmp oeq double %lhs, %rhs +; CHECK: fcmp d0, d1 +; CHECK: csinc w0, wzr, wzr, ne + ret i1 %val +} + +define i1 @test_setcc_i32(i32 %lhs, i32 %rhs) { +; CHECK: test_setcc_i32 + %val = icmp ugt i32 %lhs, %rhs +; CHECK: cmp w0, w1 +; CHECK: csinc w0, wzr, wzr, ls + ret i1 %val +} + +define i1 @test_setcc_i64(i64 %lhs, i64 %rhs) { +; CHECK: test_setcc_i64 + %val = icmp ne i64 %lhs, %rhs +; CHECK: cmp x0, x1 +; CHECK: csinc w0, wzr, wzr, eq + ret i1 %val +} diff --git a/test/CodeGen/AArch64/dp-3source.ll b/test/CodeGen/AArch64/dp-3source.ll new file mode 100644 index 0000000000..c40d3933b4 --- /dev/null +++ b/test/CodeGen/AArch64/dp-3source.ll @@ -0,0 +1,163 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i32 @test_madd32(i32 %val0, i32 %val1, i32 %val2) { +; CHECK: test_madd32: + %mid = mul i32 %val1, %val2 + %res = add i32 %val0, %mid +; CHECK: madd {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i32 %res +} + +define i64 @test_madd64(i64 %val0, i64 %val1, i64 %val2) { +; CHECK: test_madd64: + %mid = mul i64 %val1, %val2 + %res = add i64 %val0, %mid +; CHECK: madd {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i32 @test_msub32(i32 %val0, i32 %val1, i32 %val2) { +; CHECK: test_msub32: + %mid = mul i32 %val1, %val2 + %res = sub i32 %val0, %mid +; CHECK: msub {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i32 %res +} + +define i64 @test_msub64(i64 %val0, i64 %val1, i64 %val2) { +; CHECK: test_msub64: + %mid = mul i64 %val1, %val2 + %res = sub i64 %val0, %mid +; CHECK: msub {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_smaddl(i64 %acc, i32 %val1, i32 %val2) { +; CHECK: test_smaddl: + %ext1 = sext i32 %val1 to i64 + %ext2 = sext i32 %val2 to i64 + %prod = mul i64 %ext1, %ext2 + %res = add i64 %acc, %prod +; CHECK: smaddl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_smsubl(i64 %acc, i32 %val1, i32 %val2) { +; CHECK: test_smsubl: + %ext1 = sext i32 %val1 to i64 + %ext2 = sext i32 %val2 to i64 + %prod = mul i64 %ext1, %ext2 + %res = sub i64 %acc, %prod +; CHECK: smsubl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_umaddl(i64 %acc, i32 %val1, i32 %val2) { +; CHECK: test_umaddl: + %ext1 = zext i32 %val1 to i64 + %ext2 = zext i32 %val2 to i64 + %prod = mul i64 %ext1, %ext2 + %res = add i64 %acc, %prod +; CHECK: umaddl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_umsubl(i64 %acc, i32 %val1, i32 %val2) { +; CHECK: test_umsubl: + %ext1 = zext i32 %val1 to i64 + %ext2 = zext i32 %val2 to i64 + %prod = mul i64 %ext1, %ext2 + %res = sub i64 %acc, %prod +; CHECK: umsubl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_smulh(i64 %lhs, i64 %rhs) { +; CHECK: test_smulh: + %ext1 = sext i64 %lhs to i128 + %ext2 = sext i64 %rhs to i128 + %res = mul i128 %ext1, %ext2 + %high = lshr i128 %res, 64 + %val = trunc i128 %high to i64 +; CHECK: smulh {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %val +} + +define i64 @test_umulh(i64 %lhs, i64 %rhs) { +; CHECK: test_umulh: + %ext1 = zext i64 %lhs to i128 + %ext2 = zext i64 %rhs to i128 + %res = mul i128 %ext1, %ext2 + %high = lshr i128 %res, 64 + %val = trunc i128 %high to i64 +; CHECK: umulh {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %val +} + +define i32 @test_mul32(i32 %lhs, i32 %rhs) { +; CHECK: test_mul32: + %res = mul i32 %lhs, %rhs +; CHECK: mul {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i32 %res +} + +define i64 @test_mul64(i64 %lhs, i64 %rhs) { +; CHECK: test_mul64: + %res = mul i64 %lhs, %rhs +; CHECK: mul {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i32 @test_mneg32(i32 %lhs, i32 %rhs) { +; CHECK: test_mneg32: + %prod = mul i32 %lhs, %rhs + %res = sub i32 0, %prod +; CHECK: mneg {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i32 %res +} + +define i64 @test_mneg64(i64 %lhs, i64 %rhs) { +; CHECK: test_mneg64: + %prod = mul i64 %lhs, %rhs + %res = sub i64 0, %prod +; CHECK: mneg {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + ret i64 %res +} + +define i64 @test_smull(i32 %lhs, i32 %rhs) { +; CHECK: test_smull: + %ext1 = sext i32 %lhs to i64 + %ext2 = sext i32 %rhs to i64 + %res = mul i64 %ext1, %ext2 +; CHECK: smull {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i64 %res +} + +define i64 @test_umull(i32 %lhs, i32 %rhs) { +; CHECK: test_umull: + %ext1 = zext i32 %lhs to i64 + %ext2 = zext i32 %rhs to i64 + %res = mul i64 %ext1, %ext2 +; CHECK: umull {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i64 %res +} + +define i64 @test_smnegl(i32 %lhs, i32 %rhs) { +; CHECK: test_smnegl: + %ext1 = sext i32 %lhs to i64 + %ext2 = sext i32 %rhs to i64 + %prod = mul i64 %ext1, %ext2 + %res = sub i64 0, %prod +; CHECK: smnegl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i64 %res +} + +define i64 @test_umnegl(i32 %lhs, i32 %rhs) { +; CHECK: test_umnegl: + %ext1 = zext i32 %lhs to i64 + %ext2 = zext i32 %rhs to i64 + %prod = mul i64 %ext1, %ext2 + %res = sub i64 0, %prod +; CHECK: umnegl {{x[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + ret i64 %res +} diff --git a/test/CodeGen/AArch64/dp1.ll b/test/CodeGen/AArch64/dp1.ll new file mode 100644 index 0000000000..83aa8b4f66 --- /dev/null +++ b/test/CodeGen/AArch64/dp1.ll @@ -0,0 +1,152 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @rev_i32() { +; CHECK: rev_i32: + %val0_tmp = load i32* @var32 + %val1_tmp = call i32 @llvm.bswap.i32(i32 %val0_tmp) +; CHECK: rev {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val1_tmp, i32* @var32 + ret void +} + +define void @rev_i64() { +; CHECK: rev_i64: + %val0_tmp = load i64* @var64 + %val1_tmp = call i64 @llvm.bswap.i64(i64 %val0_tmp) +; CHECK: rev {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val1_tmp, i64* @var64 + ret void +} + +define void @rev32_i64() { +; CHECK: rev32_i64: + %val0_tmp = load i64* @var64 + %val1_tmp = shl i64 %val0_tmp, 32 + %val5_tmp = sub i64 64, 32 + %val2_tmp = lshr i64 %val0_tmp, %val5_tmp + %val3_tmp = or i64 %val1_tmp, %val2_tmp + %val4_tmp = call i64 @llvm.bswap.i64(i64 %val3_tmp) +; CHECK: rev32 {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + +define void @rev16_i32() { +; CHECK: rev16_i32: + %val0_tmp = load i32* @var32 + %val1_tmp = shl i32 %val0_tmp, 16 + %val2_tmp = lshr i32 %val0_tmp, 16 + %val3_tmp = or i32 %val1_tmp, %val2_tmp + %val4_tmp = call i32 @llvm.bswap.i32(i32 %val3_tmp) +; CHECK: rev16 {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @clz_zerodef_i32() { +; CHECK: clz_zerodef_i32: + %val0_tmp = load i32* @var32 + %val4_tmp = call i32 @llvm.ctlz.i32(i32 %val0_tmp, i1 0) +; CHECK: clz {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @clz_zerodef_i64() { +; CHECK: clz_zerodef_i64: + %val0_tmp = load i64* @var64 + %val4_tmp = call i64 @llvm.ctlz.i64(i64 %val0_tmp, i1 0) +; CHECK: clz {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + +define void @clz_zeroundef_i32() { +; CHECK: clz_zeroundef_i32: + %val0_tmp = load i32* @var32 + %val4_tmp = call i32 @llvm.ctlz.i32(i32 %val0_tmp, i1 1) +; CHECK: clz {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @clz_zeroundef_i64() { +; CHECK: clz_zeroundef_i64: + %val0_tmp = load i64* @var64 + %val4_tmp = call i64 @llvm.ctlz.i64(i64 %val0_tmp, i1 1) +; CHECK: clz {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + +define void @cttz_zerodef_i32() { +; CHECK: cttz_zerodef_i32: + %val0_tmp = load i32* @var32 + %val4_tmp = call i32 @llvm.cttz.i32(i32 %val0_tmp, i1 0) +; CHECK: rbit [[REVERSED:w[0-9]+]], {{w[0-9]+}} +; CHECK: clz {{w[0-9]+}}, [[REVERSED]] + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @cttz_zerodef_i64() { +; CHECK: cttz_zerodef_i64: + %val0_tmp = load i64* @var64 + %val4_tmp = call i64 @llvm.cttz.i64(i64 %val0_tmp, i1 0) +; CHECK: rbit [[REVERSED:x[0-9]+]], {{x[0-9]+}} +; CHECK: clz {{x[0-9]+}}, [[REVERSED]] + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + +define void @cttz_zeroundef_i32() { +; CHECK: cttz_zeroundef_i32: + %val0_tmp = load i32* @var32 + %val4_tmp = call i32 @llvm.cttz.i32(i32 %val0_tmp, i1 1) +; CHECK: rbit [[REVERSED:w[0-9]+]], {{w[0-9]+}} +; CHECK: clz {{w[0-9]+}}, [[REVERSED]] + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @cttz_zeroundef_i64() { +; CHECK: cttz_zeroundef_i64: + %val0_tmp = load i64* @var64 + %val4_tmp = call i64 @llvm.cttz.i64(i64 %val0_tmp, i1 1) +; CHECK: rbit [[REVERSED:x[0-9]+]], {{x[0-9]+}} +; CHECK: clz {{x[0-9]+}}, [[REVERSED]] + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + +; These two are just compilation tests really: the operation's set to Expand in +; ISelLowering. +define void @ctpop_i32() { +; CHECK: ctpop_i32: + %val0_tmp = load i32* @var32 + %val4_tmp = call i32 @llvm.ctpop.i32(i32 %val0_tmp) + store volatile i32 %val4_tmp, i32* @var32 + ret void +} + +define void @ctpop_i64() { +; CHECK: ctpop_i64: + %val0_tmp = load i64* @var64 + %val4_tmp = call i64 @llvm.ctpop.i64(i64 %val0_tmp) + store volatile i64 %val4_tmp, i64* @var64 + ret void +} + + +declare i32 @llvm.bswap.i32(i32) +declare i64 @llvm.bswap.i64(i64) +declare i32 @llvm.ctlz.i32 (i32, i1) +declare i64 @llvm.ctlz.i64 (i64, i1) +declare i32 @llvm.cttz.i32 (i32, i1) +declare i64 @llvm.cttz.i64 (i64, i1) +declare i32 @llvm.ctpop.i32 (i32) +declare i64 @llvm.ctpop.i64 (i64) + diff --git a/test/CodeGen/AArch64/dp2.ll b/test/CodeGen/AArch64/dp2.ll new file mode 100644 index 0000000000..4c740f6b86 --- /dev/null +++ b/test/CodeGen/AArch64/dp2.ll @@ -0,0 +1,169 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32_0 = global i32 0 +@var32_1 = global i32 0 +@var64_0 = global i64 0 +@var64_1 = global i64 0 + +define void @rorv_i64() { +; CHECK: rorv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val2_tmp = sub i64 64, %val1_tmp + %val3_tmp = shl i64 %val0_tmp, %val2_tmp + %val4_tmp = lshr i64 %val0_tmp, %val1_tmp + %val5_tmp = or i64 %val3_tmp, %val4_tmp +; CHECK: ror {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val5_tmp, i64* @var64_0 + ret void +} + +define void @asrv_i64() { +; CHECK: asrv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val4_tmp = ashr i64 %val0_tmp, %val1_tmp +; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64_1 + ret void +} + +define void @lsrv_i64() { +; CHECK: lsrv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val4_tmp = lshr i64 %val0_tmp, %val1_tmp +; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64_0 + ret void +} + +define void @lslv_i64() { +; CHECK: lslv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val4_tmp = shl i64 %val0_tmp, %val1_tmp +; CHECK: lsl {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64_1 + ret void +} + +define void @udiv_i64() { +; CHECK: udiv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val4_tmp = udiv i64 %val0_tmp, %val1_tmp +; CHECK: udiv {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64_0 + ret void +} + +define void @sdiv_i64() { +; CHECK: sdiv_i64: + %val0_tmp = load i64* @var64_0 + %val1_tmp = load i64* @var64_1 + %val4_tmp = sdiv i64 %val0_tmp, %val1_tmp +; CHECK: sdiv {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %val4_tmp, i64* @var64_1 + ret void +} + + +define void @lsrv_i32() { +; CHECK: lsrv_i32: + %val0_tmp = load i32* @var32_0 + %val1_tmp = load i32* @var32_1 + %val2_tmp = add i32 1, %val1_tmp + %val4_tmp = lshr i32 %val0_tmp, %val2_tmp +; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32_0 + ret void +} + +define void @lslv_i32() { +; CHECK: lslv_i32: + %val0_tmp = load i32* @var32_0 + %val1_tmp = load i32* @var32_1 + %val2_tmp = add i32 1, %val1_tmp + %val4_tmp = shl i32 %val0_tmp, %val2_tmp +; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32_1 + ret void +} + +define void @rorv_i32() { +; CHECK: rorv_i32: + %val0_tmp = load i32* @var32_0 + %val6_tmp = load i32* @var32_1 + %val1_tmp = add i32 1, %val6_tmp + %val2_tmp = sub i32 32, %val1_tmp + %val3_tmp = shl i32 %val0_tmp, %val2_tmp + %val4_tmp = lshr i32 %val0_tmp, %val1_tmp + %val5_tmp = or i32 %val3_tmp, %val4_tmp +; CHECK: ror {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val5_tmp, i32* @var32_0 + ret void +} + +define void @asrv_i32() { +; CHECK: asrv_i32: + %val0_tmp = load i32* @var32_0 + %val1_tmp = load i32* @var32_1 + %val2_tmp = add i32 1, %val1_tmp + %val4_tmp = ashr i32 %val0_tmp, %val2_tmp +; CHECK: asr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32_1 + ret void +} + +define void @sdiv_i32() { +; CHECK: sdiv_i32: + %val0_tmp = load i32* @var32_0 + %val1_tmp = load i32* @var32_1 + %val4_tmp = sdiv i32 %val0_tmp, %val1_tmp +; CHECK: sdiv {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32_1 + ret void +} + +define void @udiv_i32() { +; CHECK: udiv_i32: + %val0_tmp = load i32* @var32_0 + %val1_tmp = load i32* @var32_1 + %val4_tmp = udiv i32 %val0_tmp, %val1_tmp +; CHECK: udiv {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %val4_tmp, i32* @var32_0 + ret void +} + +; The point of this test is that we may not actually see (shl GPR32:$Val, (zext GPR32:$Val2)) +; in the DAG (the RHS may be natively 64-bit), but we should still use the lsl instructions. +define i32 @test_lsl32() { +; CHECK: test_lsl32: + + %val = load i32* @var32_0 + %ret = shl i32 1, %val +; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + + ret i32 %ret +} + +define i32 @test_lsr32() { +; CHECK: test_lsr32: + + %val = load i32* @var32_0 + %ret = lshr i32 1, %val +; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + + ret i32 %ret +} + +define i32 @test_asr32(i32 %in) { +; CHECK: test_asr32: + + %val = load i32* @var32_0 + %ret = ashr i32 %in, %val +; CHECK: asr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + + ret i32 %ret +} diff --git a/test/CodeGen/AArch64/elf-extern.ll b/test/CodeGen/AArch64/elf-extern.ll new file mode 100644 index 0000000000..ee89d8d94b --- /dev/null +++ b/test/CodeGen/AArch64/elf-extern.ll @@ -0,0 +1,21 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -filetype=obj | elf-dump | FileCheck %s + +; External symbols are a different concept to global variables but should still +; get relocations and so on when used. + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) + +define i32 @check_extern() { + call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* undef, i32 undef, i32 4, i1 0) + ret i32 0 +} + +; CHECK: .rela.text +; CHECK: ('r_sym', 0x00000009) +; CHECK-NEXT: ('r_type', 0x0000011b) + +; CHECK: .symtab +; CHECK: Symbol 9 +; CHECK-NEXT: memcpy + + diff --git a/test/CodeGen/AArch64/extern-weak.ll b/test/CodeGen/AArch64/extern-weak.ll new file mode 100644 index 0000000000..3d3d867681 --- /dev/null +++ b/test/CodeGen/AArch64/extern-weak.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -o - < %s | FileCheck %s + +declare extern_weak i32 @var() + +define i32()* @foo() { +; The usual ADRP/ADD pair can't be used for a weak reference because it must +; evaluate to 0 if the symbol is undefined. We use a litpool entry. + ret i32()* @var +; CHECK: .LCPI0_0: +; CHECK-NEXT: .xword var + +; CHECK: ldr x0, [{{x[0-9]+}}, #:lo12:.LCPI0_0] + +} + + +@arr_var = extern_weak global [10 x i32] + +define i32* @bar() { + %addr = getelementptr [10 x i32]* @arr_var, i32 0, i32 5 +; CHECK: .LCPI1_0: +; CHECK-NEXT: .xword arr_var + +; CHECK: ldr [[BASE:x[0-9]+]], [{{x[0-9]+}}, #:lo12:.LCPI1_0] +; CHECK: add x0, [[BASE]], #20 + ret i32* %addr +} + +@defined_weak_var = internal unnamed_addr global i32 0 + +define i32* @wibble() { + ret i32* @defined_weak_var +; CHECK: adrp [[BASE:x[0-9]+]], defined_weak_var +; CHECK: add x0, [[BASE]], #:lo12:defined_weak_var +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/extract.ll b/test/CodeGen/AArch64/extract.ll new file mode 100644 index 0000000000..06267816a4 --- /dev/null +++ b/test/CodeGen/AArch64/extract.ll @@ -0,0 +1,57 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i64 @ror_i64(i64 %in) { +; CHECK: ror_i64: + %left = shl i64 %in, 19 + %right = lshr i64 %in, 45 + %val5 = or i64 %left, %right +; CHECK: extr {{x[0-9]+}}, x0, x0, #45 + ret i64 %val5 +} + +define i32 @ror_i32(i32 %in) { +; CHECK: ror_i32: + %left = shl i32 %in, 9 + %right = lshr i32 %in, 23 + %val5 = or i32 %left, %right +; CHECK: extr {{w[0-9]+}}, w0, w0, #23 + ret i32 %val5 +} + +define i32 @extr_i32(i32 %lhs, i32 %rhs) { +; CHECK: extr_i32: + %left = shl i32 %lhs, 6 + %right = lshr i32 %rhs, 26 + %val = or i32 %left, %right + ; Order of lhs and rhs matters here. Regalloc would have to be very odd to use + ; something other than w0 and w1. +; CHECK: extr {{w[0-9]+}}, w0, w1, #26 + + ret i32 %val +} + +define i64 @extr_i64(i64 %lhs, i64 %rhs) { +; CHECK: extr_i64: + %right = lshr i64 %rhs, 40 + %left = shl i64 %lhs, 24 + %val = or i64 %right, %left + ; Order of lhs and rhs matters here. Regalloc would have to be very odd to use + ; something other than w0 and w1. +; CHECK: extr {{x[0-9]+}}, x0, x1, #40 + + ret i64 %val +} + +; Regression test: a bad experimental pattern crept into git which optimised +; this pattern to a single EXTR. +define i32 @extr_regress(i32 %a, i32 %b) { +; CHECK: extr_regress: + + %sh1 = shl i32 %a, 14 + %sh2 = lshr i32 %b, 14 + %val = or i32 %sh2, %sh1 +; CHECK-NOT: extr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, #{{[0-9]+}} + + ret i32 %val +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/fastcc-reserved.ll b/test/CodeGen/AArch64/fastcc-reserved.ll new file mode 100644 index 0000000000..e40aa3033b --- /dev/null +++ b/test/CodeGen/AArch64/fastcc-reserved.ll @@ -0,0 +1,58 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s + +; This test is designed to be run in the situation where the +; call-frame is not reserved (hence disable-fp-elim), but where +; callee-pop can occur (hence tailcallopt). + +declare fastcc void @will_pop([8 x i32], i32 %val) + +define fastcc void @foo(i32 %in) { +; CHECK: foo: + + %addr = alloca i8, i32 %in + +; Normal frame setup stuff: +; CHECK: sub sp, sp, +; CHECK: stp x29, x30 + +; Reserve space for call-frame: +; CHECK: sub sp, sp, #16 + + call fastcc void @will_pop([8 x i32] undef, i32 42) +; CHECK: bl will_pop + +; Since @will_pop is fastcc with tailcallopt, it will put the stack +; back where it needs to be, we shouldn't duplicate that +; CHECK-NOT: sub sp, sp, #16 +; CHECK-NOT: add sp, sp, + +; CHECK: ldp x29, x30 +; CHECK: add sp, sp, + ret void +} + +declare void @wont_pop([8 x i32], i32 %val) + +define void @foo1(i32 %in) { +; CHECK: foo1: + + %addr = alloca i8, i32 %in +; Normal frame setup again +; CHECK: sub sp, sp, +; CHECK: stp x29, x30 + +; Reserve space for call-frame +; CHECK: sub sp, sp, #16 + + call void @wont_pop([8 x i32] undef, i32 42) +; CHECK: bl wont_pop + +; This time we *do* need to unreserve the call-frame +; CHECK: add sp, sp, #16 + +; Check for epilogue (primarily to make sure sp spotted above wasn't +; part of it). +; CHECK: ldp x29, x30 +; CHECK: add sp, sp, + ret void +} diff --git a/test/CodeGen/AArch64/fastcc.ll b/test/CodeGen/AArch64/fastcc.ll new file mode 100644 index 0000000000..41cde94edc --- /dev/null +++ b/test/CodeGen/AArch64/fastcc.ll @@ -0,0 +1,123 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s -check-prefix CHECK-TAIL +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +; Without tailcallopt fastcc still means the caller cleans up the +; stack, so try to make sure this is respected. + +define fastcc void @func_stack0() { +; CHECK: func_stack0: +; CHECK: sub sp, sp, #48 + +; CHECK-TAIL: func_stack0: +; CHECK-TAIL: sub sp, sp, #48 + + + call fastcc void @func_stack8([8 x i32] undef, i32 42) +; CHECK: bl func_stack8 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack8 +; CHECK-TAIL: sub sp, sp, #16 + + + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) +; CHECK: bl func_stack32 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack32 +; CHECK-TAIL: sub sp, sp, #32 + + + call fastcc void @func_stack0() +; CHECK: bl func_stack0 +; CHECK-NOT: sub sp, sp + +; CHECK-TAIL: bl func_stack0 +; CHECK-TAIL-NOT: sub sp, sp + + ret void +; CHECK: add sp, sp, #48 +; CHECK-NEXT: ret + +; CHECK-TAIL: add sp, sp, #48 +; CHECK-TAIL-NEXT: ret + +} + +define fastcc void @func_stack8([8 x i32], i32 %stacked) { +; CHECK: func_stack8: +; CHECK: sub sp, sp, #48 + +; CHECK-TAIL: func_stack8: +; CHECK-TAIL: sub sp, sp, #48 + + + call fastcc void @func_stack8([8 x i32] undef, i32 42) +; CHECK: bl func_stack8 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack8 +; CHECK-TAIL: sub sp, sp, #16 + + + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) +; CHECK: bl func_stack32 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack32 +; CHECK-TAIL: sub sp, sp, #32 + + + call fastcc void @func_stack0() +; CHECK: bl func_stack0 +; CHECK-NOT: sub sp, sp + +; CHECK-TAIL: bl func_stack0 +; CHECK-TAIL-NOT: sub sp, sp + + ret void +; CHECK: add sp, sp, #48 +; CHECK-NEXT: ret + +; CHECK-TAIL: add sp, sp, #64 +; CHECK-TAIL-NEXT: ret +} + +define fastcc void @func_stack32([8 x i32], i128 %stacked0, i128 %stacked1) { +; CHECK: func_stack32: +; CHECK: sub sp, sp, #48 + +; CHECK-TAIL: func_stack32: +; CHECK-TAIL: sub sp, sp, #48 + + + call fastcc void @func_stack8([8 x i32] undef, i32 42) +; CHECK: bl func_stack8 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack8 +; CHECK-TAIL: sub sp, sp, #16 + + + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) +; CHECK: bl func_stack32 +; CHECK-NOT: sub sp, sp, + +; CHECK-TAIL: bl func_stack32 +; CHECK-TAIL: sub sp, sp, #32 + + + call fastcc void @func_stack0() +; CHECK: bl func_stack0 +; CHECK-NOT: sub sp, sp + +; CHECK-TAIL: bl func_stack0 +; CHECK-TAIL-NOT: sub sp, sp + + ret void +; CHECK: add sp, sp, #48 +; CHECK-NEXT: ret + +; CHECK-TAIL: add sp, sp, #80 +; CHECK-TAIL-NEXT: ret +} diff --git a/test/CodeGen/AArch64/fcmp.ll b/test/CodeGen/AArch64/fcmp.ll new file mode 100644 index 0000000000..ad4a903c9b --- /dev/null +++ b/test/CodeGen/AArch64/fcmp.ll @@ -0,0 +1,81 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +declare void @bar(i32) + +define void @test_float(float %a, float %b) { +; CHECK: test_float: + + %tst1 = fcmp oeq float %a, %b + br i1 %tst1, label %end, label %t2 +; CHECK: fcmp {{s[0-9]+}}, {{s[0-9]+}} +; CHECK: b.eq .L + +t2: + %tst2 = fcmp une float %b, 0.0 + br i1 %tst2, label %t3, label %end +; CHECK: fcmp {{s[0-9]+}}, #0.0 +; CHECK: b.eq .L + + +t3: +; This test can't be implemented with just one A64 conditional +; branch. LLVM converts "ordered and not equal" to "unordered or +; equal" before instruction selection, which is what we currently +; test. Obviously, other sequences are valid. + %tst3 = fcmp one float %a, %b + br i1 %tst3, label %t4, label %end +; CHECK: fcmp {{s[0-9]+}}, {{s[0-9]+}} +; CHECK-NEXT: b.eq .[[T4:LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: b.vs .[[T4]] +t4: + %tst4 = fcmp uge float %a, -0.0 + br i1 %tst4, label %t5, label %end +; CHECK-NOT: fcmp {{s[0-9]+}}, #0.0 +; CHECK: b.mi .LBB + +t5: + call void @bar(i32 0) + ret void +end: + ret void + +} + +define void @test_double(double %a, double %b) { +; CHECK: test_double: + + %tst1 = fcmp oeq double %a, %b + br i1 %tst1, label %end, label %t2 +; CHECK: fcmp {{d[0-9]+}}, {{d[0-9]+}} +; CHECK: b.eq .L + +t2: + %tst2 = fcmp une double %b, 0.0 + br i1 %tst2, label %t3, label %end +; CHECK: fcmp {{d[0-9]+}}, #0.0 +; CHECK: b.eq .L + + +t3: +; This test can't be implemented with just one A64 conditional +; branch. LLVM converts "ordered and not equal" to "unordered or +; equal" before instruction selection, which is what we currently +; test. Obviously, other sequences are valid. + %tst3 = fcmp one double %a, %b + br i1 %tst3, label %t4, label %end +; CHECK: fcmp {{d[0-9]+}}, {{d[0-9]+}} +; CHECK-NEXT: b.eq .[[T4:LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: b.vs .[[T4]] +t4: + %tst4 = fcmp uge double %a, -0.0 + br i1 %tst4, label %t5, label %end +; CHECK-NOT: fcmp {{d[0-9]+}}, #0.0 +; CHECK: b.mi .LBB + +t5: + call void @bar(i32 0) + ret void +end: + ret void + +} diff --git a/test/CodeGen/AArch64/fcvt-fixed.ll b/test/CodeGen/AArch64/fcvt-fixed.ll new file mode 100644 index 0000000000..0f7b95b2a4 --- /dev/null +++ b/test/CodeGen/AArch64/fcvt-fixed.ll @@ -0,0 +1,191 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -O0 | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_fcvtzs(float %flt, double %dbl) { +; CHECK: test_fcvtzs: + + %fix1 = fmul float %flt, 128.0 + %cvt1 = fptosi float %fix1 to i32 +; CHECK: fcvtzs {{w[0-9]+}}, {{s[0-9]+}}, #7 + store volatile i32 %cvt1, i32* @var32 + + %fix2 = fmul float %flt, 4294967296.0 + %cvt2 = fptosi float %fix2 to i32 +; CHECK: fcvtzs {{w[0-9]+}}, {{s[0-9]+}}, #32 + store volatile i32 %cvt2, i32* @var32 + + %fix3 = fmul float %flt, 128.0 + %cvt3 = fptosi float %fix3 to i64 +; CHECK: fcvtzs {{x[0-9]+}}, {{s[0-9]+}}, #7 + store volatile i64 %cvt3, i64* @var64 + + %fix4 = fmul float %flt, 18446744073709551616.0 + %cvt4 = fptosi float %fix4 to i64 +; CHECK: fcvtzs {{x[0-9]+}}, {{s[0-9]+}}, #64 + store volatile i64 %cvt4, i64* @var64 + + %fix5 = fmul double %dbl, 128.0 + %cvt5 = fptosi double %fix5 to i32 +; CHECK: fcvtzs {{w[0-9]+}}, {{d[0-9]+}}, #7 + store volatile i32 %cvt5, i32* @var32 + + %fix6 = fmul double %dbl, 4294967296.0 + %cvt6 = fptosi double %fix6 to i32 +; CHECK: fcvtzs {{w[0-9]+}}, {{d[0-9]+}}, #32 + store volatile i32 %cvt6, i32* @var32 + + %fix7 = fmul double %dbl, 128.0 + %cvt7 = fptosi double %fix7 to i64 +; CHECK: fcvtzs {{x[0-9]+}}, {{d[0-9]+}}, #7 + store volatile i64 %cvt7, i64* @var64 + + %fix8 = fmul double %dbl, 18446744073709551616.0 + %cvt8 = fptosi double %fix8 to i64 +; CHECK: fcvtzs {{x[0-9]+}}, {{d[0-9]+}}, #64 + store volatile i64 %cvt8, i64* @var64 + + ret void +} + +define void @test_fcvtzu(float %flt, double %dbl) { +; CHECK: test_fcvtzu: + + %fix1 = fmul float %flt, 128.0 + %cvt1 = fptoui float %fix1 to i32 +; CHECK: fcvtzu {{w[0-9]+}}, {{s[0-9]+}}, #7 + store volatile i32 %cvt1, i32* @var32 + + %fix2 = fmul float %flt, 4294967296.0 + %cvt2 = fptoui float %fix2 to i32 +; CHECK: fcvtzu {{w[0-9]+}}, {{s[0-9]+}}, #32 + store volatile i32 %cvt2, i32* @var32 + + %fix3 = fmul float %flt, 128.0 + %cvt3 = fptoui float %fix3 to i64 +; CHECK: fcvtzu {{x[0-9]+}}, {{s[0-9]+}}, #7 + store volatile i64 %cvt3, i64* @var64 + + %fix4 = fmul float %flt, 18446744073709551616.0 + %cvt4 = fptoui float %fix4 to i64 +; CHECK: fcvtzu {{x[0-9]+}}, {{s[0-9]+}}, #64 + store volatile i64 %cvt4, i64* @var64 + + %fix5 = fmul double %dbl, 128.0 + %cvt5 = fptoui double %fix5 to i32 +; CHECK: fcvtzu {{w[0-9]+}}, {{d[0-9]+}}, #7 + store volatile i32 %cvt5, i32* @var32 + + %fix6 = fmul double %dbl, 4294967296.0 + %cvt6 = fptoui double %fix6 to i32 +; CHECK: fcvtzu {{w[0-9]+}}, {{d[0-9]+}}, #32 + store volatile i32 %cvt6, i32* @var32 + + %fix7 = fmul double %dbl, 128.0 + %cvt7 = fptoui double %fix7 to i64 +; CHECK: fcvtzu {{x[0-9]+}}, {{d[0-9]+}}, #7 + store volatile i64 %cvt7, i64* @var64 + + %fix8 = fmul double %dbl, 18446744073709551616.0 + %cvt8 = fptoui double %fix8 to i64 +; CHECK: fcvtzu {{x[0-9]+}}, {{d[0-9]+}}, #64 + store volatile i64 %cvt8, i64* @var64 + + ret void +} + +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +define void @test_scvtf(i32 %int, i64 %long) { +; CHECK: test_scvtf: + + %cvt1 = sitofp i32 %int to float + %fix1 = fdiv float %cvt1, 128.0 +; CHECK: scvtf {{s[0-9]+}}, {{w[0-9]+}}, #7 + store volatile float %fix1, float* @varfloat + + %cvt2 = sitofp i32 %int to float + %fix2 = fdiv float %cvt2, 4294967296.0 +; CHECK: scvtf {{s[0-9]+}}, {{w[0-9]+}}, #32 + store volatile float %fix2, float* @varfloat + + %cvt3 = sitofp i64 %long to float + %fix3 = fdiv float %cvt3, 128.0 +; CHECK: scvtf {{s[0-9]+}}, {{x[0-9]+}}, #7 + store volatile float %fix3, float* @varfloat + + %cvt4 = sitofp i64 %long to float + %fix4 = fdiv float %cvt4, 18446744073709551616.0 +; CHECK: scvtf {{s[0-9]+}}, {{x[0-9]+}}, #64 + store volatile float %fix4, float* @varfloat + + %cvt5 = sitofp i32 %int to double + %fix5 = fdiv double %cvt5, 128.0 +; CHECK: scvtf {{d[0-9]+}}, {{w[0-9]+}}, #7 + store volatile double %fix5, double* @vardouble + + %cvt6 = sitofp i32 %int to double + %fix6 = fdiv double %cvt6, 4294967296.0 +; CHECK: scvtf {{d[0-9]+}}, {{w[0-9]+}}, #32 + store volatile double %fix6, double* @vardouble + + %cvt7 = sitofp i64 %long to double + %fix7 = fdiv double %cvt7, 128.0 +; CHECK: scvtf {{d[0-9]+}}, {{x[0-9]+}}, #7 + store volatile double %fix7, double* @vardouble + + %cvt8 = sitofp i64 %long to double + %fix8 = fdiv double %cvt8, 18446744073709551616.0 +; CHECK: scvtf {{d[0-9]+}}, {{x[0-9]+}}, #64 + store volatile double %fix8, double* @vardouble + + ret void +} + +define void @test_ucvtf(i32 %int, i64 %long) { +; CHECK: test_ucvtf: + + %cvt1 = uitofp i32 %int to float + %fix1 = fdiv float %cvt1, 128.0 +; CHECK: ucvtf {{s[0-9]+}}, {{w[0-9]+}}, #7 + store volatile float %fix1, float* @varfloat + + %cvt2 = uitofp i32 %int to float + %fix2 = fdiv float %cvt2, 4294967296.0 +; CHECK: ucvtf {{s[0-9]+}}, {{w[0-9]+}}, #32 + store volatile float %fix2, float* @varfloat + + %cvt3 = uitofp i64 %long to float + %fix3 = fdiv float %cvt3, 128.0 +; CHECK: ucvtf {{s[0-9]+}}, {{x[0-9]+}}, #7 + store volatile float %fix3, float* @varfloat + + %cvt4 = uitofp i64 %long to float + %fix4 = fdiv float %cvt4, 18446744073709551616.0 +; CHECK: ucvtf {{s[0-9]+}}, {{x[0-9]+}}, #64 + store volatile float %fix4, float* @varfloat + + %cvt5 = uitofp i32 %int to double + %fix5 = fdiv double %cvt5, 128.0 +; CHECK: ucvtf {{d[0-9]+}}, {{w[0-9]+}}, #7 + store volatile double %fix5, double* @vardouble + + %cvt6 = uitofp i32 %int to double + %fix6 = fdiv double %cvt6, 4294967296.0 +; CHECK: ucvtf {{d[0-9]+}}, {{w[0-9]+}}, #32 + store volatile double %fix6, double* @vardouble + + %cvt7 = uitofp i64 %long to double + %fix7 = fdiv double %cvt7, 128.0 +; CHECK: ucvtf {{d[0-9]+}}, {{x[0-9]+}}, #7 + store volatile double %fix7, double* @vardouble + + %cvt8 = uitofp i64 %long to double + %fix8 = fdiv double %cvt8, 18446744073709551616.0 +; CHECK: ucvtf {{d[0-9]+}}, {{x[0-9]+}}, #64 + store volatile double %fix8, double* @vardouble + + ret void +} diff --git a/test/CodeGen/AArch64/fcvt-int.ll b/test/CodeGen/AArch64/fcvt-int.ll new file mode 100644 index 0000000000..c771d683a9 --- /dev/null +++ b/test/CodeGen/AArch64/fcvt-int.ll @@ -0,0 +1,151 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i32 @test_floattoi32(float %in) { +; CHECK: test_floattoi32: + + %signed = fptosi float %in to i32 + %unsigned = fptoui float %in to i32 +; CHECK: fcvtzu [[UNSIG:w[0-9]+]], {{s[0-9]+}} +; CHECK: fcvtzs [[SIG:w[0-9]+]], {{s[0-9]+}} + + %res = sub i32 %signed, %unsigned +; CHECK: sub {{w[0-9]+}}, [[SIG]], [[UNSIG]] + + ret i32 %res +; CHECK: ret +} + +define i32 @test_doubletoi32(double %in) { +; CHECK: test_doubletoi32: + + %signed = fptosi double %in to i32 + %unsigned = fptoui double %in to i32 +; CHECK: fcvtzu [[UNSIG:w[0-9]+]], {{d[0-9]+}} +; CHECK: fcvtzs [[SIG:w[0-9]+]], {{d[0-9]+}} + + %res = sub i32 %signed, %unsigned +; CHECK: sub {{w[0-9]+}}, [[SIG]], [[UNSIG]] + + ret i32 %res +; CHECK: ret +} + +define i64 @test_floattoi64(float %in) { +; CHECK: test_floattoi64: + + %signed = fptosi float %in to i64 + %unsigned = fptoui float %in to i64 +; CHECK: fcvtzu [[UNSIG:x[0-9]+]], {{s[0-9]+}} +; CHECK: fcvtzs [[SIG:x[0-9]+]], {{s[0-9]+}} + + %res = sub i64 %signed, %unsigned +; CHECK: sub {{x[0-9]+}}, [[SIG]], [[UNSIG]] + + ret i64 %res +; CHECK: ret +} + +define i64 @test_doubletoi64(double %in) { +; CHECK: test_doubletoi64: + + %signed = fptosi double %in to i64 + %unsigned = fptoui double %in to i64 +; CHECK: fcvtzu [[UNSIG:x[0-9]+]], {{d[0-9]+}} +; CHECK: fcvtzs [[SIG:x[0-9]+]], {{d[0-9]+}} + + %res = sub i64 %signed, %unsigned +; CHECK: sub {{x[0-9]+}}, [[SIG]], [[UNSIG]] + + ret i64 %res +; CHECK: ret +} + +define float @test_i32tofloat(i32 %in) { +; CHECK: test_i32tofloat: + + %signed = sitofp i32 %in to float + %unsigned = uitofp i32 %in to float +; CHECK: ucvtf [[UNSIG:s[0-9]+]], {{w[0-9]+}} +; CHECK: scvtf [[SIG:s[0-9]+]], {{w[0-9]+}} + + %res = fsub float %signed, %unsigned +; CHECL: fsub {{s[0-9]+}}, [[SIG]], [[UNSIG]] + ret float %res +; CHECK: ret +} + +define double @test_i32todouble(i32 %in) { +; CHECK: test_i32todouble: + + %signed = sitofp i32 %in to double + %unsigned = uitofp i32 %in to double +; CHECK: ucvtf [[UNSIG:d[0-9]+]], {{w[0-9]+}} +; CHECK: scvtf [[SIG:d[0-9]+]], {{w[0-9]+}} + + %res = fsub double %signed, %unsigned +; CHECK: fsub {{d[0-9]+}}, [[SIG]], [[UNSIG]] + ret double %res +; CHECK: ret +} + +define float @test_i64tofloat(i64 %in) { +; CHECK: test_i64tofloat: + + %signed = sitofp i64 %in to float + %unsigned = uitofp i64 %in to float +; CHECK: ucvtf [[UNSIG:s[0-9]+]], {{x[0-9]+}} +; CHECK: scvtf [[SIG:s[0-9]+]], {{x[0-9]+}} + + %res = fsub float %signed, %unsigned +; CHECK: fsub {{s[0-9]+}}, [[SIG]], [[UNSIG]] + ret float %res +; CHECK: ret +} + +define double @test_i64todouble(i64 %in) { +; CHECK: test_i64todouble: + + %signed = sitofp i64 %in to double + %unsigned = uitofp i64 %in to double +; CHECK: ucvtf [[UNSIG:d[0-9]+]], {{x[0-9]+}} +; CHECK: scvtf [[SIG:d[0-9]+]], {{x[0-9]+}} + + %res = fsub double %signed, %unsigned +; CHECK: sub {{d[0-9]+}}, [[SIG]], [[UNSIG]] + ret double %res +; CHECK: ret +} + +define i32 @test_bitcastfloattoi32(float %in) { +; CHECK: test_bitcastfloattoi32: + + %res = bitcast float %in to i32 +; CHECK: fmov {{w[0-9]+}}, {{s[0-9]+}} + ret i32 %res +} + +define i64 @test_bitcastdoubletoi64(double %in) { +; CHECK: test_bitcastdoubletoi64: + + %res = bitcast double %in to i64 +; CHECK: fmov {{x[0-9]+}}, {{d[0-9]+}} + ret i64 %res +} + +define float @test_bitcasti32tofloat(i32 %in) { +; CHECK: test_bitcasti32tofloat: + + %res = bitcast i32 %in to float +; CHECK: fmov {{s[0-9]+}}, {{w[0-9]+}} + ret float %res + +} + +define double @test_bitcasti64todouble(i64 %in) { +; CHECK: test_bitcasti64todouble: + + %res = bitcast i64 %in to double +; CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}} + ret double %res + +} diff --git a/test/CodeGen/AArch64/flags-multiuse.ll b/test/CodeGen/AArch64/flags-multiuse.ll new file mode 100644 index 0000000000..940c146f0a --- /dev/null +++ b/test/CodeGen/AArch64/flags-multiuse.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +; LLVM should be able to cope with multiple uses of the same flag-setting +; instruction at different points of a routine. Either by rematerializing the +; compare or by saving and restoring the flag register. + +declare void @bar() + +@var = global i32 0 + +define i32 @test_multiflag(i32 %n, i32 %m, i32 %o) { +; CHECK: test_multiflag: + + %test = icmp ne i32 %n, %m +; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]] + + %val = zext i1 %test to i32 +; CHECK: csinc {{[xw][0-9]+}}, {{xzr|wzr}}, {{xzr|wzr}}, eq + + store i32 %val, i32* @var + + call void @bar() +; CHECK: bl bar + + ; Currently, the comparison is emitted again. An MSR/MRS pair would also be + ; acceptable, but assuming the call preserves NZCV is not. + br i1 %test, label %iftrue, label %iffalse +; CHECK: cmp [[LHS]], [[RHS]] +; CHECK: b.eq + +iftrue: + ret i32 42 +iffalse: + ret i32 0 +} diff --git a/test/CodeGen/AArch64/floatdp_1source.ll b/test/CodeGen/AArch64/floatdp_1source.ll new file mode 100644 index 0000000000..c94ba9b57b --- /dev/null +++ b/test/CodeGen/AArch64/floatdp_1source.ll @@ -0,0 +1,138 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@varhalf = global half 0.0 +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +declare float @fabsf(float) readonly +declare double @fabs(double) readonly + +declare float @llvm.sqrt.f32(float %Val) +declare double @llvm.sqrt.f64(double %Val) + +declare float @ceilf(float) readonly +declare double @ceil(double) readonly + +declare float @floorf(float) readonly +declare double @floor(double) readonly + +declare float @truncf(float) readonly +declare double @trunc(double) readonly + +declare float @rintf(float) readonly +declare double @rint(double) readonly + +declare float @nearbyintf(float) readonly +declare double @nearbyint(double) readonly + +define void @simple_float() { +; CHECK: simple_float: + %val1 = load volatile float* @varfloat + + %valabs = call float @fabsf(float %val1) + store volatile float %valabs, float* @varfloat +; CHECK: fabs {{s[0-9]+}}, {{s[0-9]+}} + + %valneg = fsub float -0.0, %val1 + store volatile float %valneg, float* @varfloat +; CHECK: fneg {{s[0-9]+}}, {{s[0-9]+}} + + %valsqrt = call float @llvm.sqrt.f32(float %val1) + store volatile float %valsqrt, float* @varfloat +; CHECK: fsqrt {{s[0-9]+}}, {{s[0-9]+}} + + %valceil = call float @ceilf(float %val1) + store volatile float %valceil, float* @varfloat +; CHECK: frintp {{s[0-9]+}}, {{s[0-9]+}} + + %valfloor = call float @floorf(float %val1) + store volatile float %valfloor, float* @varfloat +; CHECK: frintm {{s[0-9]+}}, {{s[0-9]+}} + + %valtrunc = call float @truncf(float %val1) + store volatile float %valtrunc, float* @varfloat +; CHECK: frintz {{s[0-9]+}}, {{s[0-9]+}} + + %valrint = call float @rintf(float %val1) + store volatile float %valrint, float* @varfloat +; CHECK: frintx {{s[0-9]+}}, {{s[0-9]+}} + + %valnearbyint = call float @nearbyintf(float %val1) + store volatile float %valnearbyint, float* @varfloat +; CHECK: frinti {{s[0-9]+}}, {{s[0-9]+}} + + ret void +} + +define void @simple_double() { +; CHECK: simple_double: + %val1 = load volatile double* @vardouble + + %valabs = call double @fabs(double %val1) + store volatile double %valabs, double* @vardouble +; CHECK: fabs {{d[0-9]+}}, {{d[0-9]+}} + + %valneg = fsub double -0.0, %val1 + store volatile double %valneg, double* @vardouble +; CHECK: fneg {{d[0-9]+}}, {{d[0-9]+}} + + %valsqrt = call double @llvm.sqrt.f64(double %val1) + store volatile double %valsqrt, double* @vardouble +; CHECK: fsqrt {{d[0-9]+}}, {{d[0-9]+}} + + %valceil = call double @ceil(double %val1) + store volatile double %valceil, double* @vardouble +; CHECK: frintp {{d[0-9]+}}, {{d[0-9]+}} + + %valfloor = call double @floor(double %val1) + store volatile double %valfloor, double* @vardouble +; CHECK: frintm {{d[0-9]+}}, {{d[0-9]+}} + + %valtrunc = call double @trunc(double %val1) + store volatile double %valtrunc, double* @vardouble +; CHECK: frintz {{d[0-9]+}}, {{d[0-9]+}} + + %valrint = call double @rint(double %val1) + store volatile double %valrint, double* @vardouble +; CHECK: frintx {{d[0-9]+}}, {{d[0-9]+}} + + %valnearbyint = call double @nearbyint(double %val1) + store volatile double %valnearbyint, double* @vardouble +; CHECK: frinti {{d[0-9]+}}, {{d[0-9]+}} + + ret void +} + +define void @converts() { +; CHECK: converts: + + %val16 = load volatile half* @varhalf + %val32 = load volatile float* @varfloat + %val64 = load volatile double* @vardouble + + %val16to32 = fpext half %val16 to float + store volatile float %val16to32, float* @varfloat +; CHECK: fcvt {{s[0-9]+}}, {{h[0-9]+}} + + %val16to64 = fpext half %val16 to double + store volatile double %val16to64, double* @vardouble +; CHECK: fcvt {{d[0-9]+}}, {{h[0-9]+}} + + %val32to16 = fptrunc float %val32 to half + store volatile half %val32to16, half* @varhalf +; CHECK: fcvt {{h[0-9]+}}, {{s[0-9]+}} + + %val32to64 = fpext float %val32 to double + store volatile double %val32to64, double* @vardouble +; CHECK: fcvt {{d[0-9]+}}, {{s[0-9]+}} + + %val64to16 = fptrunc double %val64 to half + store volatile half %val64to16, half* @varhalf +; CHECK: fcvt {{h[0-9]+}}, {{d[0-9]+}} + + %val64to32 = fptrunc double %val64 to float + store volatile float %val64to32, float* @varfloat +; CHECK: fcvt {{s[0-9]+}}, {{d[0-9]+}} + + ret void +} diff --git a/test/CodeGen/AArch64/floatdp_2source.ll b/test/CodeGen/AArch64/floatdp_2source.ll new file mode 100644 index 0000000000..b2256b342a --- /dev/null +++ b/test/CodeGen/AArch64/floatdp_2source.ll @@ -0,0 +1,60 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +define void @testfloat() { +; CHECK: testfloat: + %val1 = load float* @varfloat + + %val2 = fadd float %val1, %val1 +; CHECK: fadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + + %val3 = fmul float %val2, %val1 +; CHECK: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + + %val4 = fdiv float %val3, %val1 +; CHECK: fdiv {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + + %val5 = fsub float %val4, %val2 +; CHECK: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + + store volatile float %val5, float* @varfloat + +; These will be enabled with the implementation of floating-point litpool entries. + %val6 = fmul float %val1, %val2 + %val7 = fsub float -0.0, %val6 +; CHECK: fnmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + + store volatile float %val7, float* @varfloat + + ret void +} + +define void @testdouble() { +; CHECK: testdouble: + %val1 = load double* @vardouble + + %val2 = fadd double %val1, %val1 +; CHECK: fadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + + %val3 = fmul double %val2, %val1 +; CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + + %val4 = fdiv double %val3, %val1 +; CHECK: fdiv {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + + %val5 = fsub double %val4, %val2 +; CHECK: fsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + + store volatile double %val5, double* @vardouble + +; These will be enabled with the implementation of doubleing-point litpool entries. + %val6 = fmul double %val1, %val2 + %val7 = fsub double -0.0, %val6 +; CHECK: fnmul {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + + store volatile double %val7, double* @vardouble + + ret void +} diff --git a/test/CodeGen/AArch64/fp-cond-sel.ll b/test/CodeGen/AArch64/fp-cond-sel.ll new file mode 100644 index 0000000000..56e8f16f9b --- /dev/null +++ b/test/CodeGen/AArch64/fp-cond-sel.ll @@ -0,0 +1,26 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +define void @test_csel(i32 %lhs32, i32 %rhs32, i64 %lhs64) { +; CHECK: test_csel: + + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %val1 = select i1 %tst1, float 0.0, float 1.0 + store float %val1, float* @varfloat +; CHECK: ldr [[FLT0:s[0-9]+]], [{{x[0-9]+}}, #:lo12:.LCPI +; CHECK: fmov [[FLT1:s[0-9]+]], #1.0 +; CHECK: fcsel {{s[0-9]+}}, [[FLT0]], [[FLT1]], hi + + %rhs64 = sext i32 %rhs32 to i64 + %tst2 = icmp sle i64 %lhs64, %rhs64 + %val2 = select i1 %tst2, double 1.0, double 0.0 + store double %val2, double* @vardouble +; CHECK: ldr [[FLT0:d[0-9]+]], [{{x[0-9]+}}, #:lo12:.LCPI +; CHECK: fmov [[FLT1:d[0-9]+]], #1.0 +; CHECK: fcsel {{d[0-9]+}}, [[FLT1]], [[FLT0]], le + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/fp-dp3.ll b/test/CodeGen/AArch64/fp-dp3.ll new file mode 100644 index 0000000000..39db9be157 --- /dev/null +++ b/test/CodeGen/AArch64/fp-dp3.ll @@ -0,0 +1,102 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -fp-contract=fast | FileCheck %s + +declare float @llvm.fma.f32(float, float, float) +declare double @llvm.fma.f64(double, double, double) + +define float @test_fmadd(float %a, float %b, float %c) { +; CHECK: test_fmadd: + %val = call float @llvm.fma.f32(float %a, float %b, float %c) +; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %val +} + +define float @test_fmsub(float %a, float %b, float %c) { +; CHECK: test_fmsub: + %nega = fsub float -0.0, %a + %val = call float @llvm.fma.f32(float %nega, float %b, float %c) +; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %val +} + +define float @test_fnmadd(float %a, float %b, float %c) { +; CHECK: test_fnmadd: + %negc = fsub float -0.0, %c + %val = call float @llvm.fma.f32(float %a, float %b, float %negc) +; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %val +} + +define float @test_fnmsub(float %a, float %b, float %c) { +; CHECK: test_fnmsub: + %nega = fsub float -0.0, %a + %negc = fsub float -0.0, %c + %val = call float @llvm.fma.f32(float %nega, float %b, float %negc) +; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %val +} + +define double @testd_fmadd(double %a, double %b, double %c) { +; CHECK: testd_fmadd: + %val = call double @llvm.fma.f64(double %a, double %b, double %c) +; CHECK: fmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + ret double %val +} + +define double @testd_fmsub(double %a, double %b, double %c) { +; CHECK: testd_fmsub: + %nega = fsub double -0.0, %a + %val = call double @llvm.fma.f64(double %nega, double %b, double %c) +; CHECK: fmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + ret double %val +} + +define double @testd_fnmadd(double %a, double %b, double %c) { +; CHECK: testd_fnmadd: + %negc = fsub double -0.0, %c + %val = call double @llvm.fma.f64(double %a, double %b, double %negc) +; CHECK: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + ret double %val +} + +define double @testd_fnmsub(double %a, double %b, double %c) { +; CHECK: testd_fnmsub: + %nega = fsub double -0.0, %a + %negc = fsub double -0.0, %c + %val = call double @llvm.fma.f64(double %nega, double %b, double %negc) +; CHECK: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + ret double %val +} + +define float @test_fmadd_unfused(float %a, float %b, float %c) { +; CHECK: test_fmadd_unfused: + %prod = fmul float %b, %c + %sum = fadd float %a, %prod +; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %sum +} + +define float @test_fmsub_unfused(float %a, float %b, float %c) { +; CHECK: test_fmsub_unfused: + %prod = fmul float %b, %c + %diff = fsub float %a, %prod +; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %diff +} + +define float @test_fnmadd_unfused(float %a, float %b, float %c) { +; CHECK: test_fnmadd_unfused: + %nega = fsub float -0.0, %a + %prod = fmul float %b, %c + %sum = fadd float %nega, %prod +; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %sum +} + +define float @test_fnmsub_unfused(float %a, float %b, float %c) { +; CHECK: test_fnmsub_unfused: + %nega = fsub float -0.0, %a + %prod = fmul float %b, %c + %diff = fsub float %nega, %prod +; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + ret float %diff +} diff --git a/test/CodeGen/AArch64/fp128-folding.ll b/test/CodeGen/AArch64/fp128-folding.ll new file mode 100644 index 0000000000..b5bdcf4f37 --- /dev/null +++ b/test/CodeGen/AArch64/fp128-folding.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s +declare void @bar(i8*, i8*, i32*) + +; SelectionDAG used to try to fold some fp128 operations using the ppc128 type, +; which is not supported. + +define fp128 @test_folding() { +; CHECK: test_folding: + %l = alloca i32 + store i32 42, i32* %l + %val = load i32* %l + %fpval = sitofp i32 %val to fp128 + ; If the value is loaded from a constant pool into an fp128, it's been folded + ; successfully. +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, #:lo12:.LCPI + ret fp128 %fpval +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/fp128.ll b/test/CodeGen/AArch64/fp128.ll new file mode 100644 index 0000000000..258d34b8f8 --- /dev/null +++ b/test/CodeGen/AArch64/fp128.ll @@ -0,0 +1,280 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +@lhs = global fp128 zeroinitializer +@rhs = global fp128 zeroinitializer + +define fp128 @test_add() { +; CHECK: test_add: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + + %val = fadd fp128 %lhs, %rhs +; CHECK: bl __addtf3 + ret fp128 %val +} + +define fp128 @test_sub() { +; CHECK: test_sub: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + + %val = fsub fp128 %lhs, %rhs +; CHECK: bl __subtf3 + ret fp128 %val +} + +define fp128 @test_mul() { +; CHECK: test_mul: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + + %val = fmul fp128 %lhs, %rhs +; CHECK: bl __multf3 + ret fp128 %val +} + +define fp128 @test_div() { +; CHECK: test_div: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + + %val = fdiv fp128 %lhs, %rhs +; CHECK: bl __divtf3 + ret fp128 %val +} + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_fptosi() { +; CHECK: test_fptosi: + %val = load fp128* @lhs + + %val32 = fptosi fp128 %val to i32 + store i32 %val32, i32* @var32 +; CHECK: bl __fixtfsi + + %val64 = fptosi fp128 %val to i64 + store i64 %val64, i64* @var64 +; CHECK: bl __fixtfdi + + ret void +} + +define void @test_fptoui() { +; CHECK: test_fptoui: + %val = load fp128* @lhs + + %val32 = fptoui fp128 %val to i32 + store i32 %val32, i32* @var32 +; CHECK: bl __fixunstfsi + + %val64 = fptoui fp128 %val to i64 + store i64 %val64, i64* @var64 +; CHECK: bl __fixunstfdi + + ret void +} + +define void @test_sitofp() { +; CHECK: test_sitofp: + + %src32 = load i32* @var32 + %val32 = sitofp i32 %src32 to fp128 + store volatile fp128 %val32, fp128* @lhs +; CHECK: bl __floatsitf + + %src64 = load i64* @var64 + %val64 = sitofp i64 %src64 to fp128 + store volatile fp128 %val64, fp128* @lhs +; CHECK: bl __floatditf + + ret void +} + +define void @test_uitofp() { +; CHECK: test_uitofp: + + %src32 = load i32* @var32 + %val32 = uitofp i32 %src32 to fp128 + store volatile fp128 %val32, fp128* @lhs +; CHECK: bl __floatunsitf + + %src64 = load i64* @var64 + %val64 = uitofp i64 %src64 to fp128 + store volatile fp128 %val64, fp128* @lhs +; CHECK: bl __floatunditf + + ret void +} + +define i1 @test_setcc1() { +; CHECK: test_setcc1: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + +; Technically, everything after the call to __letf2 is redundant, but we'll let +; LLVM have its fun for now. + %val = fcmp ole fp128 %lhs, %rhs +; CHECK: bl __letf2 +; CHECK: cmp w0, #0 +; CHECK: csinc w0, wzr, wzr, gt + + ret i1 %val +; CHECK: ret +} + +define i1 @test_setcc2() { +; CHECK: test_setcc2: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + +; Technically, everything after the call to __letf2 is redundant, but we'll let +; LLVM have its fun for now. + %val = fcmp ugt fp128 %lhs, %rhs +; CHECK: bl __unordtf2 +; CHECK: mov x[[UNORDERED:[0-9]+]], x0 + +; CHECK: bl __gttf2 +; CHECK: cmp w0, #0 +; CHECK: csinc [[GT:w[0-9]+]], wzr, wzr, le +; CHECK: cmp w[[UNORDERED]], #0 +; CHECK: csinc [[UNORDERED:w[0-9]+]], wzr, wzr, eq +; CHECK: orr w0, [[UNORDERED]], [[GT]] + + ret i1 %val +; CHECK: ret +} + +define i32 @test_br_cc() { +; CHECK: test_br_cc: + + %lhs = load fp128* @lhs + %rhs = load fp128* @rhs +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:lhs] +; CHECK: ldr q1, [{{x[0-9]+}}, #:lo12:rhs] + + ; olt == !uge, which LLVM unfortunately "optimizes" this to. + %cond = fcmp olt fp128 %lhs, %rhs +; CHECK: bl __unordtf2 +; CHECK: mov x[[UNORDERED:[0-9]+]], x0 + +; CHECK: bl __getf2 +; CHECK: cmp w0, #0 + +; CHECK: csinc [[OGE:w[0-9]+]], wzr, wzr, lt +; CHECK: cmp w[[UNORDERED]], #0 +; CHECK: csinc [[UNORDERED:w[0-9]+]], wzr, wzr, eq +; CHECK: orr [[UGE:w[0-9]+]], [[UNORDERED]], [[OGE]] +; CHECK: cbnz [[UGE]], [[RET29:.LBB[0-9]+_[0-9]+]] + br i1 %cond, label %iftrue, label %iffalse + +iftrue: + ret i32 42 +; CHECK-NEXT: BB# +; CHECK-NEXT: movz x0, #42 +; CHECK-NEXT: b [[REALRET:.LBB[0-9]+_[0-9]+]] + +iffalse: + ret i32 29 +; CHECK: [[RET29]]: +; CHECK-NEXT: movz x0, #29 +; CHECK-NEXT: [[REALRET]]: +; CHECK: ret +} + +define void @test_select(i1 %cond, fp128 %lhs, fp128 %rhs) { +; CHECK: test_select: + + %val = select i1 %cond, fp128 %lhs, fp128 %rhs + store fp128 %val, fp128* @lhs +; CHECK: cmp w0, #0 +; CHECK: str q1, [sp] +; CHECK-NEXT: b.eq [[IFFALSE:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: BB# +; CHECK-NEXT: str q0, [sp] +; CHECK-NEXT: [[IFFALSE]]: +; CHECK-NEXT: ldr q0, [sp] +; CHECK: str q0, [{{x[0-9]+}}, #:lo12:lhs] + ret void +; CHECK: ret +} + +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +define void @test_round() { +; CHECK: test_round: + + %val = load fp128* @lhs + + %float = fptrunc fp128 %val to float + store float %float, float* @varfloat +; CHECK: bl __trunctfsf2 +; CHECK: str s0, [{{x[0-9]+}}, #:lo12:varfloat] + + %double = fptrunc fp128 %val to double + store double %double, double* @vardouble +; CHECK: bl __trunctfdf2 +; CHECK: str d0, [{{x[0-9]+}}, #:lo12:vardouble] + + ret void +} + +define void @test_extend() { +; CHECK: test_extend: + + %val = load fp128* @lhs + + %float = load float* @varfloat + %fromfloat = fpext float %float to fp128 + store volatile fp128 %fromfloat, fp128* @lhs +; CHECK: bl __extendsftf2 +; CHECK: str q0, [{{x[0-9]+}}, #:lo12:lhs] + + %double = load double* @vardouble + %fromdouble = fpext double %double to fp128 + store volatile fp128 %fromdouble, fp128* @lhs +; CHECK: bl __extenddftf2 +; CHECK: str q0, [{{x[0-9]+}}, #:lo12:lhs] + + ret void +; CHECK: ret +} + +define fp128 @test_neg(fp128 %in) { +; CHECK: [[MINUS0:.LCPI[0-9]+_0]]: +; Make sure the weird hex constant below *is* -0.0 +; CHECK-NEXT: fp128 -0 + +; CHECK: test_neg: + + ; Could in principle be optimized to fneg which we can't select, this makes + ; sure that doesn't happen. + %ret = fsub fp128 0xL00000000000000008000000000000000, %in +; CHECK: str q0, [sp, #-16] +; CHECK-NEXT: ldr q1, [sp], #16 +; CHECK: ldr q0, [{{x[0-9]+}}, #:lo12:[[MINUS0]]] +; CHECK: bl __subtf3 + + ret fp128 %ret +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/fpimm.ll b/test/CodeGen/AArch64/fpimm.ll new file mode 100644 index 0000000000..fd28aeef92 --- /dev/null +++ b/test/CodeGen/AArch64/fpimm.ll @@ -0,0 +1,34 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@varf32 = global float 0.0 +@varf64 = global double 0.0 + +define void @check_float() { +; CHECK: check_float: + + %val = load float* @varf32 + %newval1 = fadd float %val, 8.5 + store volatile float %newval1, float* @varf32 +; CHECK: fmov {{s[0-9]+}}, #8.5 + + %newval2 = fadd float %val, 128.0 + store volatile float %newval2, float* @varf32 +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, #:lo12:.LCPI0_0 + + ret void +} + +define void @check_double() { +; CHECK: check_double: + + %val = load double* @varf64 + %newval1 = fadd double %val, 8.5 + store volatile double %newval1, double* @varf64 +; CHECK: fmov {{d[0-9]+}}, #8.5 + + %newval2 = fadd double %val, 128.0 + store volatile double %newval2, double* @varf64 +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, #:lo12:.LCPI1_0 + + ret void +} diff --git a/test/CodeGen/AArch64/func-argpassing.ll b/test/CodeGen/AArch64/func-argpassing.ll new file mode 100644 index 0000000000..78fde6a3c3 --- /dev/null +++ b/test/CodeGen/AArch64/func-argpassing.ll @@ -0,0 +1,193 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +%myStruct = type { i64 , i8, i32 } + +@var8 = global i8 0 +@var32 = global i32 0 +@var64 = global i64 0 +@var128 = global i128 0 +@varfloat = global float 0.0 +@vardouble = global double 0.0 +@varstruct = global %myStruct zeroinitializer + +define void @take_i8s(i8 %val1, i8 %val2) { +; CHECK: take_i8s: + store i8 %val2, i8* @var8 + ; Not using w1 may be technically allowed, but it would indicate a + ; problem in itself. +; CHECK: strb w1, [{{x[0-9]+}}, #:lo12:var8] + ret void +} + +define void @add_floats(float %val1, float %val2) { +; CHECK: add_floats: + %newval = fadd float %val1, %val2 +; CHECK: fadd [[ADDRES:s[0-9]+]], s0, s1 + store float %newval, float* @varfloat +; CHECK: str [[ADDRES]], [{{x[0-9]+}}, #:lo12:varfloat] + ret void +} + +; byval pointers should be allocated to the stack and copied as if +; with memcpy. +define void @take_struct(%myStruct* byval %structval) { +; CHECK: take_struct: + %addr0 = getelementptr %myStruct* %structval, i64 0, i32 2 + %addr1 = getelementptr %myStruct* %structval, i64 0, i32 0 + + %val0 = load i32* %addr0 + ; Some weird move means x0 is used for one access +; CHECK: ldr [[REG32:w[0-9]+]], [{{x[0-9]+|sp}}, #12] + store i32 %val0, i32* @var32 +; CHECK: str [[REG32]], [{{x[0-9]+}}, #:lo12:var32] + + %val1 = load i64* %addr1 +; CHECK: ldr [[REG64:x[0-9]+]], [{{x[0-9]+|sp}}] + store i64 %val1, i64* @var64 +; CHECK: str [[REG64]], [{{x[0-9]+}}, #:lo12:var64] + + ret void +} + +; %structval should be at sp + 16 +define void @check_byval_align(i32* byval %ignore, %myStruct* byval align 16 %structval) { +; CHECK: check_byval_align: + + %addr0 = getelementptr %myStruct* %structval, i64 0, i32 2 + %addr1 = getelementptr %myStruct* %structval, i64 0, i32 0 + + %val0 = load i32* %addr0 + ; Some weird move means x0 is used for one access +; CHECK: add x[[STRUCTVAL_ADDR:[0-9]+]], sp, #16 +; CHECK: ldr [[REG32:w[0-9]+]], [x[[STRUCTVAL_ADDR]], #12] + store i32 %val0, i32* @var32 +; CHECK: str [[REG32]], [{{x[0-9]+}}, #:lo12:var32] + + %val1 = load i64* %addr1 +; CHECK: ldr [[REG64:x[0-9]+]], [sp, #16] + store i64 %val1, i64* @var64 +; CHECK: str [[REG64]], [{{x[0-9]+}}, #:lo12:var64] + + ret void +} + +define i32 @return_int() { +; CHECK: return_int: + %val = load i32* @var32 + ret i32 %val +; CHECK: ldr w0, [{{x[0-9]+}}, #:lo12:var32] + ; Make sure epilogue follows +; CHECK-NEXT: ret +} + +define double @return_double() { +; CHECK: return_double: + ret double 3.14 +; CHECK: ldr d0, [{{x[0-9]+}}, #:lo12:.LCPI +} + +; This is the kind of IR clang will produce for returning a struct +; small enough to go into registers. Not all that pretty, but it +; works. +define [2 x i64] @return_struct() { +; CHECK: return_struct: + %addr = bitcast %myStruct* @varstruct to [2 x i64]* + %val = load [2 x i64]* %addr + ret [2 x i64] %val +; CHECK: ldr x0, [{{x[0-9]+}}, #:lo12:varstruct] + ; Odd register regex below disallows x0 which we want to be live now. +; CHECK: add {{x[1-9][0-9]*}}, {{x[1-9][0-9]*}}, #:lo12:varstruct +; CHECK-NEXT: ldr x1, [{{x[1-9][0-9]*}}, #8] + ; Make sure epilogue immediately follows +; CHECK-NEXT: ret +} + +; Large structs are passed by reference (storage allocated by caller +; to preserve value semantics) in x8. Strictly this only applies to +; structs larger than 16 bytes, but C semantics can still be provided +; if LLVM does it to %myStruct too. So this is the simplest check +define void @return_large_struct(%myStruct* sret %retval) { +; CHECK: return_large_struct: + %addr0 = getelementptr %myStruct* %retval, i64 0, i32 0 + %addr1 = getelementptr %myStruct* %retval, i64 0, i32 1 + %addr2 = getelementptr %myStruct* %retval, i64 0, i32 2 + + store i64 42, i64* %addr0 + store i8 2, i8* %addr1 + store i32 9, i32* %addr2 +; CHECK: str {{x[0-9]+}}, [x8] +; CHECK: strb {{w[0-9]+}}, [x8, #8] +; CHECK: str {{w[0-9]+}}, [x8, #12] + + ret void +} + +; This struct is just too far along to go into registers: (only x7 is +; available, but it needs two). Also make sure that %stacked doesn't +; sneak into x7 behind. +define i32 @struct_on_stack(i8 %var0, i16 %var1, i32 %var2, i64 %var3, i128 %var45, + i32* %var6, %myStruct* byval %struct, i32* byval %stacked, + double %notstacked) { +; CHECK: struct_on_stack: + %addr = getelementptr %myStruct* %struct, i64 0, i32 0 + %val64 = load i64* %addr + store i64 %val64, i64* @var64 + ; Currently nothing on local stack, so struct should be at sp +; CHECK: ldr [[VAL64:x[0-9]+]], [sp] +; CHECK: str [[VAL64]], [{{x[0-9]+}}, #:lo12:var64] + + store double %notstacked, double* @vardouble +; CHECK-NOT: ldr d0 +; CHECK: str d0, [{{x[0-9]+}}, #:lo12:vardouble + + %retval = load i32* %stacked + ret i32 %retval +; CHECK: ldr w0, [sp, #16] +} + +define void @stacked_fpu(float %var0, double %var1, float %var2, float %var3, + float %var4, float %var5, float %var6, float %var7, + float %var8) { +; CHECK: stacked_fpu: + store float %var8, float* @varfloat + ; Beware as above: the offset would be different on big-endian + ; machines if the first ldr were changed to use s-registers. +; CHECK: ldr d[[VALFLOAT:[0-9]+]], [sp] +; CHECK: str s[[VALFLOAT]], [{{x[0-9]+}}, #:lo12:varfloat] + + ret void +} + +; 128-bit integer types should be passed in xEVEN, xODD rather than +; the reverse. In this case x2 and x3. Nothing should use x1. +define i32 @check_i128_regalign(i32 %val0, i128 %val1, i32 %val2) { +; CHECK: check_i128_regalign + store i128 %val1, i128* @var128 +; CHECK: str x2, [{{x[0-9]+}}, #:lo12:var128] +; CHECK: str x3, [{{x[0-9]+}}, #8] + + ret i32 %val2 +; CHECK: mov x0, x4 +} + +define void @check_i128_stackalign(i32 %val0, i32 %val1, i32 %val2, i32 %val3, + i32 %val4, i32 %val5, i32 %val6, i32 %val7, + i32 %stack1, i128 %stack2) { +; CHECK: check_i128_stackalign + store i128 %stack2, i128* @var128 + ; Nothing local on stack in current codegen, so first stack is 16 away +; CHECK: ldr {{x[0-9]+}}, [sp, #16] + ; Important point is that we address sp+24 for second dword +; CHECK: add [[REG:x[0-9]+]], sp, #16 +; CHECK: ldr {{x[0-9]+}}, {{\[}}[[REG]], #8] + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1) + +define i32 @test_extern() { +; CHECK: test_extern: + call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* undef, i32 undef, i32 4, i1 0) +; CHECK: bl memcpy + ret i32 0 +} diff --git a/test/CodeGen/AArch64/func-calls.ll b/test/CodeGen/AArch64/func-calls.ll new file mode 100644 index 0000000000..13b689c408 --- /dev/null +++ b/test/CodeGen/AArch64/func-calls.ll @@ -0,0 +1,140 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +%myStruct = type { i64 , i8, i32 } + +@var8 = global i8 0 +@var8_2 = global i8 0 +@var32 = global i32 0 +@var64 = global i64 0 +@var128 = global i128 0 +@varfloat = global float 0.0 +@varfloat_2 = global float 0.0 +@vardouble = global double 0.0 +@varstruct = global %myStruct zeroinitializer +@varsmallstruct = global [2 x i64] zeroinitializer + +declare void @take_i8s(i8 %val1, i8 %val2) +declare void @take_floats(float %val1, float %val2) + +define void @simple_args() { +; CHECK: simple_args: + %char1 = load i8* @var8 + %char2 = load i8* @var8_2 + call void @take_i8s(i8 %char1, i8 %char2) +; CHECK: ldrb w0, [{{x[0-9]+}}, #:lo12:var8] +; CHECK: ldrb w1, [{{x[0-9]+}}, #:lo12:var8_2] +; CHECK: bl take_i8s + + %float1 = load float* @varfloat + %float2 = load float* @varfloat_2 + call void @take_floats(float %float1, float %float2) +; CHECK: ldr s1, [{{x[0-9]+}}, #:lo12:varfloat_2] +; CHECK: ldr s0, [{{x[0-9]+}}, #:lo12:varfloat] +; CHECK: bl take_floats + + ret void +} + +declare i32 @return_int() +declare double @return_double() +declare [2 x i64] @return_smallstruct() +declare void @return_large_struct(%myStruct* sret %retval) + +define void @simple_rets() { +; CHECK: simple_rets: + + %int = call i32 @return_int() + store i32 %int, i32* @var32 +; CHECK: bl return_int +; CHECK: str w0, [{{x[0-9]+}}, #:lo12:var32] + + %dbl = call double @return_double() + store double %dbl, double* @vardouble +; CHECK: bl return_double +; CHECK: str d0, [{{x[0-9]+}}, #:lo12:vardouble] + + %arr = call [2 x i64] @return_smallstruct() + store [2 x i64] %arr, [2 x i64]* @varsmallstruct +; CHECK: bl return_smallstruct +; CHECK: str x1, [{{x[0-9]+}}, #8] +; CHECK: str x0, [{{x[0-9]+}}, #:lo12:varsmallstruct] + + call void @return_large_struct(%myStruct* sret @varstruct) +; CHECK: add x8, {{x[0-9]+}}, #:lo12:varstruct +; CHECK: bl return_large_struct + + ret void +} + + +declare i32 @struct_on_stack(i8 %var0, i16 %var1, i32 %var2, i64 %var3, i128 %var45, + i32* %var6, %myStruct* byval %struct, i32 %stacked, + double %notstacked) +declare void @stacked_fpu(float %var0, double %var1, float %var2, float %var3, + float %var4, float %var5, float %var6, float %var7, + float %var8) + +define void @check_stack_args() { + call i32 @struct_on_stack(i8 0, i16 12, i32 42, i64 99, i128 1, + i32* @var32, %myStruct* byval @varstruct, + i32 999, double 1.0) + ; Want to check that the final double is passed in registers and + ; that varstruct is passed on the stack. Rather dependent on how a + ; memcpy gets created, but the following works for now. +; CHECK: mov x0, sp +; CHECK: str {{w[0-9]+}}, [x0] +; CHECK: str {{w[0-9]+}}, [x0, #12] +; CHECK: fmov d0, +; CHECK: bl struct_on_stack + + call void @stacked_fpu(float -1.0, double 1.0, float 4.0, float 2.0, + float -2.0, float -8.0, float 16.0, float 1.0, + float 64.0) +; CHECK: ldr s[[STACKEDREG:[0-9]+]], [{{x[0-9]+}}, #:lo12:.LCPI +; CHECK: mov x0, sp +; CHECK: str d[[STACKEDREG]], [x0] +; CHECK: bl stacked_fpu + ret void +} + + +declare void @check_i128_stackalign(i32 %val0, i32 %val1, i32 %val2, i32 %val3, + i32 %val4, i32 %val5, i32 %val6, i32 %val7, + i32 %stack1, i128 %stack2) + +declare void @check_i128_regalign(i32 %val0, i128 %val1) + + +define void @check_i128_align() { +; CHECK: check_i128_align: + %val = load i128* @var128 + call void @check_i128_stackalign(i32 0, i32 1, i32 2, i32 3, + i32 4, i32 5, i32 6, i32 7, + i32 42, i128 %val) +; CHECK: ldr [[I128LO:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var128] +; CHECK: ldr [[I128HI:x[0-9]+]], [{{x[0-9]+}}, #8] +; CHECK: mov x[[SPREG:[0-9]+]], sp +; CHECK: str [[I128HI]], [x[[SPREG]], #24] +; CHECK: str [[I128LO]], [x[[SPREG]], #16] +; CHECK: bl check_i128_stackalign + + call void @check_i128_regalign(i32 0, i128 42) +; CHECK-NOT: mov x1 +; CHECK: movz x2, #42 +; CHECK: mov x3, xzr +; CHECK: bl check_i128_regalign + + ret void +} + +@fptr = global void()* null + +define void @check_indirect_call() { +; CHECK: check_indirect_call: + %func = load void()** @fptr + call void %func() +; CHECK: ldr [[FPTR:x[0-9]+]], [{{x[0-9]+}}, #:lo12:fptr] +; CHECK: blr [[FPTR]] + + ret void +} diff --git a/test/CodeGen/AArch64/global-alignment.ll b/test/CodeGen/AArch64/global-alignment.ll new file mode 100644 index 0000000000..8ed6e551cd --- /dev/null +++ b/test/CodeGen/AArch64/global-alignment.ll @@ -0,0 +1,69 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +@var32 = global [3 x i32] zeroinitializer +@var64 = global [3 x i64] zeroinitializer +@var32_align64 = global [3 x i32] zeroinitializer, align 8 + +define i64 @test_align32() { +; CHECK: test_align32: + %addr = bitcast [3 x i32]* @var32 to i64* + + ; Since @var32 is only guaranteed to be aligned to 32-bits, it's invalid to + ; emit an "LDR x0, [x0, #:lo12:var32] instruction to implement this load. + %val = load i64* %addr +; CHECK: adrp [[HIBITS:x[0-9]+]], var32 +; CHECK: add x[[ADDR:[0-9]+]], [[HIBITS]], #:lo12:var32 +; CHECK: ldr x0, [x[[ADDR]]] + + ret i64 %val +} + +define i64 @test_align64() { +; CHECK: test_align64: + %addr = bitcast [3 x i64]* @var64 to i64* + + ; However, var64 *is* properly aligned and emitting an adrp/add/ldr would be + ; inefficient. + %val = load i64* %addr +; CHECK: adrp x[[HIBITS:[0-9]+]], var64 +; CHECK-NOT: add x[[HIBITS]] +; CHECK: ldr x0, [x[[HIBITS]], #:lo12:var64] + + ret i64 %val +} + +define i64 @test_var32_align64() { +; CHECK: test_var32_align64: + %addr = bitcast [3 x i32]* @var32_align64 to i64* + + ; Since @var32 is only guaranteed to be aligned to 32-bits, it's invalid to + ; emit an "LDR x0, [x0, #:lo12:var32] instruction to implement this load. + %val = load i64* %addr +; CHECK: adrp x[[HIBITS:[0-9]+]], var32_align64 +; CHECK-NOT: add x[[HIBITS]] +; CHECK: ldr x0, [x[[HIBITS]], #:lo12:var32_align64] + + ret i64 %val +} + +@yet_another_var = external global {i32, i32} + +define i64 @test_yet_another_var() { +; CHECK: test_yet_another_var: + + ; @yet_another_var has a preferred alignment of 8, but that's not enough if + ; we're going to be linking against other things. Its ABI alignment is only 4 + ; so we can't fold the load. + %val = load i64* bitcast({i32, i32}* @yet_another_var to i64*) +; CHECK: adrp [[HIBITS:x[0-9]+]], yet_another_var +; CHECK: add x[[ADDR:[0-9]+]], [[HIBITS]], #:lo12:yet_another_var +; CHECK: ldr x0, [x[[ADDR]]] + ret i64 %val +} + +define i64()* @test_functions() { +; CHECK: test_functions: + ret i64()* @test_yet_another_var +; CHECK: adrp [[HIBITS:x[0-9]+]], test_yet_another_var +; CHECK: add x0, [[HIBITS]], #:lo12:test_yet_another_var +} diff --git a/test/CodeGen/AArch64/got-abuse.ll b/test/CodeGen/AArch64/got-abuse.ll new file mode 100644 index 0000000000..c474e5845a --- /dev/null +++ b/test/CodeGen/AArch64/got-abuse.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -filetype=obj < %s + +; LLVM gives well-defined semantics to this horrible construct (though C says +; it's undefined). Regardless, we shouldn't crash. The important feature here is +; that in general the only way to access a GOT symbol is via a 64-bit +; load. Neither of these alternatives has the ELF relocations required to +; support it: +; + ldr wD, [xN, #:got_lo12:func] +; + add xD, xN, #:got_lo12:func + +declare void @consume(i32) +declare void @func() + +define void @foo() nounwind { +; CHECK: foo: +entry: + call void @consume(i32 ptrtoint (void ()* @func to i32)) +; CHECK: adrp x[[ADDRHI:[0-9]+]], :got:func +; CHECK: ldr {{x[0-9]+}}, [x[[ADDRHI]], #:got_lo12:func] + ret void +} + diff --git a/test/CodeGen/AArch64/i128-align.ll b/test/CodeGen/AArch64/i128-align.ll new file mode 100644 index 0000000000..f019ea0a67 --- /dev/null +++ b/test/CodeGen/AArch64/i128-align.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +%struct = type { i32, i128, i8 } + +@var = global %struct zeroinitializer + +define i64 @check_size() { +; CHECK: check_size: + %starti = ptrtoint %struct* @var to i64 + + %endp = getelementptr %struct* @var, i64 1 + %endi = ptrtoint %struct* %endp to i64 + + %diff = sub i64 %endi, %starti + ret i64 %diff +; CHECK: movz x0, #48 +} + +define i64 @check_field() { +; CHECK: check_field: + %starti = ptrtoint %struct* @var to i64 + + %endp = getelementptr %struct* @var, i64 0, i32 1 + %endi = ptrtoint i128* %endp to i64 + + %diff = sub i64 %endi, %starti + ret i64 %diff +; CHECK: movz x0, #16 +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/illegal-float-ops.ll b/test/CodeGen/AArch64/illegal-float-ops.ll new file mode 100644 index 0000000000..446151b8ff --- /dev/null +++ b/test/CodeGen/AArch64/illegal-float-ops.ll @@ -0,0 +1,221 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +@varfloat = global float 0.0 +@vardouble = global double 0.0 +@varfp128 = global fp128 zeroinitializer + +declare float @llvm.cos.f32(float) +declare double @llvm.cos.f64(double) +declare fp128 @llvm.cos.f128(fp128) + +define void @test_cos(float %float, double %double, fp128 %fp128) { +; CHECK: test_cos: + + %cosfloat = call float @llvm.cos.f32(float %float) + store float %cosfloat, float* @varfloat +; CHECK: bl cosf + + %cosdouble = call double @llvm.cos.f64(double %double) + store double %cosdouble, double* @vardouble +; CHECK: bl cos + + %cosfp128 = call fp128 @llvm.cos.f128(fp128 %fp128) + store fp128 %cosfp128, fp128* @varfp128 +; CHECK: bl cosl + + ret void +} + +declare float @llvm.exp.f32(float) +declare double @llvm.exp.f64(double) +declare fp128 @llvm.exp.f128(fp128) + +define void @test_exp(float %float, double %double, fp128 %fp128) { +; CHECK: test_exp: + + %expfloat = call float @llvm.exp.f32(float %float) + store float %expfloat, float* @varfloat +; CHECK: bl expf + + %expdouble = call double @llvm.exp.f64(double %double) + store double %expdouble, double* @vardouble +; CHECK: bl exp + + %expfp128 = call fp128 @llvm.exp.f128(fp128 %fp128) + store fp128 %expfp128, fp128* @varfp128 +; CHECK: bl expl + + ret void +} + +declare float @llvm.exp2.f32(float) +declare double @llvm.exp2.f64(double) +declare fp128 @llvm.exp2.f128(fp128) + +define void @test_exp2(float %float, double %double, fp128 %fp128) { +; CHECK: test_exp2: + + %exp2float = call float @llvm.exp2.f32(float %float) + store float %exp2float, float* @varfloat +; CHECK: bl exp2f + + %exp2double = call double @llvm.exp2.f64(double %double) + store double %exp2double, double* @vardouble +; CHECK: bl exp2 + + %exp2fp128 = call fp128 @llvm.exp2.f128(fp128 %fp128) + store fp128 %exp2fp128, fp128* @varfp128 +; CHECK: bl exp2l + ret void + +} + +declare float @llvm.log.f32(float) +declare double @llvm.log.f64(double) +declare fp128 @llvm.log.f128(fp128) + +define void @test_log(float %float, double %double, fp128 %fp128) { +; CHECK: test_log: + + %logfloat = call float @llvm.log.f32(float %float) + store float %logfloat, float* @varfloat +; CHECK: bl logf + + %logdouble = call double @llvm.log.f64(double %double) + store double %logdouble, double* @vardouble +; CHECK: bl log + + %logfp128 = call fp128 @llvm.log.f128(fp128 %fp128) + store fp128 %logfp128, fp128* @varfp128 +; CHECK: bl logl + + ret void +} + +declare float @llvm.log2.f32(float) +declare double @llvm.log2.f64(double) +declare fp128 @llvm.log2.f128(fp128) + +define void @test_log2(float %float, double %double, fp128 %fp128) { +; CHECK: test_log2: + + %log2float = call float @llvm.log2.f32(float %float) + store float %log2float, float* @varfloat +; CHECK: bl log2f + + %log2double = call double @llvm.log2.f64(double %double) + store double %log2double, double* @vardouble +; CHECK: bl log2 + + %log2fp128 = call fp128 @llvm.log2.f128(fp128 %fp128) + store fp128 %log2fp128, fp128* @varfp128 +; CHECK: bl log2l + ret void + +} + +declare float @llvm.log10.f32(float) +declare double @llvm.log10.f64(double) +declare fp128 @llvm.log10.f128(fp128) + +define void @test_log10(float %float, double %double, fp128 %fp128) { +; CHECK: test_log10: + + %log10float = call float @llvm.log10.f32(float %float) + store float %log10float, float* @varfloat +; CHECK: bl log10f + + %log10double = call double @llvm.log10.f64(double %double) + store double %log10double, double* @vardouble +; CHECK: bl log10 + + %log10fp128 = call fp128 @llvm.log10.f128(fp128 %fp128) + store fp128 %log10fp128, fp128* @varfp128 +; CHECK: bl log10l + + ret void +} + +declare float @llvm.sin.f32(float) +declare double @llvm.sin.f64(double) +declare fp128 @llvm.sin.f128(fp128) + +define void @test_sin(float %float, double %double, fp128 %fp128) { +; CHECK: test_sin: + + %sinfloat = call float @llvm.sin.f32(float %float) + store float %sinfloat, float* @varfloat +; CHECK: bl sinf + + %sindouble = call double @llvm.sin.f64(double %double) + store double %sindouble, double* @vardouble +; CHECK: bl sin + + %sinfp128 = call fp128 @llvm.sin.f128(fp128 %fp128) + store fp128 %sinfp128, fp128* @varfp128 +; CHECK: bl sinl + ret void + +} + +declare float @llvm.pow.f32(float, float) +declare double @llvm.pow.f64(double, double) +declare fp128 @llvm.pow.f128(fp128, fp128) + +define void @test_pow(float %float, double %double, fp128 %fp128) { +; CHECK: test_pow: + + %powfloat = call float @llvm.pow.f32(float %float, float %float) + store float %powfloat, float* @varfloat +; CHECK: bl powf + + %powdouble = call double @llvm.pow.f64(double %double, double %double) + store double %powdouble, double* @vardouble +; CHECK: bl pow + + %powfp128 = call fp128 @llvm.pow.f128(fp128 %fp128, fp128 %fp128) + store fp128 %powfp128, fp128* @varfp128 +; CHECK: bl powl + + ret void +} + +declare float @llvm.powi.f32(float, i32) +declare double @llvm.powi.f64(double, i32) +declare fp128 @llvm.powi.f128(fp128, i32) + +define void @test_powi(float %float, double %double, i32 %exponent, fp128 %fp128) { +; CHECK: test_powi: + + %powifloat = call float @llvm.powi.f32(float %float, i32 %exponent) + store float %powifloat, float* @varfloat +; CHECK: bl __powisf2 + + %powidouble = call double @llvm.powi.f64(double %double, i32 %exponent) + store double %powidouble, double* @vardouble +; CHECK: bl __powidf2 + + %powifp128 = call fp128 @llvm.powi.f128(fp128 %fp128, i32 %exponent) + store fp128 %powifp128, fp128* @varfp128 +; CHECK: bl __powitf2 + ret void + +} + +define void @test_frem(float %float, double %double, fp128 %fp128) { +; CHECK: test_frem: + + %fremfloat = frem float %float, %float + store float %fremfloat, float* @varfloat +; CHECK: bl fmodf + + %fremdouble = frem double %double, %double + store double %fremdouble, double* @vardouble +; CHECK: bl fmod + + %fremfp128 = frem fp128 %fp128, %fp128 + store fp128 %fremfp128, fp128* @varfp128 +; CHECK: bl fmodl + + ret void +} diff --git a/test/CodeGen/AArch64/init-array.ll b/test/CodeGen/AArch64/init-array.ll new file mode 100644 index 0000000000..d80be8f3a6 --- /dev/null +++ b/test/CodeGen/AArch64/init-array.ll @@ -0,0 +1,9 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -use-init-array < %s | FileCheck %s + +define internal void @_GLOBAL__I_a() section ".text.startup" { + ret void +} + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] + +; CHECK: .section .init_array
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-constraints-badI.ll b/test/CodeGen/AArch64/inline-asm-constraints-badI.ll new file mode 100644 index 0000000000..c39c57f058 --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-constraints-badI.ll @@ -0,0 +1,7 @@ +; RUN: not llc -mtriple=aarch64-none-linux-gnu < %s + +define void @foo() { + ; Out of range immediate for I. + call void asm sideeffect "add x0, x0, $0", "I"(i32 4096) + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-constraints-badK.ll b/test/CodeGen/AArch64/inline-asm-constraints-badK.ll new file mode 100644 index 0000000000..47c5f98bf0 --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-constraints-badK.ll @@ -0,0 +1,7 @@ +; RUN: not llc -mtriple=aarch64-none-linux-gnu < %s + +define void @foo() { + ; 32-bit bitpattern ending in 1101 can't be produced. + call void asm sideeffect "and w0, w0, $0", "K"(i32 13) + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-constraints-badK2.ll b/test/CodeGen/AArch64/inline-asm-constraints-badK2.ll new file mode 100644 index 0000000000..7a5b99e23b --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-constraints-badK2.ll @@ -0,0 +1,7 @@ +; RUN: not llc -mtriple=aarch64-none-linux-gnu < %s + +define void @foo() { + ; 32-bit bitpattern ending in 1101 can't be produced. + call void asm sideeffect "and w0, w0, $0", "K"(i64 4294967296) + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-constraints-badL.ll b/test/CodeGen/AArch64/inline-asm-constraints-badL.ll new file mode 100644 index 0000000000..4f0039865a --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-constraints-badL.ll @@ -0,0 +1,7 @@ +; RUN: not llc -mtriple=aarch64-none-linux-gnu < %s + +define void @foo() { + ; 32-bit bitpattern ending in 1101 can't be produced. + call void asm sideeffect "and x0, x0, $0", "L"(i32 13) + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-constraints.ll b/test/CodeGen/AArch64/inline-asm-constraints.ll new file mode 100644 index 0000000000..c232f3208c --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-constraints.ll @@ -0,0 +1,117 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +define i64 @test_inline_constraint_r(i64 %base, i32 %offset) { +; CHECK: test_inline_constraint_r: + %val = call i64 asm "add $0, $1, $2, sxtw", "=r,r,r"(i64 %base, i32 %offset) +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{w[0-9]+}}, sxtw + ret i64 %val +} + +define i16 @test_small_reg(i16 %lhs, i16 %rhs) { +; CHECK: test_small_reg: + %val = call i16 asm sideeffect "add $0, $1, $2, sxth", "=r,r,r"(i16 %lhs, i16 %rhs) +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, sxth + ret i16 %val +} + +define i64 @test_inline_constraint_r_imm(i64 %base, i32 %offset) { +; CHECK: test_inline_constraint_r_imm: + %val = call i64 asm "add $0, $1, $2, sxtw", "=r,r,r"(i64 4, i32 12) +; CHECK: movz [[FOUR:x[0-9]+]], #4 +; CHECK: movz [[TWELVE:w[0-9]+]], #12 +; CHECK: add {{x[0-9]+}}, [[FOUR]], [[TWELVE]], sxtw + ret i64 %val +} + +; m is permitted to have a base/offset form. We don't do that +; currently though. +define i32 @test_inline_constraint_m(i32 *%ptr) { +; CHECK: test_inline_constraint_m: + %val = call i32 asm "ldr $0, $1", "=r,m"(i32 *%ptr) +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}] + ret i32 %val +} + +@arr = global [8 x i32] zeroinitializer + +; Q should *never* have base/offset form even if given the chance. +define i32 @test_inline_constraint_Q(i32 *%ptr) { +; CHECK: test_inline_constraint_Q: + %val = call i32 asm "ldr $0, $1", "=r,Q"(i32* getelementptr([8 x i32]* @arr, i32 0, i32 1)) +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}] + ret i32 %val +} + +@dump = global fp128 zeroinitializer + +define void @test_inline_constraint_I() { +; CHECK: test_inline_constraint_I: + call void asm sideeffect "add x0, x0, $0", "I"(i32 0) + call void asm sideeffect "add x0, x0, $0", "I"(i64 4095) +; CHECK: add x0, x0, #0 +; CHECK: add x0, x0, #4095 + + ret void +} + +; Skip J because it's useless + +define void @test_inline_constraint_K() { +; CHECK: test_inline_constraint_K: + call void asm sideeffect "and w0, w0, $0", "K"(i32 2863311530) ; = 0xaaaaaaaa + call void asm sideeffect "and w0, w0, $0", "K"(i32 65535) +; CHECK: and w0, w0, #-1431655766 +; CHECK: and w0, w0, #65535 + + ret void +} + +define void @test_inline_constraint_L() { +; CHECK: test_inline_constraint_L: + call void asm sideeffect "and x0, x0, $0", "L"(i64 4294967296) ; = 0xaaaaaaaa + call void asm sideeffect "and x0, x0, $0", "L"(i64 65535) +; CHECK: and x0, x0, #4294967296 +; CHECK: and x0, x0, #65535 + + ret void +} + +; Skip M and N because we don't support MOV pseudo-instructions yet. + +@var = global i32 0 + +define void @test_inline_constraint_S() { +; CHECK: test_inline_constraint_S: + call void asm sideeffect "adrp x0, $0", "S"(i32* @var) + call void asm sideeffect "adrp x0, ${0:A}", "S"(i32* @var) + call void asm sideeffect "add x0, x0, ${0:L}", "S"(i32* @var) +; CHECK: adrp x0, var +; CHECK: adrp x0, var +; CHECK: add x0, x0, #:lo12:var + ret void +} + +define i32 @test_inline_constraint_S_label(i1 %in) { +; CHECK: test_inline_constraint_S_label: + call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label, %loc)) +; CHECK: adr x0, .Ltmp{{[0-9]+}} + br i1 %in, label %loc, label %loc2 +loc: + ret i32 0 +loc2: + ret i32 42 +} + +define void @test_inline_constraint_Y() { +; CHECK: test_inline_constraint_Y: + call void asm sideeffect "fcmp s0, $0", "Y"(float 0.0) +; CHECK: fcmp s0, #0.0 + ret void +} + +define void @test_inline_constraint_Z() { +; CHECK: test_inline_constraint_Z: + call void asm sideeffect "cmp w0, $0", "Z"(i32 0) +; CHECK: cmp w0, #0 + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/inline-asm-modifiers.ll b/test/CodeGen/AArch64/inline-asm-modifiers.ll new file mode 100644 index 0000000000..3b55945561 --- /dev/null +++ b/test/CodeGen/AArch64/inline-asm-modifiers.ll @@ -0,0 +1,125 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-ELF %s + +@var_simple = hidden global i32 0 +@var_got = global i32 0 +@var_tlsgd = thread_local global i32 0 +@var_tlsld = thread_local(localdynamic) global i32 0 +@var_tlsie = thread_local(initialexec) global i32 0 +@var_tlsle = thread_local(localexec) global i32 0 + +define void @test_inline_modifier_L() nounwind { +; CHECK: test_inline_modifier_L: + call void asm sideeffect "add x0, x0, ${0:L}", "S,~{x0}"(i32* @var_simple) + call void asm sideeffect "ldr x0, [x0, ${0:L}]", "S,~{x0}"(i32* @var_got) + call void asm sideeffect "add x0, x0, ${0:L}", "S,~{x0}"(i32* @var_tlsgd) + call void asm sideeffect "add x0, x0, ${0:L}", "S,~{x0}"(i32* @var_tlsld) + call void asm sideeffect "ldr x0, [x0, ${0:L}]", "S,~{x0}"(i32* @var_tlsie) + call void asm sideeffect "add x0, x0, ${0:L}", "S,~{x0}"(i32* @var_tlsle) +; CHECK: add x0, x0, #:lo12:var_simple +; CHECK: ldr x0, [x0, #:got_lo12:var_got] +; CHECK: add x0, x0, #:tlsdesc_lo12:var_tlsgd +; CHECK: add x0, x0, #:dtprel_lo12:var_tlsld +; CHECK: ldr x0, [x0, #:gottprel_lo12:var_tlsie] +; CHECK: add x0, x0, #:tprel_lo12:var_tlsle + +; CHECK-ELF: R_AARCH64_ADD_ABS_LO12_NC var_simple +; CHECK-ELF: R_AARCH64_LD64_GOT_LO12_NC var_got +; CHECK-ELF: R_AARCH64_TLSDESC_ADD_LO12_NC var_tlsgd +; CHECK-ELF: R_AARCH64_TLSLD_ADD_DTPREL_LO12 var_tlsld +; CHECK-ELF: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC var_tlsie +; CHECK-ELF: R_AARCH64_TLSLE_ADD_TPREL_LO12 var_tlsle + + ret void +} + +define void @test_inline_modifier_G() nounwind { +; CHECK: test_inline_modifier_G: + call void asm sideeffect "add x0, x0, ${0:G}, lsl #12", "S,~{x0}"(i32* @var_tlsld) + call void asm sideeffect "add x0, x0, ${0:G}, lsl #12", "S,~{x0}"(i32* @var_tlsle) +; CHECK: add x0, x0, #:dtprel_hi12:var_tlsld, lsl #12 +; CHECK: add x0, x0, #:tprel_hi12:var_tlsle, lsl #12 + +; CHECK-ELF: R_AARCH64_TLSLD_ADD_DTPREL_HI12 var_tlsld +; CHECK-ELF: R_AARCH64_TLSLE_ADD_TPREL_HI12 var_tlsle + + ret void +} + +define void @test_inline_modifier_A() nounwind { +; CHECK: test_inline_modifier_A: + call void asm sideeffect "adrp x0, ${0:A}", "S,~{x0}"(i32* @var_simple) + call void asm sideeffect "adrp x0, ${0:A}", "S,~{x0}"(i32* @var_got) + call void asm sideeffect "adrp x0, ${0:A}", "S,~{x0}"(i32* @var_tlsgd) + call void asm sideeffect "adrp x0, ${0:A}", "S,~{x0}"(i32* @var_tlsie) + ; N.b. All tprel and dtprel relocs are modified: lo12 or granules. +; CHECK: adrp x0, var_simple +; CHECK: adrp x0, :got:var_got +; CHECK: adrp x0, :tlsdesc:var_tlsgd +; CHECK: adrp x0, :gottprel:var_tlsie + +; CHECK-ELF: R_AARCH64_ADR_PREL_PG_HI21 var_simple +; CHECK-ELF: R_AARCH64_ADR_GOT_PAGE var_got +; CHECK-ELF: R_AARCH64_TLSDESC_ADR_PAGE var_tlsgd +; CHECK-ELF: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 var_tlsie + + ret void +} + +define void @test_inline_modifier_wx(i32 %small, i64 %big) nounwind { +; CHECK: test_inline_modifier_wx: + call i32 asm sideeffect "add $0, $0, $0", "=r,0"(i32 %small) + call i32 asm sideeffect "add ${0:w}, ${0:w}, ${0:w}", "=r,0"(i32 %small) + call i32 asm sideeffect "add ${0:x}, ${0:x}, ${0:x}", "=r,0"(i32 %small) +; CHECK: //APP +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + + call i64 asm sideeffect "add $0, $0, $0", "=r,0"(i64 %big) + call i64 asm sideeffect "add ${0:w}, ${0:w}, ${0:w}", "=r,0"(i64 %big) + call i64 asm sideeffect "add ${0:x}, ${0:x}, ${0:x}", "=r,0"(i64 %big) +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + + call i32 asm sideeffect "add ${0:w}, ${1:w}, ${1:w}", "=r,r"(i32 0) + call i32 asm sideeffect "add ${0:x}, ${1:x}, ${1:x}", "=r,r"(i32 0) +; CHECK: add {{w[0-9]+}}, wzr, wzr +; CHECK: add {{x[0-9]+}}, xzr, xzr + ret void +} + +define void @test_inline_modifier_bhsdq() nounwind { +; CHECK: test_inline_modifier_bhsdq: + call float asm sideeffect "ldr ${0:b}, [sp]", "=w"() + call float asm sideeffect "ldr ${0:h}, [sp]", "=w"() + call float asm sideeffect "ldr ${0:s}, [sp]", "=w"() + call float asm sideeffect "ldr ${0:d}, [sp]", "=w"() + call float asm sideeffect "ldr ${0:q}, [sp]", "=w"() +; CHECK: ldr b0, [sp] +; CHECK: ldr h0, [sp] +; CHECK: ldr s0, [sp] +; CHECK: ldr d0, [sp] +; CHECK: ldr q0, [sp] + + call double asm sideeffect "ldr ${0:b}, [sp]", "=w"() + call double asm sideeffect "ldr ${0:h}, [sp]", "=w"() + call double asm sideeffect "ldr ${0:s}, [sp]", "=w"() + call double asm sideeffect "ldr ${0:d}, [sp]", "=w"() + call double asm sideeffect "ldr ${0:q}, [sp]", "=w"() +; CHECK: ldr b0, [sp] +; CHECK: ldr h0, [sp] +; CHECK: ldr s0, [sp] +; CHECK: ldr d0, [sp] +; CHECK: ldr q0, [sp] + ret void +} + +define void @test_inline_modifier_c() nounwind { +; CHECK: test_inline_modifier_c: + call void asm sideeffect "adr x0, ${0:c}", "i"(i32 3) +; CHECK: adr x0, 3 + + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/jump-table.ll b/test/CodeGen/AArch64/jump-table.ll new file mode 100644 index 0000000000..dcf9f4ed45 --- /dev/null +++ b/test/CodeGen/AArch64/jump-table.ll @@ -0,0 +1,56 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -filetype=obj | elf-dump | FileCheck %s -check-prefix=CHECK-ELF + +define i32 @test_jumptable(i32 %in) { +; CHECK: test_jumptable + + switch i32 %in, label %def [ + i32 0, label %lbl1 + i32 1, label %lbl2 + i32 2, label %lbl3 + i32 4, label %lbl4 + ] +; CHECK: adrp [[JTPAGE:x[0-9]+]], .LJTI0_0 +; CHECK: add x[[JT:[0-9]+]], [[JTPAGE]], #:lo12:.LJTI0_0 +; CHECK: ldr [[DEST:x[0-9]+]], [x[[JT]], {{x[0-9]+}}, lsl #3] +; CHECK: br [[DEST]] + +def: + ret i32 0 + +lbl1: + ret i32 1 + +lbl2: + ret i32 2 + +lbl3: + ret i32 4 + +lbl4: + ret i32 8 + +} + +; CHECK: .rodata + +; CHECK: .LJTI0_0: +; CHECK-NEXT: .xword +; CHECK-NEXT: .xword +; CHECK-NEXT: .xword +; CHECK-NEXT: .xword +; CHECK-NEXT: .xword + +; ELF tests: + +; First make sure we get a page/lo12 pair in .text to pick up the jump-table +; CHECK-ELF: .rela.text +; CHECK-ELF: ('r_sym', 0x00000008) +; CHECK-ELF-NEXT: ('r_type', 0x00000113) +; CHECK-ELF: ('r_sym', 0x00000008) +; CHECK-ELF-NEXT: ('r_type', 0x00000115) + +; Also check the targets in .rodata are relocated +; CHECK-ELF: .rela.rodata +; CHECK-ELF: ('r_sym', 0x00000005) +; CHECK-ELF-NEXT: ('r_type', 0x00000101)
\ No newline at end of file diff --git a/test/CodeGen/AArch64/large-frame.ll b/test/CodeGen/AArch64/large-frame.ll new file mode 100644 index 0000000000..2b2e1295c4 --- /dev/null +++ b/test/CodeGen/AArch64/large-frame.ll @@ -0,0 +1,114 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s +declare void @use_addr(i8*) + +@addr = global i8* null + +define void @test_bigframe() { +; CHECK: test_bigframe: + + %var1 = alloca i8, i32 20000000 + %var2 = alloca i8, i32 16 + %var3 = alloca i8, i32 20000000 +; CHECK: sub sp, sp, #496 +; CHECK: str x30, [sp, #488] + ; Total adjust is 39999536 +; CHECK: movz [[SUBCONST:x[0-9]+]], #22576 +; CHECK: movk [[SUBCONST]], #610, lsl #16 +; CHECK: sub sp, sp, [[SUBCONST]] + + ; Total offset is 20000024 +; CHECK: movz [[VAR1OFFSET:x[0-9]+]], #11544 +; CHECK: movk [[VAR1OFFSET]], #305, lsl #16 +; CHECK: add {{x[0-9]+}}, sp, [[VAR1OFFSET]] + store volatile i8* %var1, i8** @addr + + %var1plus2 = getelementptr i8* %var1, i32 2 + store volatile i8* %var1plus2, i8** @addr + +; CHECK: movz [[VAR2OFFSET:x[0-9]+]], #11528 +; CHECK: movk [[VAR2OFFSET]], #305, lsl #16 +; CHECK: add {{x[0-9]+}}, sp, [[VAR2OFFSET]] + store volatile i8* %var2, i8** @addr + + %var2plus2 = getelementptr i8* %var2, i32 2 + store volatile i8* %var2plus2, i8** @addr + + store volatile i8* %var3, i8** @addr + + %var3plus2 = getelementptr i8* %var3, i32 2 + store volatile i8* %var3plus2, i8** @addr + +; CHECK: movz [[ADDCONST:x[0-9]+]], #22576 +; CHECK: movk [[ADDCONST]], #610, lsl #16 +; CHECK: add sp, sp, [[ADDCONST]] + ret void +} + +define void @test_mediumframe() { +; CHECK: test_mediumframe: + %var1 = alloca i8, i32 1000000 + %var2 = alloca i8, i32 16 + %var3 = alloca i8, i32 1000000 +; CHECK: sub sp, sp, #496 +; CHECK: str x30, [sp, #488] +; CHECK: sub sp, sp, #688 +; CHECK-NEXT: sub sp, sp, #488, lsl #12 + + store volatile i8* %var1, i8** @addr +; CHECK: add [[VAR1ADDR:x[0-9]+]], sp, #600 +; CHECK: add [[VAR1ADDR]], [[VAR1ADDR]], #244, lsl #12 + + %var1plus2 = getelementptr i8* %var1, i32 2 + store volatile i8* %var1plus2, i8** @addr +; CHECK: add [[VAR1PLUS2:x[0-9]+]], {{x[0-9]+}}, #2 + + store volatile i8* %var2, i8** @addr +; CHECK: add [[VAR2ADDR:x[0-9]+]], sp, #584 +; CHECK: add [[VAR2ADDR]], [[VAR2ADDR]], #244, lsl #12 + + %var2plus2 = getelementptr i8* %var2, i32 2 + store volatile i8* %var2plus2, i8** @addr +; CHECK: add [[VAR2PLUS2:x[0-9]+]], {{x[0-9]+}}, #2 + + store volatile i8* %var3, i8** @addr + + %var3plus2 = getelementptr i8* %var3, i32 2 + store volatile i8* %var3plus2, i8** @addr + +; CHECK: add sp, sp, #688 +; CHECK: add sp, sp, #488, lsl #12 +; CHECK: ldr x30, [sp, #488] +; CHECK: add sp, sp, #496 + ret void +} + + +@bigspace = global [8 x i64] zeroinitializer + +; If temporary registers are allocated for adjustment, they should *not* clobber +; argument registers. +define void @test_tempallocation([8 x i64] %val) nounwind { +; CHECK: test_tempallocation: + %var = alloca i8, i32 1000000 +; CHECK: sub sp, sp, + +; Make sure the prologue is reasonably efficient +; CHECK-NEXT: stp x29, x30, [sp, +; CHECK-NEXT: stp x25, x26, [sp, +; CHECK-NEXT: stp x23, x24, [sp, +; CHECK-NEXT: stp x21, x22, [sp, +; CHECK-NEXT: stp x19, x20, [sp, + +; Make sure we don't trash an argument register +; CHECK-NOT: movz {{x[0-7],}} +; CHECK: sub sp, sp, + +; CHECK-NOT: movz {{x[0-7],}} + +; CHECK: bl use_addr + call void @use_addr(i8* %var) + + store [8 x i64] %val, [8 x i64]* @bigspace + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/ldst-regoffset.ll b/test/CodeGen/AArch64/ldst-regoffset.ll new file mode 100644 index 0000000000..45935129fd --- /dev/null +++ b/test/CodeGen/AArch64/ldst-regoffset.ll @@ -0,0 +1,333 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var_8bit = global i8 0 +@var_16bit = global i16 0 +@var_32bit = global i32 0 +@var_64bit = global i64 0 + +@var_float = global float 0.0 +@var_double = global double 0.0 + +define void @ldst_8bit(i8* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_8bit: + + %addr8_sxtw = getelementptr i8* %base, i32 %off32 + %val8_sxtw = load volatile i8* %addr8_sxtw + %val32_signed = sext i8 %val8_sxtw to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: ldrsb {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + %addr_lsl = getelementptr i8* %base, i64 %off64 + %val8_lsl = load volatile i8* %addr_lsl + %val32_unsigned = zext i8 %val8_lsl to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %addrint_uxtw = ptrtoint i8* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to i8* + %val8_uxtw = load volatile i8* %addr_uxtw + %newval8 = add i8 %val8_uxtw, 1 + store volatile i8 %newval8, i8* @var_8bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + ret void +} + + +define void @ldst_16bit(i16* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_16bit: + + %addr8_sxtwN = getelementptr i16* %base, i32 %off32 + %val8_sxtwN = load volatile i16* %addr8_sxtwN + %val32_signed = sext i16 %val8_sxtwN to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: ldrsh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #1] + + %addr_lslN = getelementptr i16* %base, i64 %off64 + %val8_lslN = load volatile i16* %addr_lslN + %val32_unsigned = zext i16 %val8_lslN to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #1] + + %addrint_uxtw = ptrtoint i16* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to i16* + %val8_uxtw = load volatile i16* %addr_uxtw + %newval8 = add i16 %val8_uxtw, 1 + store volatile i16 %newval8, i16* @var_16bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + %base_sxtw = ptrtoint i16* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to i16* + %val16_sxtw = load volatile i16* %addr_sxtw + %val64_signed = sext i16 %val16_sxtw to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldrsh {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + + %base_lsl = ptrtoint i16* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to i16* + %val16_lsl = load volatile i16* %addr_lsl + %val64_unsigned = zext i16 %val16_lsl to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint i16* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 1 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i16* + %val32 = load volatile i32* @var_32bit + %val16_trunc32 = trunc i32 %val32 to i16 + store volatile i16 %val16_trunc32, i16* %addr_uxtwN +; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #1] + ret void +} + +define void @ldst_32bit(i32* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_32bit: + + %addr_sxtwN = getelementptr i32* %base, i32 %off32 + %val_sxtwN = load volatile i32* %addr_sxtwN + store volatile i32 %val_sxtwN, i32* @var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #2] + + %addr_lslN = getelementptr i32* %base, i64 %off64 + %val_lslN = load volatile i32* %addr_lslN + store volatile i32 %val_lslN, i32* @var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2] + + %addrint_uxtw = ptrtoint i32* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to i32* + %val_uxtw = load volatile i32* %addr_uxtw + %newval8 = add i32 %val_uxtw, 1 + store volatile i32 %newval8, i32* @var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + + %base_sxtw = ptrtoint i32* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to i32* + %val16_sxtw = load volatile i32* %addr_sxtw + %val64_signed = sext i32 %val16_sxtw to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldrsw {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + + %base_lsl = ptrtoint i32* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to i32* + %val16_lsl = load volatile i32* %addr_lsl + %val64_unsigned = zext i32 %val16_lsl to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint i32* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 2 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i32* + %val32 = load volatile i32* @var_32bit + store volatile i32 %val32, i32* %addr_uxtwN +; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #2] + ret void +} + +define void @ldst_64bit(i64* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_64bit: + + %addr_sxtwN = getelementptr i64* %base, i32 %off32 + %val_sxtwN = load volatile i64* %addr_sxtwN + store volatile i64 %val_sxtwN, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #3] + + %addr_lslN = getelementptr i64* %base, i64 %off64 + %val_lslN = load volatile i64* %addr_lslN + store volatile i64 %val_lslN, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3] + + %addrint_uxtw = ptrtoint i64* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to i64* + %val8_uxtw = load volatile i64* %addr_uxtw + %newval8 = add i64 %val8_uxtw, 1 + store volatile i64 %newval8, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + %base_sxtw = ptrtoint i64* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to i64* + %val64_sxtw = load volatile i64* %addr_sxtw + store volatile i64 %val64_sxtw, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + %base_lsl = ptrtoint i64* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to i64* + %val64_lsl = load volatile i64* %addr_lsl + store volatile i64 %val64_lsl, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint i64* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 3 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i64* + %val64 = load volatile i64* @var_64bit + store volatile i64 %val64, i64* %addr_uxtwN +; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #3] + ret void +} + +define void @ldst_float(float* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_float: + + %addr_sxtwN = getelementptr float* %base, i32 %off32 + %val_sxtwN = load volatile float* %addr_sxtwN + store volatile float %val_sxtwN, float* @var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #2] + + %addr_lslN = getelementptr float* %base, i64 %off64 + %val_lslN = load volatile float* %addr_lslN + store volatile float %val_lslN, float* @var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2] + + %addrint_uxtw = ptrtoint float* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to float* + %val_uxtw = load volatile float* %addr_uxtw + store volatile float %val_uxtw, float* @var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + %base_sxtw = ptrtoint float* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to float* + %val64_sxtw = load volatile float* %addr_sxtw + store volatile float %val64_sxtw, float* @var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + %base_lsl = ptrtoint float* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to float* + %val64_lsl = load volatile float* %addr_lsl + store volatile float %val64_lsl, float* @var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint float* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 2 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to float* + %val64 = load volatile float* @var_float + store volatile float %val64, float* %addr_uxtwN +; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #2] + ret void +} + +define void @ldst_double(double* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_double: + + %addr_sxtwN = getelementptr double* %base, i32 %off32 + %val_sxtwN = load volatile double* %addr_sxtwN + store volatile double %val_sxtwN, double* @var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #3] + + %addr_lslN = getelementptr double* %base, i64 %off64 + %val_lslN = load volatile double* %addr_lslN + store volatile double %val_lslN, double* @var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3] + + %addrint_uxtw = ptrtoint double* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to double* + %val_uxtw = load volatile double* %addr_uxtw + store volatile double %val_uxtw, double* @var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + %base_sxtw = ptrtoint double* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to double* + %val64_sxtw = load volatile double* %addr_sxtw + store volatile double %val64_sxtw, double* @var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + %base_lsl = ptrtoint double* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to double* + %val64_lsl = load volatile double* %addr_lsl + store volatile double %val64_lsl, double* @var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint double* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 3 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to double* + %val64 = load volatile double* @var_double + store volatile double %val64, double* %addr_uxtwN +; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #3] + ret void +} + + +define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) { +; CHECK: ldst_128bit: + + %addr_sxtwN = getelementptr fp128* %base, i32 %off32 + %val_sxtwN = load volatile fp128* %addr_sxtwN + store volatile fp128 %val_sxtwN, fp128* %base +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4] + + %addr_lslN = getelementptr fp128* %base, i64 %off64 + %val_lslN = load volatile fp128* %addr_lslN + store volatile fp128 %val_lslN, fp128* %base +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #4] + + %addrint_uxtw = ptrtoint fp128* %base to i64 + %offset_uxtw = zext i32 %off32 to i64 + %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw + %addr_uxtw = inttoptr i64 %addrint1_uxtw to fp128* + %val_uxtw = load volatile fp128* %addr_uxtw + store volatile fp128 %val_uxtw, fp128* %base +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw] + + %base_sxtw = ptrtoint fp128* %base to i64 + %offset_sxtw = sext i32 %off32 to i64 + %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw + %addr_sxtw = inttoptr i64 %addrint_sxtw to fp128* + %val64_sxtw = load volatile fp128* %addr_sxtw + store volatile fp128 %val64_sxtw, fp128* %base +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw] + + %base_lsl = ptrtoint fp128* %base to i64 + %addrint_lsl = add i64 %base_lsl, %off64 + %addr_lsl = inttoptr i64 %addrint_lsl to fp128* + %val64_lsl = load volatile fp128* %addr_lsl + store volatile fp128 %val64_lsl, fp128* %base +; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}] + + %base_uxtwN = ptrtoint fp128* %base to i64 + %offset_uxtwN = zext i32 %off32 to i64 + %offset2_uxtwN = shl i64 %offset_uxtwN, 4 + %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN + %addr_uxtwN = inttoptr i64 %addrint_uxtwN to fp128* + %val64 = load volatile fp128* %base + store volatile fp128 %val64, fp128* %addr_uxtwN +; CHECK: str {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #4] + ret void +} diff --git a/test/CodeGen/AArch64/ldst-unscaledimm.ll b/test/CodeGen/AArch64/ldst-unscaledimm.ll new file mode 100644 index 0000000000..78a3c83c3d --- /dev/null +++ b/test/CodeGen/AArch64/ldst-unscaledimm.ll @@ -0,0 +1,218 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var_8bit = global i8 0 +@var_16bit = global i16 0 +@var_32bit = global i32 0 +@var_64bit = global i64 0 + +@var_float = global float 0.0 +@var_double = global double 0.0 + +@varptr = global i8* null + +define void @ldst_8bit() { +; CHECK: ldst_8bit: + +; No architectural support for loads to 16-bit or 8-bit since we +; promote i8 during lowering. + %addr_8bit = load i8** @varptr + +; match a sign-extending load 8-bit -> 32-bit + %addr_sext32 = getelementptr i8* %addr_8bit, i64 -256 + %val8_sext32 = load volatile i8* %addr_sext32 + %val32_signed = sext i8 %val8_sext32 to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: ldursb {{w[0-9]+}}, [{{x[0-9]+}}, #-256] + +; match a zero-extending load volatile 8-bit -> 32-bit + %addr_zext32 = getelementptr i8* %addr_8bit, i64 -12 + %val8_zext32 = load volatile i8* %addr_zext32 + %val32_unsigned = zext i8 %val8_zext32 to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-12] + +; match an any-extending load volatile 8-bit -> 32-bit + %addr_anyext = getelementptr i8* %addr_8bit, i64 -1 + %val8_anyext = load volatile i8* %addr_anyext + %newval8 = add i8 %val8_anyext, 1 + store volatile i8 %newval8, i8* @var_8bit +; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-1] + +; match a sign-extending load volatile 8-bit -> 64-bit + %addr_sext64 = getelementptr i8* %addr_8bit, i64 -5 + %val8_sext64 = load volatile i8* %addr_sext64 + %val64_signed = sext i8 %val8_sext64 to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldursb {{x[0-9]+}}, [{{x[0-9]+}}, #-5] + +; match a zero-extending load volatile 8-bit -> 64-bit. +; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits +; of x0 so it's identical to load volatileing to 32-bits. + %addr_zext64 = getelementptr i8* %addr_8bit, i64 -9 + %val8_zext64 = load volatile i8* %addr_zext64 + %val64_unsigned = zext i8 %val8_zext64 to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldurb {{w[0-9]+}}, [{{x[0-9]+}}, #-9] + +; truncating store volatile 32-bits to 8-bits + %addr_trunc32 = getelementptr i8* %addr_8bit, i64 -256 + %val32 = load volatile i32* @var_32bit + %val8_trunc32 = trunc i32 %val32 to i8 + store volatile i8 %val8_trunc32, i8* %addr_trunc32 +; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-256] + +; truncating store volatile 64-bits to 8-bits + %addr_trunc64 = getelementptr i8* %addr_8bit, i64 -1 + %val64 = load volatile i64* @var_64bit + %val8_trunc64 = trunc i64 %val64 to i8 + store volatile i8 %val8_trunc64, i8* %addr_trunc64 +; CHECK: sturb {{w[0-9]+}}, [{{x[0-9]+}}, #-1] + + ret void +} + +define void @ldst_16bit() { +; CHECK: ldst_16bit: + +; No architectural support for loads to 16-bit or 16-bit since we +; promote i16 during lowering. + %addr_8bit = load i8** @varptr + +; match a sign-extending load 16-bit -> 32-bit + %addr8_sext32 = getelementptr i8* %addr_8bit, i64 -256 + %addr_sext32 = bitcast i8* %addr8_sext32 to i16* + %val16_sext32 = load volatile i16* %addr_sext32 + %val32_signed = sext i16 %val16_sext32 to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: ldursh {{w[0-9]+}}, [{{x[0-9]+}}, #-256] + +; match a zero-extending load volatile 16-bit -> 32-bit. With offset that would be unaligned. + %addr8_zext32 = getelementptr i8* %addr_8bit, i64 15 + %addr_zext32 = bitcast i8* %addr8_zext32 to i16* + %val16_zext32 = load volatile i16* %addr_zext32 + %val32_unsigned = zext i16 %val16_zext32 to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #15] + +; match an any-extending load volatile 16-bit -> 32-bit + %addr8_anyext = getelementptr i8* %addr_8bit, i64 -1 + %addr_anyext = bitcast i8* %addr8_anyext to i16* + %val16_anyext = load volatile i16* %addr_anyext + %newval16 = add i16 %val16_anyext, 1 + store volatile i16 %newval16, i16* @var_16bit +; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #-1] + +; match a sign-extending load volatile 16-bit -> 64-bit + %addr8_sext64 = getelementptr i8* %addr_8bit, i64 -5 + %addr_sext64 = bitcast i8* %addr8_sext64 to i16* + %val16_sext64 = load volatile i16* %addr_sext64 + %val64_signed = sext i16 %val16_sext64 to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldursh {{x[0-9]+}}, [{{x[0-9]+}}, #-5] + +; match a zero-extending load volatile 16-bit -> 64-bit. +; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits +; of x0 so it's identical to load volatileing to 32-bits. + %addr8_zext64 = getelementptr i8* %addr_8bit, i64 9 + %addr_zext64 = bitcast i8* %addr8_zext64 to i16* + %val16_zext64 = load volatile i16* %addr_zext64 + %val64_unsigned = zext i16 %val16_zext64 to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldurh {{w[0-9]+}}, [{{x[0-9]+}}, #9] + +; truncating store volatile 32-bits to 16-bits + %addr8_trunc32 = getelementptr i8* %addr_8bit, i64 -256 + %addr_trunc32 = bitcast i8* %addr8_trunc32 to i16* + %val32 = load volatile i32* @var_32bit + %val16_trunc32 = trunc i32 %val32 to i16 + store volatile i16 %val16_trunc32, i16* %addr_trunc32 +; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-256] + +; truncating store volatile 64-bits to 16-bits + %addr8_trunc64 = getelementptr i8* %addr_8bit, i64 -1 + %addr_trunc64 = bitcast i8* %addr8_trunc64 to i16* + %val64 = load volatile i64* @var_64bit + %val16_trunc64 = trunc i64 %val64 to i16 + store volatile i16 %val16_trunc64, i16* %addr_trunc64 +; CHECK: sturh {{w[0-9]+}}, [{{x[0-9]+}}, #-1] + + ret void +} + +define void @ldst_32bit() { +; CHECK: ldst_32bit: + + %addr_8bit = load i8** @varptr + +; Straight 32-bit load/store + %addr32_8_noext = getelementptr i8* %addr_8bit, i64 1 + %addr32_noext = bitcast i8* %addr32_8_noext to i32* + %val32_noext = load volatile i32* %addr32_noext + store volatile i32 %val32_noext, i32* %addr32_noext +; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #1] +; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #1] + +; Zero-extension to 64-bits + %addr32_8_zext = getelementptr i8* %addr_8bit, i64 -256 + %addr32_zext = bitcast i8* %addr32_8_zext to i32* + %val32_zext = load volatile i32* %addr32_zext + %val64_unsigned = zext i32 %val32_zext to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldur {{w[0-9]+}}, [{{x[0-9]+}}, #-256] +; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_64bit] + +; Sign-extension to 64-bits + %addr32_8_sext = getelementptr i8* %addr_8bit, i64 -12 + %addr32_sext = bitcast i8* %addr32_8_sext to i32* + %val32_sext = load volatile i32* %addr32_sext + %val64_signed = sext i32 %val32_sext to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldursw {{x[0-9]+}}, [{{x[0-9]+}}, #-12] +; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_64bit] + +; Truncation from 64-bits + %addr64_8_trunc = getelementptr i8* %addr_8bit, i64 255 + %addr64_trunc = bitcast i8* %addr64_8_trunc to i64* + %addr32_8_trunc = getelementptr i8* %addr_8bit, i64 -20 + %addr32_trunc = bitcast i8* %addr32_8_trunc to i32* + + %val64_trunc = load volatile i64* %addr64_trunc + %val32_trunc = trunc i64 %val64_trunc to i32 + store volatile i32 %val32_trunc, i32* %addr32_trunc +; CHECK: ldur {{x[0-9]+}}, [{{x[0-9]+}}, #255] +; CHECK: stur {{w[0-9]+}}, [{{x[0-9]+}}, #-20] + + ret void +} + +define void @ldst_float() { +; CHECK: ldst_float: + + %addr_8bit = load i8** @varptr + %addrfp_8 = getelementptr i8* %addr_8bit, i64 -5 + %addrfp = bitcast i8* %addrfp_8 to float* + + %valfp = load volatile float* %addrfp +; CHECK: ldur {{s[0-9]+}}, [{{x[0-9]+}}, #-5] + + store volatile float %valfp, float* %addrfp +; CHECK: stur {{s[0-9]+}}, [{{x[0-9]+}}, #-5] + + ret void +} + +define void @ldst_double() { +; CHECK: ldst_double: + + %addr_8bit = load i8** @varptr + %addrfp_8 = getelementptr i8* %addr_8bit, i64 4 + %addrfp = bitcast i8* %addrfp_8 to double* + + %valfp = load volatile double* %addrfp +; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #4] + + store volatile double %valfp, double* %addrfp +; CHECK: stur {{d[0-9]+}}, [{{x[0-9]+}}, #4] + + ret void +} diff --git a/test/CodeGen/AArch64/ldst-unsignedimm.ll b/test/CodeGen/AArch64/ldst-unsignedimm.ll new file mode 100644 index 0000000000..1e7540d9be --- /dev/null +++ b/test/CodeGen/AArch64/ldst-unsignedimm.ll @@ -0,0 +1,251 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var_8bit = global i8 0 +@var_16bit = global i16 0 +@var_32bit = global i32 0 +@var_64bit = global i64 0 + +@var_float = global float 0.0 +@var_double = global double 0.0 + +define void @ldst_8bit() { +; CHECK: ldst_8bit: + +; No architectural support for loads to 16-bit or 8-bit since we +; promote i8 during lowering. + +; match a sign-extending load 8-bit -> 32-bit + %val8_sext32 = load volatile i8* @var_8bit + %val32_signed = sext i8 %val8_sext32 to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: adrp {{x[0-9]+}}, var_8bit +; CHECK: ldrsb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; match a zero-extending load volatile 8-bit -> 32-bit + %val8_zext32 = load volatile i8* @var_8bit + %val32_unsigned = zext i8 %val8_zext32 to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; match an any-extending load volatile 8-bit -> 32-bit + %val8_anyext = load volatile i8* @var_8bit + %newval8 = add i8 %val8_anyext, 1 + store volatile i8 %newval8, i8* @var_8bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; match a sign-extending load volatile 8-bit -> 64-bit + %val8_sext64 = load volatile i8* @var_8bit + %val64_signed = sext i8 %val8_sext64 to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldrsb {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; match a zero-extending load volatile 8-bit -> 64-bit. +; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits +; of x0 so it's identical to load volatileing to 32-bits. + %val8_zext64 = load volatile i8* @var_8bit + %val64_unsigned = zext i8 %val8_zext64 to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; truncating store volatile 32-bits to 8-bits + %val32 = load volatile i32* @var_32bit + %val8_trunc32 = trunc i32 %val32 to i8 + store volatile i8 %val8_trunc32, i8* @var_8bit +; CHECK: strb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + +; truncating store volatile 64-bits to 8-bits + %val64 = load volatile i64* @var_64bit + %val8_trunc64 = trunc i64 %val64 to i8 + store volatile i8 %val8_trunc64, i8* @var_8bit +; CHECK: strb {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_8bit] + + ret void +} + +define void @ldst_16bit() { +; CHECK: ldst_16bit: + +; No architectural support for load volatiles to 16-bit promote i16 during +; lowering. + +; match a sign-extending load volatile 16-bit -> 32-bit + %val16_sext32 = load volatile i16* @var_16bit + %val32_signed = sext i16 %val16_sext32 to i32 + store volatile i32 %val32_signed, i32* @var_32bit +; CHECK: adrp {{x[0-9]+}}, var_16bit +; CHECK: ldrsh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; match a zero-extending load volatile 16-bit -> 32-bit + %val16_zext32 = load volatile i16* @var_16bit + %val32_unsigned = zext i16 %val16_zext32 to i32 + store volatile i32 %val32_unsigned, i32* @var_32bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; match an any-extending load volatile 16-bit -> 32-bit + %val16_anyext = load volatile i16* @var_16bit + %newval16 = add i16 %val16_anyext, 1 + store volatile i16 %newval16, i16* @var_16bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; match a sign-extending load volatile 16-bit -> 64-bit + %val16_sext64 = load volatile i16* @var_16bit + %val64_signed = sext i16 %val16_sext64 to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldrsh {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; match a zero-extending load volatile 16-bit -> 64-bit. +; This uses the fact that ldrb w0, [x0] will zero out the high 32-bits +; of x0 so it's identical to load volatileing to 32-bits. + %val16_zext64 = load volatile i16* @var_16bit + %val64_unsigned = zext i16 %val16_zext64 to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; truncating store volatile 32-bits to 16-bits + %val32 = load volatile i32* @var_32bit + %val16_trunc32 = trunc i32 %val32 to i16 + store volatile i16 %val16_trunc32, i16* @var_16bit +; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + +; truncating store volatile 64-bits to 16-bits + %val64 = load volatile i64* @var_64bit + %val16_trunc64 = trunc i64 %val64 to i16 + store volatile i16 %val16_trunc64, i16* @var_16bit +; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_16bit] + + ret void +} + +define void @ldst_32bit() { +; CHECK: ldst_32bit: + +; Straight 32-bit load/store + %val32_noext = load volatile i32* @var_32bit + store volatile i32 %val32_noext, i32* @var_32bit +; CHECK: adrp {{x[0-9]+}}, var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_32bit] +; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_32bit] + +; Zero-extension to 64-bits + %val32_zext = load volatile i32* @var_32bit + %val64_unsigned = zext i32 %val32_zext to i64 + store volatile i64 %val64_unsigned, i64* @var_64bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_32bit] +; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_64bit] + +; Sign-extension to 64-bits + %val32_sext = load volatile i32* @var_32bit + %val64_signed = sext i32 %val32_sext to i64 + store volatile i64 %val64_signed, i64* @var_64bit +; CHECK: ldrsw {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_32bit] +; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_64bit] + +; Truncation from 64-bits + %val64_trunc = load volatile i64* @var_64bit + %val32_trunc = trunc i64 %val64_trunc to i32 + store volatile i32 %val32_trunc, i32* @var_32bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_64bit] +; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_32bit] + + ret void +} + +@arr8 = global i8* null +@arr16 = global i16* null +@arr32 = global i32* null +@arr64 = global i64* null + +; Now check that our selection copes with accesses more complex than a +; single symbol. Permitted offsets should be folded into the loads and +; stores. Since all forms use the same Operand it's only necessary to +; check the various access-sizes involved. + +define void @ldst_complex_offsets() { +; CHECK: ldst_complex_offsets + %arr8_addr = load volatile i8** @arr8 +; CHECK: adrp {{x[0-9]+}}, arr8 +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:arr8] + + %arr8_sub1_addr = getelementptr i8* %arr8_addr, i64 1 + %arr8_sub1 = load volatile i8* %arr8_sub1_addr + store volatile i8 %arr8_sub1, i8* @var_8bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #1] + + %arr8_sub4095_addr = getelementptr i8* %arr8_addr, i64 4095 + %arr8_sub4095 = load volatile i8* %arr8_sub4095_addr + store volatile i8 %arr8_sub4095, i8* @var_8bit +; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, #4095] + + + %arr16_addr = load volatile i16** @arr16 +; CHECK: adrp {{x[0-9]+}}, arr16 +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:arr16] + + %arr16_sub1_addr = getelementptr i16* %arr16_addr, i64 1 + %arr16_sub1 = load volatile i16* %arr16_sub1_addr + store volatile i16 %arr16_sub1, i16* @var_16bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, #2] + + %arr16_sub4095_addr = getelementptr i16* %arr16_addr, i64 4095 + %arr16_sub4095 = load volatile i16* %arr16_sub4095_addr + store volatile i16 %arr16_sub4095, i16* @var_16bit +; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, #8190] + + + %arr32_addr = load volatile i32** @arr32 +; CHECK: adrp {{x[0-9]+}}, arr32 +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:arr32] + + %arr32_sub1_addr = getelementptr i32* %arr32_addr, i64 1 + %arr32_sub1 = load volatile i32* %arr32_sub1_addr + store volatile i32 %arr32_sub1, i32* @var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, #4] + + %arr32_sub4095_addr = getelementptr i32* %arr32_addr, i64 4095 + %arr32_sub4095 = load volatile i32* %arr32_sub4095_addr + store volatile i32 %arr32_sub4095, i32* @var_32bit +; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, #16380] + + + %arr64_addr = load volatile i64** @arr64 +; CHECK: adrp {{x[0-9]+}}, arr64 +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #:lo12:arr64] + + %arr64_sub1_addr = getelementptr i64* %arr64_addr, i64 1 + %arr64_sub1 = load volatile i64* %arr64_sub1_addr + store volatile i64 %arr64_sub1, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #8] + + %arr64_sub4095_addr = getelementptr i64* %arr64_addr, i64 4095 + %arr64_sub4095 = load volatile i64* %arr64_sub4095_addr + store volatile i64 %arr64_sub4095, i64* @var_64bit +; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, #32760] + + ret void +} + +define void @ldst_float() { +; CHECK: ldst_float: + + %valfp = load volatile float* @var_float +; CHECK: adrp {{x[0-9]+}}, var_float +; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_float] + + store volatile float %valfp, float* @var_float +; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_float] + + ret void +} + +define void @ldst_double() { +; CHECK: ldst_double: + + %valfp = load volatile double* @var_double +; CHECK: adrp {{x[0-9]+}}, var_double +; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_double] + + store volatile double %valfp, double* @var_double +; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_double] + + ret void +} diff --git a/test/CodeGen/AArch64/lit.local.cfg b/test/CodeGen/AArch64/lit.local.cfg new file mode 100644 index 0000000000..c5ce2411ed --- /dev/null +++ b/test/CodeGen/AArch64/lit.local.cfg @@ -0,0 +1,6 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'AArch64' in targets: + config.unsupported = True + diff --git a/test/CodeGen/AArch64/literal_pools.ll b/test/CodeGen/AArch64/literal_pools.ll new file mode 100644 index 0000000000..e09084148f --- /dev/null +++ b/test/CodeGen/AArch64/literal_pools.ll @@ -0,0 +1,55 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @foo() { +; CHECK: foo: + %val32 = load i32* @var32 + %val64 = load i64* @var64 + + %val32_lit32 = and i32 %val32, 123456785 + store volatile i32 %val32_lit32, i32* @var32 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]] +; CHECK: ldr {{w[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] + + %val64_lit32 = and i64 %val64, 305402420 + store volatile i64 %val64_lit32, i64* @var64 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]] +; CHECK: ldr {{w[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] + + %val64_lit32signed = and i64 %val64, -12345678 + store volatile i64 %val64_lit32signed, i64* @var64 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]] +; CHECK: ldrsw {{x[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] + + %val64_lit64 = and i64 %val64, 1234567898765432 + store volatile i64 %val64_lit64, i64* @var64 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]] +; CHECK: ldr {{x[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] + + ret void +} + +@varfloat = global float 0.0 +@vardouble = global double 0.0 + +define void @floating_lits() { +; CHECK: floating_lits: + + %floatval = load float* @varfloat + %newfloat = fadd float %floatval, 128.0 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI1_[0-9]+]] +; CHECK: ldr {{s[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] +; CHECK: fadd + store float %newfloat, float* @varfloat + + %doubleval = load double* @vardouble + %newdouble = fadd double %doubleval, 129.0 +; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI1_[0-9]+]] +; CHECK: ldr {{d[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]] +; CHECK: fadd + store double %newdouble, double* @vardouble + + ret void +} diff --git a/test/CodeGen/AArch64/local_vars.ll b/test/CodeGen/AArch64/local_vars.ll new file mode 100644 index 0000000000..5cbf5a37ec --- /dev/null +++ b/test/CodeGen/AArch64/local_vars.ll @@ -0,0 +1,57 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -O0 | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -O0 -disable-fp-elim | FileCheck -check-prefix CHECK-WITHFP %s + +; Make sure a reasonably sane prologue and epilogue are +; generated. This test is not robust in the face of an frame-handling +; evolving, but still has value for unrelated changes, I +; believe. +; +; In particular, it will fail when ldp/stp are used for frame setup, +; when FP-elim is implemented, and when addressing from FP is +; implemented. + +@var = global i64 0 +@local_addr = global i64* null + +declare void @foo() + +define void @trivial_func() nounwind { +; CHECK: trivial_func: // @trivial_func +; CHECK-NEXT: // BB#0 +; CHECK-NEXT: ret + + ret void +} + +define void @trivial_fp_func() { +; CHECK-WITHFP: trivial_fp_func: + +; CHECK-WITHFP: sub sp, sp, #16 +; CHECK-WITHFP: stp x29, x30, [sp] +; CHECK-WITHFP-NEXT: mov x29, sp + +; Dont't really care, but it would be a Bad Thing if this came after the epilogue. +; CHECK: bl foo + call void @foo() + ret void + +; CHECK-WITHFP: ldp x29, x30, [sp] +; CHECK-WITHFP: add sp, sp, #16 + +; CHECK-WITHFP: ret +} + +define void @stack_local() { + %local_var = alloca i64 +; CHECK: stack_local: +; CHECK: sub sp, sp, #16 + + %val = load i64* @var + store i64 %val, i64* %local_var +; CHECK: str {{x[0-9]+}}, [sp, #{{[0-9]+}}] + + store i64* %local_var, i64** @local_addr +; CHECK: add {{x[0-9]+}}, sp, #{{[0-9]+}} + + ret void +} diff --git a/test/CodeGen/AArch64/logical-imm.ll b/test/CodeGen/AArch64/logical-imm.ll new file mode 100644 index 0000000000..5f3f4da0cd --- /dev/null +++ b/test/CodeGen/AArch64/logical-imm.ll @@ -0,0 +1,84 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_and(i32 %in32, i64 %in64) { +; CHECK: test_and: + + %val0 = and i32 %in32, 2863311530 + store volatile i32 %val0, i32* @var32 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xaaaaaaaa + + %val1 = and i32 %in32, 4293984240 + store volatile i32 %val1, i32* @var32 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0fff0 + + %val2 = and i64 %in64, 9331882296111890817 + store volatile i64 %val2, i64* @var64 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0x8181818181818181 + + %val3 = and i64 %in64, 18429855317404942275 + store volatile i64 %val3, i64* @var64 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffc3ffc3ffc3ffc3 + + ret void +} + +define void @test_orr(i32 %in32, i64 %in64) { +; CHECK: test_orr: + + %val0 = or i32 %in32, 2863311530 + store volatile i32 %val0, i32* @var32 +; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, #0xaaaaaaaa + + %val1 = or i32 %in32, 4293984240 + store volatile i32 %val1, i32* @var32 +; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0fff0 + + %val2 = or i64 %in64, 9331882296111890817 + store volatile i64 %val2, i64* @var64 +; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0x8181818181818181 + + %val3 = or i64 %in64, 18429855317404942275 + store volatile i64 %val3, i64* @var64 +; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0xffc3ffc3ffc3ffc3 + + ret void +} + +define void @test_eor(i32 %in32, i64 %in64) { +; CHECK: test_eor: + + %val0 = xor i32 %in32, 2863311530 + store volatile i32 %val0, i32* @var32 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, #0xaaaaaaaa + + %val1 = xor i32 %in32, 4293984240 + store volatile i32 %val1, i32* @var32 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0fff0 + + %val2 = xor i64 %in64, 9331882296111890817 + store volatile i64 %val2, i64* @var64 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, #0x8181818181818181 + + %val3 = xor i64 %in64, 18429855317404942275 + store volatile i64 %val3, i64* @var64 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, #0xffc3ffc3ffc3ffc3 + + ret void +} + +define void @test_mov(i32 %in32, i64 %in64) { +; CHECK: test_mov: + %val0 = add i32 %in32, 2863311530 + store i32 %val0, i32* @var32 +; CHECK: orr {{w[0-9]+}}, wzr, #0xaaaaaaaa + + %val1 = add i64 %in64, 11068046444225730969 + store i64 %val1, i64* @var64 +; CHECK: orr {{x[0-9]+}}, xzr, #0x9999999999999999 + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/logical_shifted_reg.ll b/test/CodeGen/AArch64/logical_shifted_reg.ll new file mode 100644 index 0000000000..bbbfcc1b91 --- /dev/null +++ b/test/CodeGen/AArch64/logical_shifted_reg.ll @@ -0,0 +1,224 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -O0 | FileCheck %s + +@var1_32 = global i32 0 +@var2_32 = global i32 0 + +@var1_64 = global i64 0 +@var2_64 = global i64 0 + +define void @logical_32bit() { +; CHECK: logical_32bit: + %val1 = load i32* @var1_32 + %val2 = load i32* @var2_32 + + ; First check basic and/bic/or/orn/eor/eon patterns with no shift + %neg_val2 = xor i32 -1, %val2 + + %and_noshift = and i32 %val1, %val2 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %and_noshift, i32* @var1_32 + %bic_noshift = and i32 %neg_val2, %val1 +; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %bic_noshift, i32* @var1_32 + + %or_noshift = or i32 %val1, %val2 +; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %or_noshift, i32* @var1_32 + %orn_noshift = or i32 %neg_val2, %val1 +; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %orn_noshift, i32* @var1_32 + + %xor_noshift = xor i32 %val1, %val2 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %xor_noshift, i32* @var1_32 + %xorn_noshift = xor i32 %neg_val2, %val1 +; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}} + store volatile i32 %xorn_noshift, i32* @var1_32 + + ; Check the maximum shift on each + %operand_lsl31 = shl i32 %val2, 31 + %neg_operand_lsl31 = xor i32 -1, %operand_lsl31 + + %and_lsl31 = and i32 %val1, %operand_lsl31 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %and_lsl31, i32* @var1_32 + %bic_lsl31 = and i32 %val1, %neg_operand_lsl31 +; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %bic_lsl31, i32* @var1_32 + + %or_lsl31 = or i32 %val1, %operand_lsl31 +; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %or_lsl31, i32* @var1_32 + %orn_lsl31 = or i32 %val1, %neg_operand_lsl31 +; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %orn_lsl31, i32* @var1_32 + + %xor_lsl31 = xor i32 %val1, %operand_lsl31 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %xor_lsl31, i32* @var1_32 + %xorn_lsl31 = xor i32 %val1, %neg_operand_lsl31 +; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31 + store volatile i32 %xorn_lsl31, i32* @var1_32 + + ; Check other shifts on a subset + %operand_asr10 = ashr i32 %val2, 10 + %neg_operand_asr10 = xor i32 -1, %operand_asr10 + + %bic_asr10 = and i32 %val1, %neg_operand_asr10 +; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #10 + store volatile i32 %bic_asr10, i32* @var1_32 + %xor_asr10 = xor i32 %val1, %operand_asr10 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #10 + store volatile i32 %xor_asr10, i32* @var1_32 + + %operand_lsr1 = lshr i32 %val2, 1 + %neg_operand_lsr1 = xor i32 -1, %operand_lsr1 + + %orn_lsr1 = or i32 %val1, %neg_operand_lsr1 +; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #1 + store volatile i32 %orn_lsr1, i32* @var1_32 + %xor_lsr1 = xor i32 %val1, %operand_lsr1 +; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #1 + store volatile i32 %xor_lsr1, i32* @var1_32 + + %operand_ror20_big = shl i32 %val2, 12 + %operand_ror20_small = lshr i32 %val2, 20 + %operand_ror20 = or i32 %operand_ror20_big, %operand_ror20_small + %neg_operand_ror20 = xor i32 -1, %operand_ror20 + + %xorn_ror20 = xor i32 %val1, %neg_operand_ror20 +; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ror #20 + store volatile i32 %xorn_ror20, i32* @var1_32 + %and_ror20 = and i32 %val1, %operand_ror20 +; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ror #20 + store volatile i32 %and_ror20, i32* @var1_32 + + ret void +} + +define void @logical_64bit() { +; CHECK: logical_64bit: + %val1 = load i64* @var1_64 + %val2 = load i64* @var2_64 + + ; First check basic and/bic/or/orn/eor/eon patterns with no shift + %neg_val2 = xor i64 -1, %val2 + + %and_noshift = and i64 %val1, %val2 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %and_noshift, i64* @var1_64 + %bic_noshift = and i64 %neg_val2, %val1 +; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %bic_noshift, i64* @var1_64 + + %or_noshift = or i64 %val1, %val2 +; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %or_noshift, i64* @var1_64 + %orn_noshift = or i64 %neg_val2, %val1 +; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %orn_noshift, i64* @var1_64 + + %xor_noshift = xor i64 %val1, %val2 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %xor_noshift, i64* @var1_64 + %xorn_noshift = xor i64 %neg_val2, %val1 +; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}} + store volatile i64 %xorn_noshift, i64* @var1_64 + + ; Check the maximum shift on each + %operand_lsl63 = shl i64 %val2, 63 + %neg_operand_lsl63 = xor i64 -1, %operand_lsl63 + + %and_lsl63 = and i64 %val1, %operand_lsl63 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %and_lsl63, i64* @var1_64 + %bic_lsl63 = and i64 %val1, %neg_operand_lsl63 +; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %bic_lsl63, i64* @var1_64 + + %or_lsl63 = or i64 %val1, %operand_lsl63 +; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %or_lsl63, i64* @var1_64 + %orn_lsl63 = or i64 %val1, %neg_operand_lsl63 +; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %orn_lsl63, i64* @var1_64 + + %xor_lsl63 = xor i64 %val1, %operand_lsl63 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %xor_lsl63, i64* @var1_64 + %xorn_lsl63 = xor i64 %val1, %neg_operand_lsl63 +; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 + store volatile i64 %xorn_lsl63, i64* @var1_64 + + ; Check other shifts on a subset + %operand_asr10 = ashr i64 %val2, 10 + %neg_operand_asr10 = xor i64 -1, %operand_asr10 + + %bic_asr10 = and i64 %val1, %neg_operand_asr10 +; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #10 + store volatile i64 %bic_asr10, i64* @var1_64 + %xor_asr10 = xor i64 %val1, %operand_asr10 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #10 + store volatile i64 %xor_asr10, i64* @var1_64 + + %operand_lsr1 = lshr i64 %val2, 1 + %neg_operand_lsr1 = xor i64 -1, %operand_lsr1 + + %orn_lsr1 = or i64 %val1, %neg_operand_lsr1 +; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #1 + store volatile i64 %orn_lsr1, i64* @var1_64 + %xor_lsr1 = xor i64 %val1, %operand_lsr1 +; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #1 + store volatile i64 %xor_lsr1, i64* @var1_64 + + ; Construct a rotate-right from a bunch of other logical + ; operations. DAGCombiner should ensure we the ROTR during + ; selection + %operand_ror20_big = shl i64 %val2, 44 + %operand_ror20_small = lshr i64 %val2, 20 + %operand_ror20 = or i64 %operand_ror20_big, %operand_ror20_small + %neg_operand_ror20 = xor i64 -1, %operand_ror20 + + %xorn_ror20 = xor i64 %val1, %neg_operand_ror20 +; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, ror #20 + store volatile i64 %xorn_ror20, i64* @var1_64 + %and_ror20 = and i64 %val1, %operand_ror20 +; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, ror #20 + store volatile i64 %and_ror20, i64* @var1_64 + + ret void +} + +define void @flag_setting() { +; CHECK: flag_setting: + %val1 = load i64* @var1_64 + %val2 = load i64* @var2_64 + +; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}} +; CHECK: b.gt .L + %simple_and = and i64 %val1, %val2 + %tst1 = icmp sgt i64 %simple_and, 0 + br i1 %tst1, label %ret, label %test2 + +test2: +; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}}, lsl #63 +; CHECK: b.lt .L + %shifted_op = shl i64 %val2, 63 + %shifted_and = and i64 %val1, %shifted_op + %tst2 = icmp slt i64 %shifted_and, 0 + br i1 %tst2, label %ret, label %test3 + +test3: +; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}}, asr #12 +; CHECK: b.gt .L + %asr_op = ashr i64 %val2, 12 + %asr_and = and i64 %asr_op, %val1 + %tst3 = icmp sgt i64 %asr_and, 0 + br i1 %tst3, label %ret, label %other_exit + +other_exit: + store volatile i64 %val1, i64* @var1_64 + ret void +ret: + ret void +} diff --git a/test/CodeGen/AArch64/logical_shifted_reg.s b/test/CodeGen/AArch64/logical_shifted_reg.s new file mode 100644 index 0000000000..89aea58011 --- /dev/null +++ b/test/CodeGen/AArch64/logical_shifted_reg.s @@ -0,0 +1,208 @@ + .file "/home/timnor01/a64-trunk/llvm/test/CodeGen/AArch64/logical_shifted_reg.ll" + .text + .globl logical_32bit + .type logical_32bit,@function +logical_32bit: // @logical_32bit + .cfi_startproc +// BB#0: + adrp x0, var1_32 + ldr w1, [x0, #:lo12:var1_32] + adrp x0, var2_32 + ldr w2, [x0, #:lo12:var2_32] + and w3, w1, w2 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + bic w3, w1, w2 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + orr w3, w1, w2 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + orn w3, w1, w2 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eor w3, w1, w2 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eon w3, w2, w1 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + and w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + bic w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + orr w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + orn w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eor w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eon w3, w1, w2, lsl #31 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + bic w3, w1, w2, asr #10 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eor w3, w1, w2, asr #10 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + orn w3, w1, w2, lsr #1 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eor w3, w1, w2, lsr #1 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + eon w3, w1, w2, ror #20 + adrp x0, var1_32 + str w3, [x0, #:lo12:var1_32] + and w1, w1, w2, ror #20 + adrp x0, var1_32 + str w1, [x0, #:lo12:var1_32] + ret +.Ltmp0: + .size logical_32bit, .Ltmp0-logical_32bit + .cfi_endproc + + .globl logical_64bit + .type logical_64bit,@function +logical_64bit: // @logical_64bit + .cfi_startproc +// BB#0: + adrp x0, var1_64 + ldr x0, [x0, #:lo12:var1_64] + adrp x1, var2_64 + ldr x1, [x1, #:lo12:var2_64] + and x2, x0, x1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + bic x2, x0, x1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + orr x2, x0, x1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + orn x2, x0, x1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eor x2, x0, x1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eon x2, x1, x0 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + and x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + bic x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + orr x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + orn x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eor x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eon x2, x0, x1, lsl #63 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + bic x2, x0, x1, asr #10 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eor x2, x0, x1, asr #10 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + orn x2, x0, x1, lsr #1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eor x2, x0, x1, lsr #1 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + eon x2, x0, x1, ror #20 + adrp x3, var1_64 + str x2, [x3, #:lo12:var1_64] + and x0, x0, x1, ror #20 + adrp x1, var1_64 + str x0, [x1, #:lo12:var1_64] + ret +.Ltmp1: + .size logical_64bit, .Ltmp1-logical_64bit + .cfi_endproc + + .globl flag_setting + .type flag_setting,@function +flag_setting: // @flag_setting + .cfi_startproc +// BB#0: + sub sp, sp, #16 + adrp x0, var1_64 + ldr x0, [x0, #:lo12:var1_64] + adrp x1, var2_64 + ldr x1, [x1, #:lo12:var2_64] + tst x0, x1 + str x0, [sp, #8] // 8-byte Folded Spill + str x1, [sp] // 8-byte Folded Spill + b.gt .LBB2_4 + b .LBB2_1 +.LBB2_1: // %test2 + ldr x0, [sp, #8] // 8-byte Folded Reload + ldr x1, [sp] // 8-byte Folded Reload + tst x0, x1, lsl #63 + b.lt .LBB2_4 + b .LBB2_2 +.LBB2_2: // %test3 + ldr x0, [sp, #8] // 8-byte Folded Reload + ldr x1, [sp] // 8-byte Folded Reload + tst x0, x1, asr #12 + b.gt .LBB2_4 + b .LBB2_3 +.LBB2_3: // %other_exit + adrp x0, var1_64 + ldr x1, [sp, #8] // 8-byte Folded Reload + str x1, [x0, #:lo12:var1_64] + add sp, sp, #16 + ret +.LBB2_4: // %ret + add sp, sp, #16 + ret +.Ltmp2: + .size flag_setting, .Ltmp2-flag_setting + .cfi_endproc + + .type var1_32,@object // @var1_32 + .bss + .globl var1_32 + .align 2 +var1_32: + .word 0 // 0x0 + .size var1_32, 4 + + .type var2_32,@object // @var2_32 + .globl var2_32 + .align 2 +var2_32: + .word 0 // 0x0 + .size var2_32, 4 + + .type var1_64,@object // @var1_64 + .globl var1_64 + .align 3 +var1_64: + .xword 0 // 0x0 + .size var1_64, 8 + + .type var2_64,@object // @var2_64 + .globl var2_64 + .align 3 +var2_64: + .xword 0 // 0x0 + .size var2_64, 8 + + diff --git a/test/CodeGen/AArch64/movw-consts.ll b/test/CodeGen/AArch64/movw-consts.ll new file mode 100644 index 0000000000..b8a5fb9322 --- /dev/null +++ b/test/CodeGen/AArch64/movw-consts.ll @@ -0,0 +1,124 @@ +; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i64 @test0() { +; CHECK: test0: +; Not produced by move wide instructions, but good to make sure we can return 0 anyway: +; CHECK: mov x0, xzr + ret i64 0 +} + +define i64 @test1() { +; CHECK: test1: +; CHECK: movz x0, #1 + ret i64 1 +} + +define i64 @test2() { +; CHECK: test2: +; CHECK: movz x0, #65535 + ret i64 65535 +} + +define i64 @test3() { +; CHECK: test3: +; CHECK: movz x0, #1, lsl #16 + ret i64 65536 +} + +define i64 @test4() { +; CHECK: test4: +; CHECK: movz x0, #65535, lsl #16 + ret i64 4294901760 +} + +define i64 @test5() { +; CHECK: test5: +; CHECK: movz x0, #1, lsl #32 + ret i64 4294967296 +} + +define i64 @test6() { +; CHECK: test6: +; CHECK: movz x0, #65535, lsl #32 + ret i64 281470681743360 +} + +define i64 @test7() { +; CHECK: test7: +; CHECK: movz x0, #1, lsl #48 + ret i64 281474976710656 +} + +; A 32-bit MOVN can generate some 64-bit patterns that a 64-bit one +; couldn't. Useful even for i64 +define i64 @test8() { +; CHECK: test8: +; CHECK: movn w0, #60875 + ret i64 4294906420 +} + +define i64 @test9() { +; CHECK: test9: +; CHECK: movn x0, #0 + ret i64 -1 +} + +define i64 @test10() { +; CHECK: test10: +; CHECK: movn x0, #60875, lsl #16 + ret i64 18446744069720047615 +} + +; For reasonably legitimate reasons returning an i32 results in the +; selection of an i64 constant, so we need a different idiom to test that selection +@var32 = global i32 0 + +define void @test11() { +; CHECK: test11: +; CHECK: mov {{w[0-9]+}}, wzr + store i32 0, i32* @var32 + ret void +} + +define void @test12() { +; CHECK: test12: +; CHECK: movz {{w[0-9]+}}, #1 + store i32 1, i32* @var32 + ret void +} + +define void @test13() { +; CHECK: test13: +; CHECK: movz {{w[0-9]+}}, #65535 + store i32 65535, i32* @var32 + ret void +} + +define void @test14() { +; CHECK: test14: +; CHECK: movz {{w[0-9]+}}, #1, lsl #16 + store i32 65536, i32* @var32 + ret void +} + +define void @test15() { +; CHECK: test15: +; CHECK: movz {{w[0-9]+}}, #65535, lsl #16 + store i32 4294901760, i32* @var32 + ret void +} + +define void @test16() { +; CHECK: test16: +; CHECK: movn {{w[0-9]+}}, #0 + store i32 -1, i32* @var32 + ret void +} + +define i64 @test17() { +; CHECK: test17: + + ; Mustn't MOVN w0 here. +; CHECK: movn x0, #2 + ret i64 -3 +} diff --git a/test/CodeGen/AArch64/pic-eh-stubs.ll b/test/CodeGen/AArch64/pic-eh-stubs.ll new file mode 100644 index 0000000000..77bf691cbc --- /dev/null +++ b/test/CodeGen/AArch64/pic-eh-stubs.ll @@ -0,0 +1,60 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -o - %s | FileCheck %s + +; Make sure exception-handling PIC code can be linked correctly. An alternative +; to the sequence described below would have .gcc_except_table itself writable +; and not use the indirection, but this isn't what LLVM does right now. + + ; There should be a read-only .gcc_except_table section... +; CHECK: .section .gcc_except_table,"a" + + ; ... referring indirectly to stubs for its typeinfo ... +; CHECK: // @TType Encoding = indirect pcrel sdata8 + ; ... one of which is "int"'s typeinfo +; CHECK: .Ltmp9: +; CHECK-NEXT: .xword .L_ZTIi.DW.stub-.Ltmp9 + + ; .. and which is properly defined (in a writable section for the dynamic loader) later. +; CHECK: .section .data.rel,"aw" +; CHECK: .L_ZTIi.DW.stub: +; CHECK-NEXT: .xword _ZTIi + +@_ZTIi = external constant i8* + +define i32 @_Z3barv() { +entry: + invoke void @_Z3foov() + to label %return unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + %1 = extractvalue { i8*, i32 } %0, 1 + %2 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind + %matches = icmp eq i32 %1, %2 + br i1 %matches, label %catch, label %eh.resume + +catch: ; preds = %lpad + %3 = extractvalue { i8*, i32 } %0, 0 + %4 = tail call i8* @__cxa_begin_catch(i8* %3) nounwind + %5 = bitcast i8* %4 to i32* + %exn.scalar = load i32* %5, align 4 + tail call void @__cxa_end_catch() nounwind + br label %return + +return: ; preds = %entry, %catch + %retval.0 = phi i32 [ %exn.scalar, %catch ], [ 42, %entry ] + ret i32 %retval.0 + +eh.resume: ; preds = %lpad + resume { i8*, i32 } %0 +} + +declare void @_Z3foov() + +declare i32 @__gxx_personality_v0(...) + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch()
\ No newline at end of file diff --git a/test/CodeGen/AArch64/regress-bitcast-formals.ll b/test/CodeGen/AArch64/regress-bitcast-formals.ll new file mode 100644 index 0000000000..28dc9a7e25 --- /dev/null +++ b/test/CodeGen/AArch64/regress-bitcast-formals.ll @@ -0,0 +1,11 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +; CallingConv.td requires a bitcast for vector arguments. Make sure we're +; actually capable of that (the test was omitted from LowerFormalArguments). + +define void @test_bitcast_lower(<2 x i32> %a) { +; CHECK: test_bitcast_lower: + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/regress-f128csel-flags.ll b/test/CodeGen/AArch64/regress-f128csel-flags.ll new file mode 100644 index 0000000000..b35185ccd6 --- /dev/null +++ b/test/CodeGen/AArch64/regress-f128csel-flags.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +; We used to not mark NZCV as being used in the continuation basic-block +; when lowering a 128-bit "select" to branches. This meant a subsequent use +; of the same flags gave an internal fault here. + +declare void @foo(fp128) + +define double @test_f128csel_flags(i32 %lhs, fp128 %a, fp128 %b) nounwind { +; CHECK: test_f128csel_flags + + %tst = icmp ne i32 %lhs, 42 + %val = select i1 %tst, fp128 %a, fp128 %b +; CHECK: cmp w0, #42 +; CHECK: b.eq .LBB0 + + call void @foo(fp128 %val) + %retval = select i1 %tst, double 4.0, double 5.0 + + ; It's also reasonably important that the actual fcsel comes before the + ; function call since bl may corrupt NZCV. We were doing the right thing anyway, + ; but just as well test it while we're here. +; CHECK: fcsel {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, ne +; CHECK: bl foo + + ret double %retval +} diff --git a/test/CodeGen/AArch64/regress-tail-livereg.ll b/test/CodeGen/AArch64/regress-tail-livereg.ll new file mode 100644 index 0000000000..8d5485cae4 --- /dev/null +++ b/test/CodeGen/AArch64/regress-tail-livereg.ll @@ -0,0 +1,19 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s +@var = global void()* zeroinitializer + +declare void @bar() + +define void @foo() { +; CHECK: foo: + %func = load void()** @var + + ; Calling a function encourages @foo to use a callee-saved register, + ; which makes it a natural choice for the tail call itself. But we don't + ; want that: the final "br xN" has to use a temporary or argument + ; register. + call void @bar() + + tail call void %func() +; CHECK: br {{x([0-79]|1[0-8])}} + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/regress-tblgen-chains.ll b/test/CodeGen/AArch64/regress-tblgen-chains.ll new file mode 100644 index 0000000000..e54552fd8e --- /dev/null +++ b/test/CodeGen/AArch64/regress-tblgen-chains.ll @@ -0,0 +1,36 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +; When generating DAG selection tables, TableGen used to only flag an +; instruction as needing a chain on its own account if it had a built-in pattern +; which used the chain. This meant that the AArch64 load/stores weren't +; recognised and so both loads from %locvar below were coalesced into a single +; LS8_LDR instruction (same operands other than the non-existent chain) and the +; increment was lost at return. + +; This was obviously a Bad Thing. + +declare void @bar(i8*) + +define i64 @test_chains() { +; CHECK: test_chains: + + %locvar = alloca i8 + + call void @bar(i8* %locvar) +; CHECK: bl bar + + %inc.1 = load i8* %locvar + %inc.2 = zext i8 %inc.1 to i64 + %inc.3 = add i64 %inc.2, 1 + %inc.4 = trunc i64 %inc.3 to i8 + store i8 %inc.4, i8* %locvar +; CHECK: ldrb {{w[0-9]+}}, [sp, [[LOCADDR:#[0-9]+]]] +; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #1 +; CHECK: strb {{w[0-9]+}}, [sp, [[LOCADDR]]] +; CHECK: ldrb {{w[0-9]+}}, [sp, [[LOCADDR]]] + + %ret.1 = load i8* %locvar + %ret.2 = zext i8 %ret.1 to i64 + ret i64 %ret.2 +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll b/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll new file mode 100644 index 0000000000..980e2ffef9 --- /dev/null +++ b/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll @@ -0,0 +1,37 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-fp-elim < %s | FileCheck %s +@var = global i32 0 + +declare void @bar() + +define void @test_w29_reserved() { +; CHECK: test_w29_reserved: +; CHECK: add x29, sp, #{{[0-9]+}} + + %val1 = load volatile i32* @var + %val2 = load volatile i32* @var + %val3 = load volatile i32* @var + %val4 = load volatile i32* @var + %val5 = load volatile i32* @var + %val6 = load volatile i32* @var + %val7 = load volatile i32* @var + %val8 = load volatile i32* @var + %val9 = load volatile i32* @var + +; CHECK-NOT: ldr w29, + + ; Call to prevent fp-elim that occurs regardless in leaf functions. + call void @bar() + + store volatile i32 %val1, i32* @var + store volatile i32 %val2, i32* @var + store volatile i32 %val3, i32* @var + store volatile i32 %val4, i32* @var + store volatile i32 %val5, i32* @var + store volatile i32 %val6, i32* @var + store volatile i32 %val7, i32* @var + store volatile i32 %val8, i32* @var + store volatile i32 %val9, i32* @var + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/regress-wzr-allocatable.ll b/test/CodeGen/AArch64/regress-wzr-allocatable.ll new file mode 100644 index 0000000000..764d2bc44f --- /dev/null +++ b/test/CodeGen/AArch64/regress-wzr-allocatable.ll @@ -0,0 +1,41 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -O0 + +; When WZR wasn't marked as reserved, this function tried to allocate +; it at O0 and then generated an internal fault (mostly incidentally) +; when it discovered that it was already in use for a multiplication. + +; I'm not really convinced this is a good test since it could easily +; stop testing what it does now with no-one any the wiser. However, I +; can't think of a better way to force the allocator to use WZR +; specifically. + +define void @test() nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.body, %entry + br i1 undef, label %for.body, label %for.end + +for.body: ; preds = %for.cond + br label %for.cond + +for.end: ; preds = %for.cond + br label %for.cond6 + +for.cond6: ; preds = %for.body9, %for.end + br i1 undef, label %for.body9, label %while.cond30 + +for.body9: ; preds = %for.cond6 + store i16 0, i16* undef, align 2 + %0 = load i32* undef, align 4 + %1 = load i32* undef, align 4 + %mul15 = mul i32 %0, %1 + %add16 = add i32 %mul15, 32768 + %div = udiv i32 %add16, 65535 + %add17 = add i32 %div, 1 + store i32 %add17, i32* undef, align 4 + br label %for.cond6 + +while.cond30: ; preds = %for.cond6 + ret void +} diff --git a/test/CodeGen/AArch64/setcc-takes-i32.ll b/test/CodeGen/AArch64/setcc-takes-i32.ll new file mode 100644 index 0000000000..d2eb77ab1b --- /dev/null +++ b/test/CodeGen/AArch64/setcc-takes-i32.ll @@ -0,0 +1,22 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +; Most important point here is that the promotion of the i1 works +; correctly. Previously LLVM thought that i64 was the appropriate SetCC output, +; which meant it proceded in two steps and produced an i64 -> i64 any_ext which +; couldn't be selected and faulted. + +; It was expecting the smallest legal promotion of i1 to be the preferred SetCC +; type, so we'll satisfy it (this actually arguably gives better code anyway, +; with flag-manipulation operations allowed to use W-registers). + +declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) + +define i64 @test_select(i64 %lhs, i64 %rhs) { +; CHECK: test_select: + + %res = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %lhs, i64 %rhs) + %flag = extractvalue {i64, i1} %res, 1 + %retval = select i1 %flag, i64 %lhs, i64 %rhs + ret i64 %retval +; CHECK: ret +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/sibling-call.ll b/test/CodeGen/AArch64/sibling-call.ll new file mode 100644 index 0000000000..a1ec618b03 --- /dev/null +++ b/test/CodeGen/AArch64/sibling-call.ll @@ -0,0 +1,97 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +declare void @callee_stack0() +declare void @callee_stack8([8 x i32], i64) +declare void @callee_stack16([8 x i32], i64, i64) + +define void @caller_to0_from0() nounwind { +; CHECK: caller_to0_from0: +; CHECK-NEXT: // BB + tail call void @callee_stack0() + ret void +; CHECK-NEXT: b callee_stack0 +} + +define void @caller_to0_from8([8 x i32], i64) nounwind{ +; CHECK: caller_to0_from8: +; CHECK-NEXT: // BB + + tail call void @callee_stack0() + ret void +; CHECK-NEXT: b callee_stack0 +} + +define void @caller_to8_from0() { +; CHECK: caller_to8_from0: + +; Caller isn't going to clean up any extra stack we allocate, so it +; can't be a tail call. + tail call void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: bl callee_stack8 +} + +define void @caller_to8_from8([8 x i32], i64 %a) { +; CHECK: caller_to8_from8: +; CHECK-NOT: sub sp, sp, + +; This should reuse our stack area for the 42 + tail call void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: str {{x[0-9]+}}, [sp] +; CHECK-NEXT: b callee_stack8 +} + +define void @caller_to16_from8([8 x i32], i64 %a) { +; CHECK: caller_to16_from8: + +; Shouldn't be a tail call: we can't use SP+8 because our caller might +; have something there. This may sound obvious but implementation does +; some funky aligning. + tail call void @callee_stack16([8 x i32] undef, i64 undef, i64 undef) +; CHECK: bl callee_stack16 + ret void +} + +define void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) { +; CHECK: caller_to8_from24: +; CHECK-NOT: sub sp, sp + +; Reuse our area, putting "42" at incoming sp + tail call void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: str {{x[0-9]+}}, [sp] +; CHECK-NEXT: b callee_stack8 +} + +define void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { +; CHECK: caller_to16_from16: +; CHECK-NOT: sub sp, sp, + +; Here we want to make sure that both loads happen before the stores: +; otherwise either %a or %b will be wrongly clobbered. + tail call void @callee_stack16([8 x i32] undef, i64 %b, i64 %a) + ret void + +; CHECK: ldr x0, +; CHECK: ldr x1, +; CHECK: str x1, +; CHECK: str x0, + +; CHECK-NOT: add sp, sp, +; CHECK: b callee_stack16 +} + +@func = global void(i32)* null + +define void @indirect_tail() { +; CHECK: indirect_tail: +; CHECK-NOT: sub sp, sp + + %fptr = load void(i32)** @func + tail call void %fptr(i32 42) + ret void +; CHECK: movz w0, #42 +; CHECK: ldr [[FPTR:x[1-9]+]], [{{x[0-9]+}}, #:lo12:func] +; CHECK: br [[FPTR]] +}
\ No newline at end of file diff --git a/test/CodeGen/AArch64/sincos-expansion.ll b/test/CodeGen/AArch64/sincos-expansion.ll new file mode 100644 index 0000000000..c7a392b78c --- /dev/null +++ b/test/CodeGen/AArch64/sincos-expansion.ll @@ -0,0 +1,35 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +define float @test_sincos_f32(float %f) { + %sin = call float @sinf(float %f) readnone + %cos = call float @cosf(float %f) readnone +; CHECK: bl cosf +; CHECK: bl sinf + %val = fadd float %sin, %cos + ret float %val +} + +define double @test_sincos_f64(double %f) { + %sin = call double @sin(double %f) readnone + %cos = call double @cos(double %f) readnone + %val = fadd double %sin, %cos +; CHECK: bl cos +; CHECK: bl sin + ret double %val +} + +define fp128 @test_sincos_f128(fp128 %f) { + %sin = call fp128 @sinl(fp128 %f) readnone + %cos = call fp128 @cosl(fp128 %f) readnone + %val = fadd fp128 %sin, %cos +; CHECK: bl cosl +; CHECK: bl sinl + ret fp128 %val +} + +declare float @sinf(float) readonly +declare double @sin(double) readonly +declare fp128 @sinl(fp128) readonly +declare float @cosf(float) readonly +declare double @cos(double) readonly +declare fp128 @cosl(fp128) readonly
\ No newline at end of file diff --git a/test/CodeGen/AArch64/tail-call.ll b/test/CodeGen/AArch64/tail-call.ll new file mode 100644 index 0000000000..f323b151ad --- /dev/null +++ b/test/CodeGen/AArch64/tail-call.ll @@ -0,0 +1,94 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s + +declare fastcc void @callee_stack0() +declare fastcc void @callee_stack8([8 x i32], i64) +declare fastcc void @callee_stack16([8 x i32], i64, i64) + +define fastcc void @caller_to0_from0() nounwind { +; CHECK: caller_to0_from0: +; CHECK-NEXT: // BB + tail call fastcc void @callee_stack0() + ret void +; CHECK-NEXT: b callee_stack0 +} + +define fastcc void @caller_to0_from8([8 x i32], i64) { +; CHECK: caller_to0_from8: + + tail call fastcc void @callee_stack0() + ret void +; CHECK: add sp, sp, #16 +; CHECK-NEXT: b callee_stack0 +} + +define fastcc void @caller_to8_from0() { +; CHECK: caller_to8_from0: +; CHECK: sub sp, sp, #32 + +; Key point is that the "42" should go #16 below incoming stack +; pointer (we didn't have arg space to reuse). + tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: str {{x[0-9]+}}, [sp, #16] +; CHECK-NEXT: add sp, sp, #16 +; CHECK-NEXT: b callee_stack8 +} + +define fastcc void @caller_to8_from8([8 x i32], i64 %a) { +; CHECK: caller_to8_from8: +; CHECK: sub sp, sp, #16 + +; Key point is that the "%a" should go where at SP on entry. + tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: str {{x[0-9]+}}, [sp, #16] +; CHECK-NEXT: add sp, sp, #16 +; CHECK-NEXT: b callee_stack8 +} + +define fastcc void @caller_to16_from8([8 x i32], i64 %a) { +; CHECK: caller_to16_from8: +; CHECK: sub sp, sp, #16 + +; Important point is that the call reuses the "dead" argument space +; above %a on the stack. If it tries to go below incoming-SP then the +; callee will not deallocate the space, even in fastcc. + tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2) +; CHECK: str {{x[0-9]+}}, [sp, #24] +; CHECK: str {{x[0-9]+}}, [sp, #16] +; CHECK: add sp, sp, #16 +; CHECK: b callee_stack16 + ret void +} + + +define fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) { +; CHECK: caller_to8_from24: +; CHECK: sub sp, sp, #16 + +; Key point is that the "%a" should go where at #16 above SP on entry. + tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) + ret void +; CHECK: str {{x[0-9]+}}, [sp, #32] +; CHECK-NEXT: add sp, sp, #32 +; CHECK-NEXT: b callee_stack8 +} + + +define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { +; CHECK: caller_to16_from16: +; CHECK: sub sp, sp, #16 + +; Here we want to make sure that both loads happen before the stores: +; otherwise either %a or %b will be wrongly clobbered. + tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a) + ret void + +; CHECK: ldr x0, +; CHECK: ldr x1, +; CHECK: str x1, +; CHECK: str x0, + +; CHECK: add sp, sp, #16 +; CHECK: b callee_stack16 +} diff --git a/test/CodeGen/AArch64/tls-dynamic-together.ll b/test/CodeGen/AArch64/tls-dynamic-together.ll new file mode 100644 index 0000000000..bad2298c8a --- /dev/null +++ b/test/CodeGen/AArch64/tls-dynamic-together.ll @@ -0,0 +1,18 @@ +; RUN: llc -O0 -mtriple=aarch64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s + +; If the .tlsdesccall and blr parts are emitted completely separately (even with +; glue) then LLVM will separate them quite happily (with a spill at O0, hence +; the option). This is definitely wrong, so we make sure they are emitted +; together. + +@general_dynamic_var = external thread_local global i32 + +define i32 @test_generaldynamic() { +; CHECK: test_generaldynamic: + + %val = load i32* @general_dynamic_var + ret i32 %val + +; CHECK: .tlsdesccall general_dynamic_var +; CHECK-NEXT: blr {{x[0-9]+}} +} diff --git a/test/CodeGen/AArch64/tls-dynamics.ll b/test/CodeGen/AArch64/tls-dynamics.ll new file mode 100644 index 0000000000..cdfd11783c --- /dev/null +++ b/test/CodeGen/AArch64/tls-dynamics.ll @@ -0,0 +1,121 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s + +@general_dynamic_var = external thread_local global i32 + +define i32 @test_generaldynamic() { +; CHECK: test_generaldynamic: + + %val = load i32* @general_dynamic_var + ret i32 %val + +; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var +; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var +; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var] +; CHECK: .tlsdesccall general_dynamic_var +; CHECK-NEXT: blr [[CALLEE]] + +; CHECK: mrs x[[TP:[0-9]+]], tpidr_el0 +; CHECK: ldr w0, [x[[TP]], x0] + +; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE +; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_CALL + +} + +define i32* @test_generaldynamic_addr() { +; CHECK: test_generaldynamic_addr: + + ret i32* @general_dynamic_var + +; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var +; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var +; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var] +; CHECK: .tlsdesccall general_dynamic_var +; CHECK-NEXT: blr [[CALLEE]] + +; CHECK: mrs [[TP:x[0-9]+]], tpidr_el0 +; CHECK: add x0, [[TP]], x0 + +; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE +; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_CALL + +} + +@local_dynamic_var = external thread_local(localdynamic) global i32 + +define i32 @test_localdynamic() { +; CHECK: test_localdynamic: + + %val = load i32* @local_dynamic_var + ret i32 %val + +; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ +; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ +; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] +; CHECK: .tlsdesccall _TLS_MODULE_BASE_ +; CHECK-NEXT: blr [[CALLEE]] + +; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var +; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var + +; CHECK: ldr w0, [x0, [[DTP_OFFSET]]] + +; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE +; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_CALL + +} + +define i32* @test_localdynamic_addr() { +; CHECK: test_localdynamic_addr: + + ret i32* @local_dynamic_var + +; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ +; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ +; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] +; CHECK: .tlsdesccall _TLS_MODULE_BASE_ +; CHECK-NEXT: blr [[CALLEE]] + +; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var +; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var + +; CHECK: add x0, x0, [[DTP_OFFSET]] + +; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE +; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC +; CHECK-RELOC: R_AARCH64_TLSDESC_CALL + +} + +; The entire point of the local-dynamic access model is to have a single call to +; the expensive resolver. Make sure we achieve that goal. + +@local_dynamic_var2 = external thread_local(localdynamic) global i32 + +define i32 @test_localdynamic_deduplicate() { +; CHECK: test_localdynamic_deduplicate: + + %val = load i32* @local_dynamic_var + %val2 = load i32* @local_dynamic_var2 + + %sum = add i32 %val, %val2 + ret i32 %sum + +; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ +; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_ +; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_] +; CHECK: .tlsdesccall _TLS_MODULE_BASE_ +; CHECK-NEXT: blr [[CALLEE]] + +; CHECK-NOT: _TLS_MODULE_BASE_ + +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/tls-execs.ll b/test/CodeGen/AArch64/tls-execs.ll new file mode 100644 index 0000000000..a665884227 --- /dev/null +++ b/test/CodeGen/AArch64/tls-execs.ll @@ -0,0 +1,63 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s + +@initial_exec_var = external thread_local(initialexec) global i32 + +define i32 @test_initial_exec() { +; CHECK: test_initial_exec: + %val = load i32* @initial_exec_var + +; CHECK: adrp x[[GOTADDR:[0-9]+]], :gottprel:initial_exec_var +; CHECK: ldr x[[TP_OFFSET:[0-9]+]], [x[[GOTADDR]], #:gottprel_lo12:initial_exec_var] +; CHECK: mrs x[[TP:[0-9]+]], tpidr_el0 +; CHECK: ldr w0, [x[[TP]], x[[TP_OFFSET]]] + +; CHECK-RELOC: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 +; CHECK-RELOC: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + + ret i32 %val +} + +define i32* @test_initial_exec_addr() { +; CHECK: test_initial_exec_addr: + ret i32* @initial_exec_var + +; CHECK: adrp x[[GOTADDR:[0-9]+]], :gottprel:initial_exec_var +; CHECK: ldr [[TP_OFFSET:x[0-9]+]], [x[[GOTADDR]], #:gottprel_lo12:initial_exec_var] +; CHECK: mrs [[TP:x[0-9]+]], tpidr_el0 +; CHECK: add x0, [[TP]], [[TP_OFFSET]] + +; CHECK-RELOC: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 +; CHECK-RELOC: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + +} + +@local_exec_var = thread_local(initialexec) global i32 0 + +define i32 @test_local_exec() { +; CHECK: test_local_exec: + %val = load i32* @local_exec_var + +; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var +; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var +; CHECK: mrs x[[TP:[0-9]+]], tpidr_el0 +; CHECK: ldr w0, [x[[TP]], [[TP_OFFSET]]] + +; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1 +; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC + + ret i32 %val +} + +define i32* @test_local_exec_addr() { +; CHECK: test_local_exec_addr: + ret i32* @local_exec_var + +; CHECK: movz [[TP_OFFSET:x[0-9]+]], #:tprel_g1:local_exec_var +; CHECK: movk [[TP_OFFSET]], #:tprel_g0_nc:local_exec_var +; CHECK: mrs [[TP:x[0-9]+]], tpidr_el0 +; CHECK: add x0, [[TP]], [[TP_OFFSET]] + +; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1 +; CHECK-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC +} diff --git a/test/CodeGen/AArch64/tst-br.ll b/test/CodeGen/AArch64/tst-br.ll new file mode 100644 index 0000000000..65c1fda49e --- /dev/null +++ b/test/CodeGen/AArch64/tst-br.ll @@ -0,0 +1,48 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +; We've got the usual issues with LLVM reordering blocks here. The +; tests are correct for the current order, but who knows when that +; will change. Beware! +@var32 = global i32 0 +@var64 = global i64 0 + +define i32 @test_tbz() { +; CHECK: test_tbz: + + %val = load i32* @var32 + %val64 = load i64* @var64 + + %tbit0 = and i32 %val, 32768 + %tst0 = icmp ne i32 %tbit0, 0 + br i1 %tst0, label %test1, label %end1 +; CHECK: tbz {{w[0-9]+}}, #15, [[LBL_end1:.LBB0_[0-9]+]] + +test1: + %tbit1 = and i32 %val, 4096 + %tst1 = icmp ne i32 %tbit1, 0 + br i1 %tst1, label %test2, label %end1 +; CHECK: tbz {{w[0-9]+}}, #12, [[LBL_end1]] + +test2: + %tbit2 = and i64 %val64, 32768 + %tst2 = icmp ne i64 %tbit2, 0 + br i1 %tst2, label %test3, label %end1 +; CHECK: tbz {{x[0-9]+}}, #15, [[LBL_end1]] + +test3: + %tbit3 = and i64 %val64, 4096 + %tst3 = icmp ne i64 %tbit3, 0 + br i1 %tst3, label %end2, label %end1 +; CHECK: tbz {{x[0-9]+}}, #12, [[LBL_end1]] + +end2: +; CHECK: movz x0, #1 +; CHECK-NEXT: ret + ret i32 1 + +end1: +; CHECK: [[LBL_end1]]: +; CHECK-NEXT: mov x0, xzr +; CHECK-NEXT: ret + ret i32 0 +} diff --git a/test/CodeGen/AArch64/variadic.ll b/test/CodeGen/AArch64/variadic.ll new file mode 100644 index 0000000000..c5d319eb11 --- /dev/null +++ b/test/CodeGen/AArch64/variadic.ll @@ -0,0 +1,144 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +%va_list = type {i8*, i8*, i8*, i32, i32} + +@var = global %va_list zeroinitializer + +declare void @llvm.va_start(i8*) + +define void @test_simple(i32 %n, ...) { +; CHECK: test_simple: +; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]] +; CHECK: mov x[[FPRBASE:[0-9]+]], sp +; CHECK: str q7, [x[[FPRBASE]], #112] +; CHECK: add x[[GPRBASE:[0-9]+]], sp, #[[GPRFROMSP:[0-9]+]] +; CHECK: str x7, [x[[GPRBASE]], #48] + +; Omit the middle ones + +; CHECK: str q0, [sp] +; CHECK: str x1, [sp, #[[GPRFROMSP]]] + + %addr = bitcast %va_list* @var to i8* + call void @llvm.va_start(i8* %addr) +; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var +; CHECK: movn [[VR_OFFS:w[0-9]+]], #127 +; CHECK: str [[VR_OFFS]], [x[[VA_LIST]], #28] +; CHECK: movn [[GR_OFFS:w[0-9]+]], #55 +; CHECK: str [[GR_OFFS]], [x[[VA_LIST]], #24] +; CHECK: add [[VR_TOP:x[0-9]+]], x[[FPRBASE]], #128 +; CHECK: str [[VR_TOP]], [x[[VA_LIST]], #16] +; CHECK: add [[GR_TOP:x[0-9]+]], x[[GPRBASE]], #56 +; CHECK: str [[GR_TOP]], [x[[VA_LIST]], #8] +; CHECK: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]] +; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var] + + ret void +} + +define void @test_fewargs(i32 %n, i32 %n1, i32 %n2, float %m, ...) { +; CHECK: test_fewargs: +; CHECK: sub sp, sp, #[[STACKSIZE:[0-9]+]] +; CHECK: mov x[[FPRBASE:[0-9]+]], sp +; CHECK: str q7, [x[[FPRBASE]], #96] +; CHECK: add x[[GPRBASE:[0-9]+]], sp, #[[GPRFROMSP:[0-9]+]] +; CHECK: str x7, [x[[GPRBASE]], #32] + +; Omit the middle ones + +; CHECK: str q1, [sp] +; CHECK: str x3, [sp, #[[GPRFROMSP]]] + + %addr = bitcast %va_list* @var to i8* + call void @llvm.va_start(i8* %addr) +; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var +; CHECK: movn [[VR_OFFS:w[0-9]+]], #111 +; CHECK: str [[VR_OFFS]], [x[[VA_LIST]], #28] +; CHECK: movn [[GR_OFFS:w[0-9]+]], #39 +; CHECK: str [[GR_OFFS]], [x[[VA_LIST]], #24] +; CHECK: add [[VR_TOP:x[0-9]+]], x[[FPRBASE]], #112 +; CHECK: str [[VR_TOP]], [x[[VA_LIST]], #16] +; CHECK: add [[GR_TOP:x[0-9]+]], x[[GPRBASE]], #40 +; CHECK: str [[GR_TOP]], [x[[VA_LIST]], #8] +; CHECK: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]] +; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var] + + ret void +} + +define void @test_nospare([8 x i64], [8 x float], ...) { +; CHECK: test_nospare: + + %addr = bitcast %va_list* @var to i8* + call void @llvm.va_start(i8* %addr) +; CHECK-NOT: sub sp, sp +; CHECK: mov [[STACK:x[0-9]+]], sp +; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var] + + ret void +} + +; If there are non-variadic arguments on the stack (here two i64s) then the +; __stack field should point just past them. +define void @test_offsetstack([10 x i64], [3 x float], ...) { +; CHECK: test_offsetstack: +; CHECK: sub sp, sp, #80 +; CHECK: mov x[[FPRBASE:[0-9]+]], sp +; CHECK: str q7, [x[[FPRBASE]], #64] + +; CHECK-NOT: str x{{[0-9]+}}, +; Omit the middle ones + +; CHECK: str q3, [sp] + + %addr = bitcast %va_list* @var to i8* + call void @llvm.va_start(i8* %addr) +; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var +; CHECK: movn [[VR_OFFS:w[0-9]+]], #79 +; CHECK: str [[VR_OFFS]], [x[[VA_LIST]], #28] +; CHECK: str wzr, [x[[VA_LIST]], #24] +; CHECK: add [[VR_TOP:x[0-9]+]], x[[FPRBASE]], #80 +; CHECK: str [[VR_TOP]], [x[[VA_LIST]], #16] +; CHECK: add [[STACK:x[0-9]+]], sp, #96 +; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var] + + ret void +} + +declare void @llvm.va_end(i8*) + +define void @test_va_end() nounwind { +; CHECK: test_va_end: +; CHECK-NEXT: BB#0 + + %addr = bitcast %va_list* @var to i8* + call void @llvm.va_end(i8* %addr) + + ret void +; CHECK-NEXT: ret +} + +declare void @llvm.va_copy(i8* %dest, i8* %src) + +@second_list = global %va_list zeroinitializer + +define void @test_va_copy() { +; CHECK: test_va_copy: + %srcaddr = bitcast %va_list* @var to i8* + %dstaddr = bitcast %va_list* @second_list to i8* + call void @llvm.va_copy(i8* %dstaddr, i8* %srcaddr) + +; Check beginning and end again: + +; CHECK: ldr [[BLOCK:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var] +; CHECK: str [[BLOCK]], [{{x[0-9]+}}, #:lo12:second_list] + +; CHECK: add x[[DEST_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:second_list +; CHECK: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var + +; CHECK: ldr [[BLOCK:x[0-9]+]], [x[[SRC_LIST]], #24] +; CHECK: str [[BLOCK]], [x[[DEST_LIST]], #24] + + ret void +; CHECK: ret +} diff --git a/test/CodeGen/AArch64/zero-reg.ll b/test/CodeGen/AArch64/zero-reg.ll new file mode 100644 index 0000000000..fef0437ae7 --- /dev/null +++ b/test/CodeGen/AArch64/zero-reg.ll @@ -0,0 +1,31 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +@var32 = global i32 0 +@var64 = global i64 0 + +define void @test_zr() { +; CHECK: test_zr: + + store i32 0, i32* @var32 +; CHECK: str wzr, [{{x[0-9]+}}, #:lo12:var32] + store i64 0, i64* @var64 +; CHECK: str xzr, [{{x[0-9]+}}, #:lo12:var64] + + ret void +; CHECK: ret +} + +define void @test_sp(i32 %val) { +; CHECK: test_sp: + +; Important correctness point here is that LLVM doesn't try to use xzr +; as an addressing register: "str w0, [xzr]" is not a valid A64 +; instruction (0b11111 in the Rn field would mean "sp"). + %addr = getelementptr i32* null, i64 0 + store i32 %val, i32* %addr +; CHECK: mov x[[NULL:[0-9]+]], xzr +; CHECK: str {{w[0-9]+}}, [x[[NULL]]] + + ret void +; CHECK: ret +}
\ No newline at end of file diff --git a/test/CodeGen/ARM/2010-08-04-StackVariable.ll b/test/CodeGen/ARM/2010-08-04-StackVariable.ll index 6aeaa26ceb..29ccf22eee 100644 --- a/test/CodeGen/ARM/2010-08-04-StackVariable.ll +++ b/test/CodeGen/ARM/2010-08-04-StackVariable.ll @@ -74,51 +74,53 @@ return: ; preds = %entry declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !9, !16, !17, !20} +!llvm.dbg.cu = !{!3} -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"", metadata !2, i32 11, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 524307, metadata !2, metadata !"SVal", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_structure_type ] -!2 = metadata !{i32 524329, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 4, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"", metadata !2, i32 11, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786451, metadata !2, metadata !"SVal", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_structure_type ] +!2 = metadata !{i32 786473, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 4, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0, metadata !47, metadata !47, metadata !46, metadata !47} ; [ DW_TAG_compile_unit ] !4 = metadata !{metadata !5, metadata !7, metadata !0, metadata !9} -!5 = metadata !{i32 524301, metadata !1, metadata !"Data", metadata !2, i32 7, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!6 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!7 = metadata !{i32 524301, metadata !1, metadata !"Kind", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !8} ; [ DW_TAG_member ] -!8 = metadata !{i32 524324, metadata !2, metadata !"unsigned int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"~SVal", metadata !"~SVal", metadata !"", metadata !2, i32 12, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786445, metadata !1, metadata !"Data", metadata !2, i32 7, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] +!6 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 786445, metadata !1, metadata !"Kind", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !8} ; [ DW_TAG_member ] +!8 = metadata !{i32 786468, metadata !2, metadata !"unsigned int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"~SVal", metadata !"~SVal", metadata !"", metadata !2, i32 12, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] !11 = metadata !{null, metadata !12, metadata !13} -!12 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] -!13 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_subroutine_type ] +!12 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] +!13 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_subroutine_type ] !15 = metadata !{null, metadata !12} -!16 = metadata !{i32 524334, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"_ZN4SValC1Ev", metadata !2, i32 11, metadata !14, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, void (%struct.SVal*)* @_ZN4SValC1Ev} ; [ DW_TAG_subprogram ] -!17 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3fooi4SVal", metadata !2, i32 16, metadata !18, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32, %struct.SVal*)* @_Z3fooi4SVal} ; [ DW_TAG_subprogram ] -!18 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !19, i32 0, null} ; [ DW_TAG_subroutine_type ] +!16 = metadata !{i32 786478, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"_ZN4SValC1Ev", metadata !2, i32 11, metadata !14, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, void (%struct.SVal*)* @_ZN4SValC1Ev} ; [ DW_TAG_subprogram ] +!17 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3fooi4SVal", metadata !2, i32 16, metadata !18, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32, %struct.SVal*)* @_Z3fooi4SVal} ; [ DW_TAG_subprogram ] +!18 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !19, i32 0, null} ; [ DW_TAG_subroutine_type ] !19 = metadata !{metadata !13, metadata !13, metadata !1} -!20 = metadata !{i32 524334, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"main", metadata !2, i32 23, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!21 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, null} ; [ DW_TAG_subroutine_type ] +!20 = metadata !{i32 786478, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"main", metadata !2, i32 23, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] +!21 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, null} ; [ DW_TAG_subroutine_type ] !22 = metadata !{metadata !13} -!23 = metadata !{i32 524545, metadata !17, metadata !"i", metadata !2, i32 16, metadata !13} ; [ DW_TAG_arg_variable ] +!23 = metadata !{i32 786689, metadata !17, metadata !"i", metadata !2, i32 16, metadata !13, i32 0, i32 0} ; [ DW_TAG_arg_variable ] !24 = metadata !{i32 16, i32 0, metadata !17, null} -!25 = metadata !{i32 524545, metadata !17, metadata !"location", metadata !2, i32 16, metadata !26} ; [ DW_TAG_arg_variable ] -!26 = metadata !{i32 524304, metadata !2, metadata !"SVal", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_reference_type ] +!25 = metadata !{i32 786689, metadata !17, metadata !"location", metadata !2, i32 16, metadata !26, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!26 = metadata !{i32 786448, metadata !2, metadata !"SVal", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_reference_type ] !27 = metadata !{i32 17, i32 0, metadata !28, null} -!28 = metadata !{i32 524299, metadata !17, i32 16, i32 0, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786443, metadata !17, i32 16, i32 0, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] !29 = metadata !{i32 18, i32 0, metadata !28, null} !30 = metadata !{i32 20, i32 0, metadata !28, null} -!31 = metadata !{i32 524545, metadata !16, metadata !"this", metadata !2, i32 11, metadata !32} ; [ DW_TAG_arg_variable ] -!32 = metadata !{i32 524326, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !33} ; [ DW_TAG_const_type ] -!33 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_pointer_type ] +!31 = metadata !{i32 786689, metadata !16, metadata !"this", metadata !2, i32 11, metadata !32, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!32 = metadata !{i32 786470, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !33} ; [ DW_TAG_const_type ] +!33 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_pointer_type ] !34 = metadata !{i32 11, i32 0, metadata !16, null} !35 = metadata !{i32 11, i32 0, metadata !36, null} -!36 = metadata !{i32 524299, metadata !37, i32 11, i32 0, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] -!37 = metadata !{i32 524299, metadata !16, i32 11, i32 0, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] -!38 = metadata !{i32 524544, metadata !39, metadata !"v", metadata !2, i32 24, metadata !1} ; [ DW_TAG_auto_variable ] -!39 = metadata !{i32 524299, metadata !40, i32 23, i32 0, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] -!40 = metadata !{i32 524299, metadata !20, i32 23, i32 0, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] +!36 = metadata !{i32 786443, metadata !37, i32 11, i32 0, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!37 = metadata !{i32 786443, metadata !16, i32 11, i32 0, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!38 = metadata !{i32 786688, metadata !39, metadata !"v", metadata !2, i32 24, metadata !1, i32 0, i32 0} ; [ DW_TAG_auto_variable ] +!39 = metadata !{i32 786443, metadata !40, i32 23, i32 0, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] +!40 = metadata !{i32 786443, metadata !20, i32 23, i32 0, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] !41 = metadata !{i32 24, i32 0, metadata !39, null} !42 = metadata !{i32 25, i32 0, metadata !39, null} !43 = metadata !{i32 26, i32 0, metadata !39, null} -!44 = metadata !{i32 524544, metadata !39, metadata !"k", metadata !2, i32 26, metadata !13} ; [ DW_TAG_auto_variable ] +!44 = metadata !{i32 786688, metadata !39, metadata !"k", metadata !2, i32 26, metadata !13, i32 0, i32 0} ; [ DW_TAG_auto_variable ] !45 = metadata !{i32 27, i32 0, metadata !39, null} +!46 = metadata !{metadata !0, metadata !9, metadata !16, metadata !17, metadata !20} +!47 = metadata !{i32 0} diff --git a/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll b/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll index ca88eedcea..c8ce6eec62 100644 --- a/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll +++ b/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll @@ -75,44 +75,45 @@ entry: ret i8 %0, !dbg !39 } -!llvm.dbg.sp = !{!0, !6, !7, !8, !9} -!llvm.dbg.lv.get1 = !{!10, !11} -!llvm.dbg.gv = !{!13, !14, !15, !16, !17} -!llvm.dbg.lv.get2 = !{!18, !19} -!llvm.dbg.lv.get3 = !{!21, !22} -!llvm.dbg.lv.get4 = !{!24, !25} -!llvm.dbg.lv.get5 = !{!27, !28} +!llvm.dbg.cu = !{!2} +!40 = metadata !{metadata !0, metadata !6, metadata !7, metadata !8, metadata !9} +!41 = metadata !{metadata !13, metadata !14, metadata !15, metadata !16, metadata !17} +!42 = metadata !{metadata !10, metadata !11} +!43 = metadata !{metadata !18, metadata !19} +!44 = metadata !{metadata !21, metadata !22} +!45 = metadata !{metadata !24, metadata !25} +!46 = metadata !{metadata !27, metadata !28} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"get1", metadata !"get1", metadata !"get1", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get1} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"foo.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2369.8)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"get1", metadata !"get1", metadata !"get1", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get1, null, null, metadata !42, i32 4} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"foo.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2369.8)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !40, metadata !41} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5, metadata !5} -!5 = metadata !{i32 589860, metadata !1, metadata !"_Bool", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"get2", metadata !"get2", metadata !"get2", metadata !1, i32 7, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get2} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589870, i32 0, metadata !1, metadata !"get3", metadata !"get3", metadata !"get3", metadata !1, i32 10, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get3} ; [ DW_TAG_subprogram ] -!8 = metadata !{i32 589870, i32 0, metadata !1, metadata !"get4", metadata !"get4", metadata !"get4", metadata !1, i32 13, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get4} ; [ DW_TAG_subprogram ] -!9 = metadata !{i32 589870, i32 0, metadata !1, metadata !"get5", metadata !"get5", metadata !"get5", metadata !1, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get5} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 590081, metadata !0, metadata !"a", metadata !1, i32 4, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!11 = metadata !{i32 590080, metadata !12, metadata !"b", metadata !1, i32 4, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!12 = metadata !{i32 589835, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!13 = metadata !{i32 589876, i32 0, metadata !1, metadata !"x1", metadata !"x1", metadata !"", metadata !1, i32 3, metadata !5, i1 true, i1 true, i8* @x1} ; [ DW_TAG_variable ] -!14 = metadata !{i32 589876, i32 0, metadata !1, metadata !"x2", metadata !"x2", metadata !"", metadata !1, i32 6, metadata !5, i1 true, i1 true, i8* @x2} ; [ DW_TAG_variable ] -!15 = metadata !{i32 589876, i32 0, metadata !1, metadata !"x3", metadata !"x3", metadata !"", metadata !1, i32 9, metadata !5, i1 true, i1 true, i8* @x3} ; [ DW_TAG_variable ] -!16 = metadata !{i32 589876, i32 0, metadata !1, metadata !"x4", metadata !"x4", metadata !"", metadata !1, i32 12, metadata !5, i1 true, i1 true, i8* @x4} ; [ DW_TAG_variable ] -!17 = metadata !{i32 589876, i32 0, metadata !1, metadata !"x5", metadata !"x5", metadata !"", metadata !1, i32 15, metadata !5, i1 false, i1 true, i8* @x5} ; [ DW_TAG_variable ] -!18 = metadata !{i32 590081, metadata !6, metadata !"a", metadata !1, i32 7, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 590080, metadata !20, metadata !"b", metadata !1, i32 7, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!20 = metadata !{i32 589835, metadata !6, i32 7, i32 0, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] -!21 = metadata !{i32 590081, metadata !7, metadata !"a", metadata !1, i32 10, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!22 = metadata !{i32 590080, metadata !23, metadata !"b", metadata !1, i32 10, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!23 = metadata !{i32 589835, metadata !7, i32 10, i32 0, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] -!24 = metadata !{i32 590081, metadata !8, metadata !"a", metadata !1, i32 13, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!25 = metadata !{i32 590080, metadata !26, metadata !"b", metadata !1, i32 13, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!26 = metadata !{i32 589835, metadata !8, i32 13, i32 0, metadata !1, i32 3} ; [ DW_TAG_lexical_block ] -!27 = metadata !{i32 590081, metadata !9, metadata !"a", metadata !1, i32 16, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!28 = metadata !{i32 590080, metadata !29, metadata !"b", metadata !1, i32 16, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!29 = metadata !{i32 589835, metadata !9, i32 16, i32 0, metadata !1, i32 4} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786468, metadata !1, metadata !"_Bool", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !1, metadata !"get2", metadata !"get2", metadata !"get2", metadata !1, i32 7, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get2, null, null, metadata !43, i32 7} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786478, i32 0, metadata !1, metadata !"get3", metadata !"get3", metadata !"get3", metadata !1, i32 10, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get3, null, null, metadata !44, i32 10} ; [ DW_TAG_subprogram ] +!8 = metadata !{i32 786478, i32 0, metadata !1, metadata !"get4", metadata !"get4", metadata !"get4", metadata !1, i32 13, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get4, null, null, metadata !45, i32 13} ; [ DW_TAG_subprogram ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"get5", metadata !"get5", metadata !"get5", metadata !1, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i8 (i8)* @get5, null, null, metadata !46, i32 16} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786689, metadata !0, metadata !"a", metadata !1, i32 4, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 786688, metadata !12, metadata !"b", metadata !1, i32 4, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!12 = metadata !{i32 786443, metadata !0, i32 4, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 786484, i32 0, metadata !1, metadata !"x1", metadata !"x1", metadata !"", metadata !1, i32 3, metadata !5, i1 true, i1 true, i8* @x1, null} ; [ DW_TAG_variable ] +!14 = metadata !{i32 786484, i32 0, metadata !1, metadata !"x2", metadata !"x2", metadata !"", metadata !1, i32 6, metadata !5, i1 true, i1 true, i8* @x2, null} ; [ DW_TAG_variable ] +!15 = metadata !{i32 786484, i32 0, metadata !1, metadata !"x3", metadata !"x3", metadata !"", metadata !1, i32 9, metadata !5, i1 true, i1 true, i8* @x3, null} ; [ DW_TAG_variable ] +!16 = metadata !{i32 786484, i32 0, metadata !1, metadata !"x4", metadata !"x4", metadata !"", metadata !1, i32 12, metadata !5, i1 true, i1 true, i8* @x4, null} ; [ DW_TAG_variable ] +!17 = metadata !{i32 786484, i32 0, metadata !1, metadata !"x5", metadata !"x5", metadata !"", metadata !1, i32 15, metadata !5, i1 false, i1 true, i8* @x5, null} ; [ DW_TAG_variable ] +!18 = metadata !{i32 786689, metadata !6, metadata !"a", metadata !1, i32 7, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786688, metadata !20, metadata !"b", metadata !1, i32 7, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!20 = metadata !{i32 786443, metadata !6, i32 7, i32 0, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!21 = metadata !{i32 786689, metadata !7, metadata !"a", metadata !1, i32 10, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!22 = metadata !{i32 786688, metadata !23, metadata !"b", metadata !1, i32 10, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!23 = metadata !{i32 786443, metadata !7, i32 10, i32 0, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] +!24 = metadata !{i32 786689, metadata !8, metadata !"a", metadata !1, i32 13, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!25 = metadata !{i32 786688, metadata !26, metadata !"b", metadata !1, i32 13, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!26 = metadata !{i32 786443, metadata !8, i32 13, i32 0, metadata !1, i32 3} ; [ DW_TAG_lexical_block ] +!27 = metadata !{i32 786689, metadata !9, metadata !"a", metadata !1, i32 16, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!28 = metadata !{i32 786688, metadata !29, metadata !"b", metadata !1, i32 16, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 786443, metadata !9, i32 16, i32 0, metadata !1, i32 4} ; [ DW_TAG_lexical_block ] !30 = metadata !{i32 4, i32 0, metadata !0, null} !31 = metadata !{i32 4, i32 0, metadata !12, null} !32 = metadata !{i32 7, i32 0, metadata !6, null} diff --git a/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll index f2b0c5d7d0..2cd4acea63 100644 --- a/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll +++ b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll @@ -8,7 +8,7 @@ ; DW_OP_constu ; offset -;CHECK: .long Lset33 +;CHECK: .long Lset8 ;CHECK-NEXT: @ DW_AT_type ;CHECK-NEXT: @ DW_AT_decl_file ;CHECK-NEXT: @ DW_AT_decl_line @@ -73,44 +73,44 @@ define i32 @get5(i32 %a) nounwind optsize ssp { declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1, !6, !7, !8, !9} -!llvm.dbg.lv.get1 = !{!10, !11} -!llvm.dbg.lv.get2 = !{!13, !14} -!llvm.dbg.lv.get3 = !{!16, !17} -!llvm.dbg.lv.get4 = !{!19, !20} -!llvm.dbg.gv = !{!22, !23, !24, !25, !26} -!llvm.dbg.lv.get5 = !{!27, !28} +!40 = metadata !{metadata !1, metadata !6, metadata !7, metadata !8, metadata !9} +!42 = metadata !{metadata !10, metadata !11} +!43 = metadata !{metadata !13, metadata !14} +!44 = metadata !{metadata !16, metadata !17} +!45 = metadata !{metadata !19, metadata !20} +!46 = metadata !{metadata !27, metadata !28} +!41 = metadata !{metadata !22, metadata !23, metadata !24, metadata !25, metadata !26} -!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"ss3.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get1", metadata !"get1", metadata !"", metadata !2, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get1, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"ss3.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"ss3.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !40, metadata !41, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"get1", metadata !"get1", metadata !"", metadata !2, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get1, null, null, metadata !42, i32 5} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"ss3.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get2", metadata !"get2", metadata !"", metadata !2, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get2, null, null} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get3", metadata !"get3", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get3, null, null} ; [ DW_TAG_subprogram ] -!8 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get4", metadata !"get4", metadata !"", metadata !2, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get4, null, null} ; [ DW_TAG_subprogram ] -!9 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get5", metadata !"get5", metadata !"", metadata !2, i32 17, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get5, null, null} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 590081, metadata !1, metadata !"a", metadata !2, i32 16777221, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!11 = metadata !{i32 590080, metadata !12, metadata !"b", metadata !2, i32 5, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!12 = metadata !{i32 589835, metadata !1, i32 5, i32 19, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] -!13 = metadata !{i32 590081, metadata !6, metadata !"a", metadata !2, i32 16777224, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!14 = metadata !{i32 590080, metadata !15, metadata !"b", metadata !2, i32 8, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!15 = metadata !{i32 589835, metadata !6, i32 8, i32 17, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] -!16 = metadata !{i32 590081, metadata !7, metadata !"a", metadata !2, i32 16777227, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!17 = metadata !{i32 590080, metadata !18, metadata !"b", metadata !2, i32 11, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!18 = metadata !{i32 589835, metadata !7, i32 11, i32 19, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] -!19 = metadata !{i32 590081, metadata !8, metadata !"a", metadata !2, i32 16777230, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!20 = metadata !{i32 590080, metadata !21, metadata !"b", metadata !2, i32 14, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!21 = metadata !{i32 589835, metadata !8, i32 14, i32 19, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] -!22 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x5", metadata !"x5", metadata !"", metadata !2, i32 16, metadata !5, i32 0, i32 1, i32* @x5} ; [ DW_TAG_variable ] -!23 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x4", metadata !"x4", metadata !"", metadata !2, i32 13, metadata !5, i32 1, i32 1, i32* @x4} ; [ DW_TAG_variable ] -!24 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x3", metadata !"x3", metadata !"", metadata !2, i32 10, metadata !5, i32 1, i32 1, i32* @x3} ; [ DW_TAG_variable ] -!25 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x2", metadata !"x2", metadata !"", metadata !2, i32 7, metadata !5, i32 1, i32 1, i32* @x2} ; [ DW_TAG_variable ] -!26 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x1", metadata !"x1", metadata !"", metadata !2, i32 4, metadata !5, i32 1, i32 1, i32* @x1} ; [ DW_TAG_variable ] -!27 = metadata !{i32 590081, metadata !9, metadata !"a", metadata !2, i32 16777233, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!28 = metadata !{i32 590080, metadata !29, metadata !"b", metadata !2, i32 17, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!29 = metadata !{i32 589835, metadata !9, i32 17, i32 19, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !2, metadata !"get2", metadata !"get2", metadata !"", metadata !2, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get2, null, null, metadata !43, i32 8} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786478, i32 0, metadata !2, metadata !"get3", metadata !"get3", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get3, null, null, metadata !44, i32 11} ; [ DW_TAG_subprogram ] +!8 = metadata !{i32 786478, i32 0, metadata !2, metadata !"get4", metadata !"get4", metadata !"", metadata !2, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get4, null, null, metadata !45, i32 14} ; [ DW_TAG_subprogram ] +!9 = metadata !{i32 786478, i32 0, metadata !2, metadata !"get5", metadata !"get5", metadata !"", metadata !2, i32 17, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get5, null, null, metadata !46, i32 17} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786689, metadata !1, metadata !"a", metadata !2, i32 16777221, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 786688, metadata !12, metadata !"b", metadata !2, i32 5, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!12 = metadata !{i32 786443, metadata !1, i32 5, i32 19, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 786689, metadata !6, metadata !"a", metadata !2, i32 16777224, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 786688, metadata !15, metadata !"b", metadata !2, i32 8, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 786443, metadata !6, i32 8, i32 17, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 786689, metadata !7, metadata !"a", metadata !2, i32 16777227, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 786688, metadata !18, metadata !"b", metadata !2, i32 11, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!18 = metadata !{i32 786443, metadata !7, i32 11, i32 19, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] +!19 = metadata !{i32 786689, metadata !8, metadata !"a", metadata !2, i32 16777230, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 786688, metadata !21, metadata !"b", metadata !2, i32 14, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!21 = metadata !{i32 786443, metadata !8, i32 14, i32 19, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] +!22 = metadata !{i32 786484, i32 0, metadata !0, metadata !"x5", metadata !"x5", metadata !"", metadata !2, i32 16, metadata !5, i32 0, i32 1, i32* @x5, null} ; [ DW_TAG_variable ] +!23 = metadata !{i32 786484, i32 0, metadata !0, metadata !"x4", metadata !"x4", metadata !"", metadata !2, i32 13, metadata !5, i32 1, i32 1, i32* @x4, null} ; [ DW_TAG_variable ] +!24 = metadata !{i32 786484, i32 0, metadata !0, metadata !"x3", metadata !"x3", metadata !"", metadata !2, i32 10, metadata !5, i32 1, i32 1, i32* @x3, null} ; [ DW_TAG_variable ] +!25 = metadata !{i32 786484, i32 0, metadata !0, metadata !"x2", metadata !"x2", metadata !"", metadata !2, i32 7, metadata !5, i32 1, i32 1, i32* @x2, null} ; [ DW_TAG_variable ] +!26 = metadata !{i32 786484, i32 0, metadata !0, metadata !"x1", metadata !"x1", metadata !"", metadata !2, i32 4, metadata !5, i32 1, i32 1, i32* @x1, null} ; [ DW_TAG_variable ] +!27 = metadata !{i32 786689, metadata !9, metadata !"a", metadata !2, i32 16777233, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!28 = metadata !{i32 786688, metadata !29, metadata !"b", metadata !2, i32 17, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 786443, metadata !9, i32 17, i32 19, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] !30 = metadata !{i32 5, i32 16, metadata !1, null} !31 = metadata !{i32 5, i32 32, metadata !12, null} !32 = metadata !{i32 8, i32 14, metadata !6, null} diff --git a/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll b/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll index f9ede7401a..0d0d03b23e 100644 --- a/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll +++ b/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll @@ -8,7 +8,7 @@ define void @test_sqrt(<4 x float>* %X) nounwind { ; CHECK: movw r1, :lower16:{{.*}} ; CHECK: movt r1, :upper16:{{.*}} -; CHECK: vld1.64 {{.*}}, [r1, :128] +; CHECK: vld1.64 {{.*}}, [r1:128] ; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}} ; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}} ; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}} @@ -252,7 +252,7 @@ define void @test_powi(<4 x float>* %X) nounwind { ; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}} ; CHECK: movt [[reg0]], :upper16:{{.*}} -; CHECK: vld1.64 {{.*}}, :128 +; CHECK: vld1.64 {{.*}}:128 ; CHECK: vmul.f32 {{.*}} ; CHECK: vst1.64 diff --git a/test/CodeGen/ARM/2012-08-09-neon-extload.ll b/test/CodeGen/ARM/2012-08-09-neon-extload.ll index b55f1cae7f..764c58f2e1 100644 --- a/test/CodeGen/ARM/2012-08-09-neon-extload.ll +++ b/test/CodeGen/ARM/2012-08-09-neon-extload.ll @@ -18,7 +18,7 @@ define void @test_v2i8tov2i32() { %i32val = sext <2 x i8> %i8val to <2 x i32> store <2 x i32> %i32val, <2 x i32>* @var_v2i32 -; CHECK: vld1.16 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}, :16] +; CHECK: vld1.16 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}:16] ; CHECK: vmovl.s8 {{q[0-9]+}}, d[[LOAD]] ; CHECK: vmovl.s16 {{q[0-9]+}}, {{d[0-9]+}} @@ -32,7 +32,7 @@ define void @test_v2i8tov2i64() { %i64val = sext <2 x i8> %i8val to <2 x i64> store <2 x i64> %i64val, <2 x i64>* @var_v2i64 -; CHECK: vld1.16 {d{{[0-9]+}}[0]}, [{{r[0-9]+}}, :16] +; CHECK: vld1.16 {d{{[0-9]+}}[0]}, [{{r[0-9]+}}:16] ; CHECK: vmovl.s8 {{q[0-9]+}}, d[[LOAD]] ; CHECK: vmovl.s16 {{q[0-9]+}}, {{d[0-9]+}} ; CHECK: vmovl.s32 {{q[0-9]+}}, {{d[0-9]+}} @@ -50,7 +50,7 @@ define void @test_v4i8tov4i16() { %i16val = sext <4 x i8> %i8val to <4 x i16> store <4 x i16> %i16val, <4 x i16>* @var_v4i16 -; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}, :32] +; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}:32] ; CHECK: vmovl.s8 {{q[0-9]+}}, d[[LOAD]] ; CHECK-NOT: vmovl.s16 @@ -65,7 +65,7 @@ define void @test_v4i8tov4i32() { %i16val = sext <4 x i8> %i8val to <4 x i32> store <4 x i32> %i16val, <4 x i32>* @var_v4i32 -; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}, :32] +; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}:32] ; CHECK: vmovl.s8 {{q[0-9]+}}, d[[LOAD]] ; CHECK: vmovl.s16 {{q[0-9]+}}, {{d[0-9]+}} @@ -79,7 +79,7 @@ define void @test_v2i16tov2i32() { %i32val = sext <2 x i16> %i16val to <2 x i32> store <2 x i32> %i32val, <2 x i32>* @var_v2i32 -; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}, :32] +; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}:32] ; CHECK: vmovl.s16 {{q[0-9]+}}, d[[LOAD]] ; CHECK-NOT: vmovl @@ -94,7 +94,7 @@ define void @test_v2i16tov2i64() { %i64val = sext <2 x i16> %i16val to <2 x i64> store <2 x i64> %i64val, <2 x i64>* @var_v2i64 -; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}, :32] +; CHECK: vld1.32 {d[[LOAD:[0-9]+]][0]}, [{{r[0-9]+}}:32] ; CHECK: vmovl.s16 {{q[0-9]+}}, d[[LOAD]] ; CHECK: vmovl.s32 {{q[0-9]+}}, d[[LOAD]] diff --git a/test/CodeGen/ARM/2013-01-21-PR14992.ll b/test/CodeGen/ARM/2013-01-21-PR14992.ll new file mode 100644 index 0000000000..38b9e0e8f0 --- /dev/null +++ b/test/CodeGen/ARM/2013-01-21-PR14992.ll @@ -0,0 +1,28 @@ +;PR14492 - Tablegen incorrectly converts ARM tLDMIA_UPD pseudo to tLDMIA +;RUN: llc -mtriple=thumbv7 < %s | FileCheck -check-prefix=EXPECTED %s +;RUN: llc -mtriple=thumbv7 < %s | FileCheck %s + +;EXPECTED: foo: +;CHECK: foo: +define i32 @foo(i32* %a) nounwind optsize { +entry: + %0 = load i32* %a, align 4, !tbaa !0 + %arrayidx1 = getelementptr inbounds i32* %a, i32 1 + %1 = load i32* %arrayidx1, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds i32* %a, i32 2 + %2 = load i32* %arrayidx2, align 4, !tbaa !0 + %add.ptr = getelementptr inbounds i32* %a, i32 3 +;Make sure we do not have a duplicated register in the front of the reg list +;EXPECTED: ldm [[BASE:r[0-9]+]]!, {[[REG:r[0-9]+]], {{r[0-9]+}}, +;CHECK-NOT: ldm [[BASE:r[0-9]+]]!, {[[REG:r[0-9]+]], [[REG]], + tail call void @bar(i32* %add.ptr) nounwind optsize + %add = add nsw i32 %1, %0 + %add3 = add nsw i32 %add, %2 + ret i32 %add3 +} + +declare void @bar(i32*) optsize + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/ARM/2013-02-27-expand-vfma.ll b/test/CodeGen/ARM/2013-02-27-expand-vfma.ll new file mode 100644 index 0000000000..0e3bf23710 --- /dev/null +++ b/test/CodeGen/ARM/2013-02-27-expand-vfma.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=armv7s-apple-darwin | FileCheck %s -check-prefix=VFP4 + +define <4 x float> @muladd(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind { +; CHECK: muladd: +; CHECK: fmaf +; CHECK: fmaf +; CHECK: fmaf +; CHECK: fmaf +; CHECK-NOT: fmaf + +; CHECK-VFP4: vfma.f32 + %tmp = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %b, <4 x float> %c, <4 x float> %a) #2 + ret <4 x float> %tmp +} + +declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) #1 + +define <2 x float> @muladd2(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind { +; CHECK: muladd2: +; CHECK: fmaf +; CHECK: fmaf +; CHECK-NOT: fmaf + +; CHECK-VFP4: vfma.f32 + %tmp = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> %c, <2 x float> %a) #2 + ret <2 x float> %tmp +} + +declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) #1 + diff --git a/test/CodeGen/ARM/DbgValueOtherTargets.test b/test/CodeGen/ARM/DbgValueOtherTargets.test new file mode 100644 index 0000000000..8739a43640 --- /dev/null +++ b/test/CodeGen/ARM/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=arm -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/ARM/PR15053.ll b/test/CodeGen/ARM/PR15053.ll new file mode 100644 index 0000000000..706a90efe3 --- /dev/null +++ b/test/CodeGen/ARM/PR15053.ll @@ -0,0 +1,13 @@ +; RUN: llc -mtriple=armv7 < %s +; PR15053 + +declare i32 @llvm.arm.strexd(i32, i32, i8*) nounwind +declare { i32, i32 } @llvm.arm.ldrexd(i8*) nounwind readonly + +define void @foo() { +entry: + %0 = tail call { i32, i32 } @llvm.arm.ldrexd(i8* undef) nounwind + %1 = extractvalue { i32, i32 } %0, 0 + %2 = tail call i32 @llvm.arm.strexd(i32 %1, i32 undef, i8* undef) nounwind + ret void +} diff --git a/test/CodeGen/ARM/2007-03-13-InstrSched.ll b/test/CodeGen/ARM/Stats/2007-03-13-InstrSched.ll index a63cdd46e2..a63cdd46e2 100644 --- a/test/CodeGen/ARM/2007-03-13-InstrSched.ll +++ b/test/CodeGen/ARM/Stats/2007-03-13-InstrSched.ll diff --git a/test/CodeGen/ARM/2011-12-14-machine-sink.ll b/test/CodeGen/ARM/Stats/2011-12-14-machine-sink.ll index b21bb006e3..b21bb006e3 100644 --- a/test/CodeGen/ARM/2011-12-14-machine-sink.ll +++ b/test/CodeGen/ARM/Stats/2011-12-14-machine-sink.ll diff --git a/test/CodeGen/ARM/addrmode.ll b/test/CodeGen/ARM/Stats/addrmode.ll index 6da90897b9..6da90897b9 100644 --- a/test/CodeGen/ARM/addrmode.ll +++ b/test/CodeGen/ARM/Stats/addrmode.ll diff --git a/test/CodeGen/ARM/Stats/lit.local.cfg b/test/CodeGen/ARM/Stats/lit.local.cfg new file mode 100644 index 0000000000..f6194d2421 --- /dev/null +++ b/test/CodeGen/ARM/Stats/lit.local.cfg @@ -0,0 +1,8 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'ARM' in targets: + config.unsupported = True + +if not config.root.enable_assertions: + config.unsupported = True diff --git a/test/CodeGen/ARM/arm-modifier.ll b/test/CodeGen/ARM/arm-modifier.ll index 5e12d8e035..c747016634 100644 --- a/test/CodeGen/ARM/arm-modifier.ll +++ b/test/CodeGen/ARM/arm-modifier.ll @@ -61,8 +61,7 @@ ret void define i64 @f4(i64* %val) nounwind { entry: ;CHECK: f4 - ;CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], {{r[0-9]?[13579]}}, [r0] - ;CHECK: mov r0, [[REG1]] + ;CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], {{r[0-9]?[13579]}}, [r{{[0-9]+}}] %0 = tail call i64 asm sideeffect "ldrexd $0, ${0:H}, [$1]", "=&r,r,*Qo"(i64* %val, i64* %val) nounwind ret i64 %0 } diff --git a/test/CodeGen/ARM/atomic-64bit.ll b/test/CodeGen/ARM/atomic-64bit.ll index 69da6221b7..f2c7305ff3 100644 --- a/test/CodeGen/ARM/atomic-64bit.ll +++ b/test/CodeGen/ARM/atomic-64bit.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB define i64 @test1(i64* %ptr, i64 %val) { ; CHECK: test1: @@ -10,6 +11,17 @@ define i64 @test1(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test1: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: adds.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB: adc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw add i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -24,6 +36,17 @@ define i64 @test2(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test2: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: subs.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB: sbc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw sub i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -38,6 +61,17 @@ define i64 @test3(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test3: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: and.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw and i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -52,6 +86,17 @@ define i64 @test4(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test4: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: orr.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw or i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -66,6 +111,17 @@ define i64 @test5(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test5: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: eor.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw xor i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -78,6 +134,15 @@ define i64 @test6(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test6: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -93,6 +158,19 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test7: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: cmp [[REG1]] +; CHECK-THUMB: it eq +; CHECK-THUMB: cmpeq [[REG2]] +; CHECK-THUMB: bne +; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst ret i64 %r } @@ -109,6 +187,18 @@ define i64 @test8(i64* %ptr) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test8: +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: cmp [[REG1]] +; CHECK-THUMB: it eq +; CHECK-THUMB: cmpeq [[REG2]] +; CHECK-THUMB: bne +; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = load atomic i64* %ptr seq_cst, align 8 ret i64 %r } @@ -123,6 +213,15 @@ define void @test9(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test9: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + store atomic i64 %val, i64* %ptr seq_cst, align 8 ret void } @@ -133,11 +232,23 @@ define i64 @test10(i64* %ptr, i64 %val) { ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] ; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] -; CHECK: ble +; CHECK: blt ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test10: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB: blt +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw min i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -148,11 +259,24 @@ define i64 @test11(i64* %ptr, i64 %val) { ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] ; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]] ; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]] -; CHECK: bls +; CHECK: blo ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + + +; CHECK-THUMB: test11: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB: blo +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw umin i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -168,6 +292,18 @@ define i64 @test12(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test12: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB: bge +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish + %r = atomicrmw max i64* %ptr, i64 %val seq_cst ret i64 %r } @@ -183,6 +319,17 @@ define i64 @test13(i64* %ptr, i64 %val) { ; CHECK: cmp ; CHECK: bne ; CHECK: dmb ish + +; CHECK-THUMB: test13: +; CHECK-THUMB: dmb ish +; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] +; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]] +; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]] +; CHECK-THUMB: bhs +; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] +; CHECK-THUMB: cmp +; CHECK-THUMB: bne +; CHECK-THUMB: dmb ish %r = atomicrmw umax i64* %ptr, i64 %val seq_cst ret i64 %r } diff --git a/test/CodeGen/ARM/avoid-cpsr-rmw.ll b/test/CodeGen/ARM/avoid-cpsr-rmw.ll index 96e83dd88e..d98925ef8f 100644 --- a/test/CodeGen/ARM/avoid-cpsr-rmw.ll +++ b/test/CodeGen/ARM/avoid-cpsr-rmw.ll @@ -49,3 +49,37 @@ while.body: while.end: ret void } + +; Allow partial CPSR dependency when code size is the priority. +; rdar://12878928 +define void @t3(i32* nocapture %ptr1, i32* %ptr2, i32 %c) nounwind minsize { +entry: +; CHECK: t3: + %tobool7 = icmp eq i32* %ptr2, null + br i1 %tobool7, label %while.end, label %while.body + +while.body: +; CHECK: while.body +; CHECK: mul r{{[0-9]+}} +; CHECK: muls + %ptr1.addr.09 = phi i32* [ %add.ptr, %while.body ], [ %ptr1, %entry ] + %ptr2.addr.08 = phi i32* [ %incdec.ptr, %while.body ], [ %ptr2, %entry ] + %0 = load i32* %ptr1.addr.09, align 4 + %arrayidx1 = getelementptr inbounds i32* %ptr1.addr.09, i32 1 + %1 = load i32* %arrayidx1, align 4 + %arrayidx3 = getelementptr inbounds i32* %ptr1.addr.09, i32 2 + %2 = load i32* %arrayidx3, align 4 + %arrayidx4 = getelementptr inbounds i32* %ptr1.addr.09, i32 3 + %3 = load i32* %arrayidx4, align 4 + %add.ptr = getelementptr inbounds i32* %ptr1.addr.09, i32 4 + %mul = mul i32 %1, %0 + %mul5 = mul i32 %mul, %2 + %mul6 = mul i32 %mul5, %3 + store i32 %mul6, i32* %ptr2.addr.08, align 4 + %incdec.ptr = getelementptr inbounds i32* %ptr2.addr.08, i32 -1 + %tobool = icmp eq i32* %incdec.ptr, null + br i1 %tobool, label %while.end, label %while.body + +while.end: + ret void +} diff --git a/test/CodeGen/ARM/bfx.ll b/test/CodeGen/ARM/bfx.ll index 519c1353a3..394da9e157 100644 --- a/test/CodeGen/ARM/bfx.ll +++ b/test/CodeGen/ARM/bfx.ll @@ -26,3 +26,28 @@ define i32 @ubfx2(i32 %a) { ret i32 %t2 } +; rdar://12870177 +define i32 @ubfx_opt(i32* nocapture %ctx, i32 %x) nounwind readonly ssp { +entry: +; CHECK: ubfx_opt +; CHECK: lsr [[REG1:(lr|r[0-9]+)]], r1, #24 +; CHECK: ldr {{lr|r[0-9]+}}, [r0, [[REG1]], lsl #2] +; CHECK: ubfx [[REG2:(lr|r[0-9]+)]], r1, #16, #8 +; CHECK: ldr {{lr|r[0-9]+}}, [r0, [[REG2]], lsl #2] +; CHECK: ubfx [[REG3:(lr|r[0-9]+)]], r1, #8, #8 +; CHECK: ldr {{lr|r[0-9]+}}, [r0, [[REG3]], lsl #2] + %and = lshr i32 %x, 8 + %shr = and i32 %and, 255 + %and1 = lshr i32 %x, 16 + %shr2 = and i32 %and1, 255 + %shr4 = lshr i32 %x, 24 + %arrayidx = getelementptr inbounds i32* %ctx, i32 %shr4 + %0 = load i32* %arrayidx, align 4 + %arrayidx5 = getelementptr inbounds i32* %ctx, i32 %shr2 + %1 = load i32* %arrayidx5, align 4 + %add = add i32 %1, %0 + %arrayidx6 = getelementptr inbounds i32* %ctx, i32 %shr + %2 = load i32* %arrayidx6, align 4 + %add7 = add i32 %add, %2 + ret i32 %add7 +} diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll index 94edff5c0b..58fbbda0f6 100644 --- a/test/CodeGen/ARM/call-tc.ll +++ b/test/CodeGen/ARM/call-tc.ll @@ -103,7 +103,6 @@ define i32 @t8(i32 %x) nounwind ssp { entry: ; CHECKT2D: t8: ; CHECKT2D-NOT: push -; CHECKT2D-NOT %and = and i32 %x, 1 %tobool = icmp eq i32 %and, 0 br i1 %tobool, label %if.end, label %if.then diff --git a/test/CodeGen/ARM/debug-info-arg.ll b/test/CodeGen/ARM/debug-info-arg.ll index a7b44e6fe7..1694d6412f 100644 --- a/test/CodeGen/ARM/debug-info-arg.ll +++ b/test/CodeGen/ARM/debug-info-arg.ll @@ -30,29 +30,29 @@ declare void @foobar(i64, i64) declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1} -!llvm.dbg.lv.foo = !{!5, !13, !14, !17, !18, !19} +!30 = metadata !{metadata !1} +!31 = metadata !{metadata !5, metadata !13, metadata !14, metadata !17, metadata !18, metadata!19} -!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !"Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void (%struct.tag_s*, %struct.tag_s*, i64, i64, %struct.tag_s*, %struct.tag_s*)* @foo, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !"Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !30, null, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void (%struct.tag_s*, %struct.tag_s*, i64, i64, %struct.tag_s*, %struct.tag_s*)* @foo, null, null, metadata !31, i32 11} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{null} -!5 = metadata !{i32 590081, metadata !1, metadata !"this", metadata !2, i32 16777227, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] -!6 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !7} ; [ DW_TAG_pointer_type ] -!7 = metadata !{i32 589843, metadata !0, metadata !"tag_s", metadata !2, i32 5, i64 96, i64 32, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!5 = metadata !{i32 786689, metadata !1, metadata !"this", metadata !2, i32 16777227, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!6 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !7} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 786451, metadata !0, metadata !"tag_s", metadata !2, i32 5, i64 96, i64 32, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_structure_type ] !8 = metadata !{metadata !9, metadata !11, metadata !12} -!9 = metadata !{i32 589837, metadata !7, metadata !"x", metadata !2, i32 6, i64 32, i64 32, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] -!10 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!11 = metadata !{i32 589837, metadata !7, metadata !"y", metadata !2, i32 7, i64 32, i64 32, i64 32, i32 0, metadata !10} ; [ DW_TAG_member ] -!12 = metadata !{i32 589837, metadata !7, metadata !"z", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !10} ; [ DW_TAG_member ] -!13 = metadata !{i32 590081, metadata !1, metadata !"c", metadata !2, i32 33554443, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] -!14 = metadata !{i32 590081, metadata !1, metadata !"x", metadata !2, i32 50331659, metadata !15, i32 0} ; [ DW_TAG_arg_variable ] -!15 = metadata !{i32 589846, metadata !0, metadata !"UInt64", metadata !2, i32 1, i64 0, i64 0, i64 0, i32 0, metadata !16} ; [ DW_TAG_typedef ] -!16 = metadata !{i32 589860, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!17 = metadata !{i32 590081, metadata !1, metadata !"y", metadata !2, i32 67108875, metadata !15, i32 0} ; [ DW_TAG_arg_variable ] -!18 = metadata !{i32 590081, metadata !1, metadata !"ptr1", metadata !2, i32 83886091, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 590081, metadata !1, metadata !"ptr2", metadata !2, i32 100663307, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!9 = metadata !{i32 786445, metadata !7, metadata !"x", metadata !2, i32 6, i64 32, i64 32, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] +!10 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!11 = metadata !{i32 786445, metadata !7, metadata !"y", metadata !2, i32 7, i64 32, i64 32, i64 32, i32 0, metadata !10} ; [ DW_TAG_member ] +!12 = metadata !{i32 786445, metadata !7, metadata !"z", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !10} ; [ DW_TAG_member ] +!13 = metadata !{i32 786689, metadata !1, metadata !"c", metadata !2, i32 33554443, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 786689, metadata !1, metadata !"x", metadata !2, i32 50331659, metadata !15, i32 0, null} ; [ DW_TAG_arg_variable ] +!15 = metadata !{i32 786454, metadata !0, metadata !"UInt64", metadata !2, i32 1, i64 0, i64 0, i64 0, i32 0, metadata !16} ; [ DW_TAG_typedef ] +!16 = metadata !{i32 786468, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!17 = metadata !{i32 786689, metadata !1, metadata !"y", metadata !2, i32 67108875, metadata !15, i32 0, null} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 786689, metadata !1, metadata !"ptr1", metadata !2, i32 83886091, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786689, metadata !1, metadata !"ptr2", metadata !2, i32 100663307, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] !20 = metadata !{i32 11, i32 24, metadata !1, null} !21 = metadata !{i32 11, i32 44, metadata !1, null} !22 = metadata !{i32 11, i32 54, metadata !1, null} @@ -60,6 +60,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !24 = metadata !{i32 11, i32 81, metadata !1, null} !25 = metadata !{i32 11, i32 101, metadata !1, null} !26 = metadata !{i32 12, i32 3, metadata !27, null} -!27 = metadata !{i32 589835, metadata !1, i32 11, i32 107, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!27 = metadata !{i32 786443, metadata !1, i32 11, i32 107, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] !28 = metadata !{i32 13, i32 5, metadata !27, null} !29 = metadata !{i32 14, i32 1, metadata !27, null} diff --git a/test/CodeGen/ARM/debug-info-blocks.ll b/test/CodeGen/ARM/debug-info-blocks.ll index 0ad0a15ca3..2cb24bd11e 100644 --- a/test/CodeGen/ARM/debug-info-blocks.ll +++ b/test/CodeGen/ARM/debug-info-blocks.ll @@ -93,152 +93,152 @@ define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %load } !llvm.dbg.cu = !{!0} -!llvm.dbg.enum = !{!1, !1, !5, !5, !9, !14, !19, !19, !14, !14, !14, !19, !19, !19} -!llvm.dbg.sp = !{!23} +!147 = metadata !{metadata !1, metadata !1, metadata !5, metadata !5, metadata !9, metadata !14, metadata !19, metadata !19, metadata !14, metadata !14, metadata !14, metadata !19, metadata !19, metadata !19} +!148 = metadata !{metadata !23} -!0 = metadata !{i32 589841, i32 0, i32 16, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !"Apple clang version 2.1", i1 true, i1 false, metadata !"", i32 2} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589828, metadata !0, metadata !"", metadata !2, i32 248, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !3, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -!2 = metadata !{i32 589865, metadata !"header.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!0 = metadata !{i32 786449, i32 0, i32 16, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !"Apple clang version 2.1", i1 true, i1 false, metadata !"", i32 2, metadata !147, null, metadata !148, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786433, metadata !0, metadata !"", metadata !2, i32 248, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !3, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!2 = metadata !{i32 786473, metadata !"header.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !3 = metadata !{metadata !4} -!4 = metadata !{i32 589864, metadata !"Ver1", i64 0} ; [ DW_TAG_enumerator ] -!5 = metadata !{i32 589828, metadata !0, metadata !"Mode", metadata !6, i32 79, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !7, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -!6 = metadata !{i32 589865, metadata !"header2.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!4 = metadata !{i32 786472, metadata !"Ver1", i64 0} ; [ DW_TAG_enumerator ] +!5 = metadata !{i32 786433, metadata !0, metadata !"Mode", metadata !6, i32 79, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !7, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!6 = metadata !{i32 786473, metadata !"header2.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !7 = metadata !{metadata !8} -!8 = metadata !{i32 589864, metadata !"One", i64 0} ; [ DW_TAG_enumerator ] -!9 = metadata !{i32 589828, metadata !0, metadata !"", metadata !10, i32 15, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !11, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -!10 = metadata !{i32 589865, metadata !"header3.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!8 = metadata !{i32 786472, metadata !"One", i64 0} ; [ DW_TAG_enumerator ] +!9 = metadata !{i32 786433, metadata !0, metadata !"", metadata !10, i32 15, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !11, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!10 = metadata !{i32 786473, metadata !"header3.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !11 = metadata !{metadata !12, metadata !13} -!12 = metadata !{i32 589864, metadata !"Unknown", i64 0} ; [ DW_TAG_enumerator ] -!13 = metadata !{i32 589864, metadata !"Known", i64 1} ; [ DW_TAG_enumerator ] -!14 = metadata !{i32 589828, metadata !0, metadata !"", metadata !15, i32 20, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !16, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -!15 = metadata !{i32 589865, metadata !"Private.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!12 = metadata !{i32 786472, metadata !"Unknown", i64 0} ; [ DW_TAG_enumerator ] +!13 = metadata !{i32 786472, metadata !"Known", i64 1} ; [ DW_TAG_enumerator ] +!14 = metadata !{i32 786433, metadata !0, metadata !"", metadata !15, i32 20, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !16, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!15 = metadata !{i32 786473, metadata !"Private.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !16 = metadata !{metadata !17, metadata !18} -!17 = metadata !{i32 589864, metadata !"Single", i64 0} ; [ DW_TAG_enumerator ] -!18 = metadata !{i32 589864, metadata !"Double", i64 1} ; [ DW_TAG_enumerator ] -!19 = metadata !{i32 589828, metadata !0, metadata !"", metadata !20, i32 14, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !21, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] -!20 = metadata !{i32 589865, metadata !"header4.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!17 = metadata !{i32 786472, metadata !"Single", i64 0} ; [ DW_TAG_enumerator ] +!18 = metadata !{i32 786472, metadata !"Double", i64 1} ; [ DW_TAG_enumerator ] +!19 = metadata !{i32 786433, metadata !0, metadata !"", metadata !20, i32 14, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !21, i32 0, i32 0} ; [ DW_TAG_enumeration_type ] +!20 = metadata !{i32 786473, metadata !"header4.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !21 = metadata !{metadata !22} -!22 = metadata !{i32 589864, metadata !"Eleven", i64 0} ; [ DW_TAG_enumerator ] -!23 = metadata !{i32 589870, i32 0, metadata !24, metadata !"foobar_func_block_invoke_0", metadata !"foobar_func_block_invoke_0", metadata !"", metadata !24, i32 609, metadata !25, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (i8*, %0*, [4 x i32], [4 x i32])* @foobar_func_block_invoke_0, null, null} ; [ DW_TAG_subprogram ] -!24 = metadata !{i32 589865, metadata !"MyLibrary.m", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] -!25 = metadata !{i32 589845, metadata !24, metadata !"", metadata !24, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !26, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!22 = metadata !{i32 786472, metadata !"Eleven", i64 0} ; [ DW_TAG_enumerator ] +!23 = metadata !{i32 786478, i32 0, metadata !24, metadata !"foobar_func_block_invoke_0", metadata !"foobar_func_block_invoke_0", metadata !"", metadata !24, i32 609, metadata !25, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (i8*, %0*, [4 x i32], [4 x i32])* @foobar_func_block_invoke_0, null, null, null, i32 609} ; [ DW_TAG_subprogram ] +!24 = metadata !{i32 786473, metadata !"MyLibrary.m", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!25 = metadata !{i32 786453, metadata !24, metadata !"", metadata !24, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !26, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !26 = metadata !{null} -!27 = metadata !{i32 590081, metadata !23, metadata !".block_descriptor", metadata !24, i32 16777825, metadata !28, i32 64} ; [ DW_TAG_arg_variable ] -!28 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !29} ; [ DW_TAG_pointer_type ] -!29 = metadata !{i32 589843, metadata !24, metadata !"__block_literal_14", metadata !24, i32 609, i64 256, i64 32, i32 0, i32 0, i32 0, metadata !30, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!27 = metadata !{i32 786689, metadata !23, metadata !".block_descriptor", metadata !24, i32 16777825, metadata !28, i32 64, null} ; [ DW_TAG_arg_variable ] +!28 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !29} ; [ DW_TAG_pointer_type ] +!29 = metadata !{i32 786451, metadata !24, metadata !"__block_literal_14", metadata !24, i32 609, i64 256, i64 32, i32 0, i32 0, i32 0, metadata !30, i32 0, i32 0} ; [ DW_TAG_structure_type ] !30 = metadata !{metadata !31, metadata !33, metadata !35, metadata !36, metadata !37, metadata !48, metadata !89, metadata !124} -!31 = metadata !{i32 589837, metadata !24, metadata !"__isa", metadata !24, i32 609, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] -!32 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!33 = metadata !{i32 589837, metadata !24, metadata !"__flags", metadata !24, i32 609, i64 32, i64 32, i64 32, i32 0, metadata !34} ; [ DW_TAG_member ] -!34 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!35 = metadata !{i32 589837, metadata !24, metadata !"__reserved", metadata !24, i32 609, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] -!36 = metadata !{i32 589837, metadata !24, metadata !"__FuncPtr", metadata !24, i32 609, i64 32, i64 32, i64 96, i32 0, metadata !32} ; [ DW_TAG_member ] -!37 = metadata !{i32 589837, metadata !24, metadata !"__descriptor", metadata !24, i32 609, i64 32, i64 32, i64 128, i32 0, metadata !38} ; [ DW_TAG_member ] -!38 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !39} ; [ DW_TAG_pointer_type ] -!39 = metadata !{i32 589843, metadata !0, metadata !"__block_descriptor_withcopydispose", metadata !40, i32 307, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !41, i32 0, i32 0} ; [ DW_TAG_structure_type ] -!40 = metadata !{i32 589865, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!31 = metadata !{i32 786445, metadata !24, metadata !"__isa", metadata !24, i32 609, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] +!32 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!33 = metadata !{i32 786445, metadata !24, metadata !"__flags", metadata !24, i32 609, i64 32, i64 32, i64 32, i32 0, metadata !34} ; [ DW_TAG_member ] +!34 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!35 = metadata !{i32 786445, metadata !24, metadata !"__reserved", metadata !24, i32 609, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] +!36 = metadata !{i32 786445, metadata !24, metadata !"__FuncPtr", metadata !24, i32 609, i64 32, i64 32, i64 96, i32 0, metadata !32} ; [ DW_TAG_member ] +!37 = metadata !{i32 786445, metadata !24, metadata !"__descriptor", metadata !24, i32 609, i64 32, i64 32, i64 128, i32 0, metadata !38} ; [ DW_TAG_member ] +!38 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !39} ; [ DW_TAG_pointer_type ] +!39 = metadata !{i32 786451, metadata !0, metadata !"__block_descriptor_withcopydispose", metadata !40, i32 307, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !41, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!40 = metadata !{i32 786473, metadata !"MyLibrary.i", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !41 = metadata !{metadata !42, metadata !44, metadata !45, metadata !47} -!42 = metadata !{i32 589837, metadata !40, metadata !"reserved", metadata !40, i32 307, i64 32, i64 32, i64 0, i32 0, metadata !43} ; [ DW_TAG_member ] -!43 = metadata !{i32 589860, metadata !0, metadata !"long unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!44 = metadata !{i32 589837, metadata !40, metadata !"Size", metadata !40, i32 307, i64 32, i64 32, i64 32, i32 0, metadata !43} ; [ DW_TAG_member ] -!45 = metadata !{i32 589837, metadata !40, metadata !"CopyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 64, i32 0, metadata !46} ; [ DW_TAG_member ] -!46 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] -!47 = metadata !{i32 589837, metadata !40, metadata !"DestroyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 96, i32 0, metadata !46} ; [ DW_TAG_member ] -!48 = metadata !{i32 589837, metadata !24, metadata !"mydata", metadata !24, i32 609, i64 32, i64 32, i64 160, i32 0, metadata !49} ; [ DW_TAG_member ] -!49 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !50} ; [ DW_TAG_pointer_type ] -!50 = metadata !{i32 589843, metadata !24, metadata !"", metadata !24, i32 0, i64 224, i64 0, i32 0, i32 16, i32 0, metadata !51, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!42 = metadata !{i32 786445, metadata !40, metadata !"reserved", metadata !40, i32 307, i64 32, i64 32, i64 0, i32 0, metadata !43} ; [ DW_TAG_member ] +!43 = metadata !{i32 786468, metadata !0, metadata !"long unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!44 = metadata !{i32 786445, metadata !40, metadata !"Size", metadata !40, i32 307, i64 32, i64 32, i64 32, i32 0, metadata !43} ; [ DW_TAG_member ] +!45 = metadata !{i32 786445, metadata !40, metadata !"CopyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 64, i32 0, metadata !46} ; [ DW_TAG_member ] +!46 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] +!47 = metadata !{i32 786445, metadata !40, metadata !"DestroyFuncPtr", metadata !40, i32 307, i64 32, i64 32, i64 96, i32 0, metadata !46} ; [ DW_TAG_member ] +!48 = metadata !{i32 786445, metadata !24, metadata !"mydata", metadata !24, i32 609, i64 32, i64 32, i64 160, i32 0, metadata !49} ; [ DW_TAG_member ] +!49 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 0, i64 0, i32 0, metadata !50} ; [ DW_TAG_pointer_type ] +!50 = metadata !{i32 786451, metadata !24, metadata !"", metadata !24, i32 0, i64 224, i64 0, i32 0, i32 16, i32 0, metadata !51, i32 0, i32 0} ; [ DW_TAG_structure_type ] !51 = metadata !{metadata !52, metadata !53, metadata !54, metadata !55, metadata !56, metadata !57, metadata !58} -!52 = metadata !{i32 589837, metadata !24, metadata !"__isa", metadata !24, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] -!53 = metadata !{i32 589837, metadata !24, metadata !"__forwarding", metadata !24, i32 0, i64 32, i64 32, i64 32, i32 0, metadata !32} ; [ DW_TAG_member ] -!54 = metadata !{i32 589837, metadata !24, metadata !"__flags", metadata !24, i32 0, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] -!55 = metadata !{i32 589837, metadata !24, metadata !"__size", metadata !24, i32 0, i64 32, i64 32, i64 96, i32 0, metadata !34} ; [ DW_TAG_member ] -!56 = metadata !{i32 589837, metadata !24, metadata !"__copy_helper", metadata !24, i32 0, i64 32, i64 32, i64 128, i32 0, metadata !32} ; [ DW_TAG_member ] -!57 = metadata !{i32 589837, metadata !24, metadata !"__destroy_helper", metadata !24, i32 0, i64 32, i64 32, i64 160, i32 0, metadata !32} ; [ DW_TAG_member ] -!58 = metadata !{i32 589837, metadata !24, metadata !"mydata", metadata !24, i32 0, i64 32, i64 32, i64 192, i32 0, metadata !59} ; [ DW_TAG_member ] -!59 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !60} ; [ DW_TAG_pointer_type ] -!60 = metadata !{i32 589843, metadata !24, metadata !"UIMydata", metadata !61, i32 26, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !62, i32 16, i32 0} ; [ DW_TAG_structure_type ] -!61 = metadata !{i32 589865, metadata !"header11.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!52 = metadata !{i32 786445, metadata !24, metadata !"__isa", metadata !24, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_member ] +!53 = metadata !{i32 786445, metadata !24, metadata !"__forwarding", metadata !24, i32 0, i64 32, i64 32, i64 32, i32 0, metadata !32} ; [ DW_TAG_member ] +!54 = metadata !{i32 786445, metadata !24, metadata !"__flags", metadata !24, i32 0, i64 32, i64 32, i64 64, i32 0, metadata !34} ; [ DW_TAG_member ] +!55 = metadata !{i32 786445, metadata !24, metadata !"__size", metadata !24, i32 0, i64 32, i64 32, i64 96, i32 0, metadata !34} ; [ DW_TAG_member ] +!56 = metadata !{i32 786445, metadata !24, metadata !"__copy_helper", metadata !24, i32 0, i64 32, i64 32, i64 128, i32 0, metadata !32} ; [ DW_TAG_member ] +!57 = metadata !{i32 786445, metadata !24, metadata !"__destroy_helper", metadata !24, i32 0, i64 32, i64 32, i64 160, i32 0, metadata !32} ; [ DW_TAG_member ] +!58 = metadata !{i32 786445, metadata !24, metadata !"mydata", metadata !24, i32 0, i64 32, i64 32, i64 192, i32 0, metadata !59} ; [ DW_TAG_member ] +!59 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !60} ; [ DW_TAG_pointer_type ] +!60 = metadata !{i32 786451, metadata !24, metadata !"UIMydata", metadata !61, i32 26, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !62, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!61 = metadata !{i32 786473, metadata !"header11.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !62 = metadata !{metadata !63, metadata !71, metadata !75, metadata !79} -!63 = metadata !{i32 589852, metadata !60, null, metadata !61, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] -!64 = metadata !{i32 589843, metadata !40, metadata !"NSO", metadata !65, i32 66, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !66, i32 16, i32 0} ; [ DW_TAG_structure_type ] -!65 = metadata !{i32 589865, metadata !"NSO.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!63 = metadata !{i32 786460, metadata !60, null, metadata !61, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!64 = metadata !{i32 786451, metadata !40, metadata !"NSO", metadata !65, i32 66, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !66, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!65 = metadata !{i32 786473, metadata !"NSO.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !66 = metadata !{metadata !67} -!67 = metadata !{i32 589837, metadata !65, metadata !"isa", metadata !65, i32 67, i64 32, i64 32, i64 0, i32 2, metadata !68, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!68 = metadata !{i32 589846, metadata !0, metadata !"Class", metadata !40, i32 197, i64 0, i64 0, i64 0, i32 0, metadata !69} ; [ DW_TAG_typedef ] -!69 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !70} ; [ DW_TAG_pointer_type ] -!70 = metadata !{i32 589843, metadata !0, metadata !"objc_class", metadata !40, i32 0, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] -!71 = metadata !{i32 589837, metadata !61, metadata !"_mydataRef", metadata !61, i32 28, i64 32, i64 32, i64 32, i32 0, metadata !72, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!72 = metadata !{i32 589846, metadata !0, metadata !"CFTypeRef", metadata !24, i32 313, i64 0, i64 0, i64 0, i32 0, metadata !73} ; [ DW_TAG_typedef ] -!73 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !74} ; [ DW_TAG_pointer_type ] -!74 = metadata !{i32 589862, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null} ; [ DW_TAG_const_type ] -!75 = metadata !{i32 589837, metadata !61, metadata !"_scale", metadata !61, i32 29, i64 32, i64 32, i64 64, i32 0, metadata !76, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!76 = metadata !{i32 589846, metadata !0, metadata !"Float", metadata !77, i32 89, i64 0, i64 0, i64 0, i32 0, metadata !78} ; [ DW_TAG_typedef ] -!77 = metadata !{i32 589865, metadata !"header12.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] -!78 = metadata !{i32 589860, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!79 = metadata !{i32 589837, metadata !61, metadata !"_mydataFlags", metadata !61, i32 37, i64 8, i64 8, i64 96, i32 0, metadata !80, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!80 = metadata !{i32 589843, metadata !0, metadata !"", metadata !61, i32 30, i64 8, i64 8, i32 0, i32 0, i32 0, metadata !81, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!67 = metadata !{i32 786445, metadata !65, metadata !"isa", metadata !65, i32 67, i64 32, i64 32, i64 0, i32 2, metadata !68, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!68 = metadata !{i32 786454, metadata !0, metadata !"Class", metadata !40, i32 197, i64 0, i64 0, i64 0, i32 0, metadata !69} ; [ DW_TAG_typedef ] +!69 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !70} ; [ DW_TAG_pointer_type ] +!70 = metadata !{i32 786451, metadata !0, metadata !"objc_class", metadata !40, i32 0, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!71 = metadata !{i32 786445, metadata !61, metadata !"_mydataRef", metadata !61, i32 28, i64 32, i64 32, i64 32, i32 0, metadata !72, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!72 = metadata !{i32 786454, metadata !0, metadata !"CFTypeRef", metadata !24, i32 313, i64 0, i64 0, i64 0, i32 0, metadata !73} ; [ DW_TAG_typedef ] +!73 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !74} ; [ DW_TAG_pointer_type ] +!74 = metadata !{i32 786470, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null} ; [ DW_TAG_const_type ] +!75 = metadata !{i32 786445, metadata !61, metadata !"_scale", metadata !61, i32 29, i64 32, i64 32, i64 64, i32 0, metadata !76, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!76 = metadata !{i32 786454, metadata !0, metadata !"Float", metadata !77, i32 89, i64 0, i64 0, i64 0, i32 0, metadata !78} ; [ DW_TAG_typedef ] +!77 = metadata !{i32 786473, metadata !"header12.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!78 = metadata !{i32 786468, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!79 = metadata !{i32 786445, metadata !61, metadata !"_mydataFlags", metadata !61, i32 37, i64 8, i64 8, i64 96, i32 0, metadata !80, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!80 = metadata !{i32 786451, metadata !0, metadata !"", metadata !61, i32 30, i64 8, i64 8, i32 0, i32 0, i32 0, metadata !81, i32 0, i32 0} ; [ DW_TAG_structure_type ] !81 = metadata !{metadata !82, metadata !84, metadata !85, metadata !86, metadata !87, metadata !88} -!82 = metadata !{i32 589837, metadata !61, metadata !"named", metadata !61, i32 31, i64 1, i64 32, i64 0, i32 0, metadata !83} ; [ DW_TAG_member ] -!83 = metadata !{i32 589860, metadata !0, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!84 = metadata !{i32 589837, metadata !61, metadata !"mydataO", metadata !61, i32 32, i64 3, i64 32, i64 1, i32 0, metadata !83} ; [ DW_TAG_member ] -!85 = metadata !{i32 589837, metadata !61, metadata !"cached", metadata !61, i32 33, i64 1, i64 32, i64 4, i32 0, metadata !83} ; [ DW_TAG_member ] -!86 = metadata !{i32 589837, metadata !61, metadata !"hasBeenCached", metadata !61, i32 34, i64 1, i64 32, i64 5, i32 0, metadata !83} ; [ DW_TAG_member ] -!87 = metadata !{i32 589837, metadata !61, metadata !"hasPattern", metadata !61, i32 35, i64 1, i64 32, i64 6, i32 0, metadata !83} ; [ DW_TAG_member ] -!88 = metadata !{i32 589837, metadata !61, metadata !"isCIMydata", metadata !61, i32 36, i64 1, i64 32, i64 7, i32 0, metadata !83} ; [ DW_TAG_member ] -!89 = metadata !{i32 589837, metadata !24, metadata !"self", metadata !24, i32 609, i64 32, i64 32, i64 192, i32 0, metadata !90} ; [ DW_TAG_member ] -!90 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !91} ; [ DW_TAG_pointer_type ] -!91 = metadata !{i32 589843, metadata !40, metadata !"MyWork", metadata !24, i32 36, i64 384, i64 32, i32 0, i32 0, i32 0, metadata !92, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!82 = metadata !{i32 786445, metadata !61, metadata !"named", metadata !61, i32 31, i64 1, i64 32, i64 0, i32 0, metadata !83} ; [ DW_TAG_member ] +!83 = metadata !{i32 786468, metadata !0, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!84 = metadata !{i32 786445, metadata !61, metadata !"mydataO", metadata !61, i32 32, i64 3, i64 32, i64 1, i32 0, metadata !83} ; [ DW_TAG_member ] +!85 = metadata !{i32 786445, metadata !61, metadata !"cached", metadata !61, i32 33, i64 1, i64 32, i64 4, i32 0, metadata !83} ; [ DW_TAG_member ] +!86 = metadata !{i32 786445, metadata !61, metadata !"hasBeenCached", metadata !61, i32 34, i64 1, i64 32, i64 5, i32 0, metadata !83} ; [ DW_TAG_member ] +!87 = metadata !{i32 786445, metadata !61, metadata !"hasPattern", metadata !61, i32 35, i64 1, i64 32, i64 6, i32 0, metadata !83} ; [ DW_TAG_member ] +!88 = metadata !{i32 786445, metadata !61, metadata !"isCIMydata", metadata !61, i32 36, i64 1, i64 32, i64 7, i32 0, metadata !83} ; [ DW_TAG_member ] +!89 = metadata !{i32 786445, metadata !24, metadata !"self", metadata !24, i32 609, i64 32, i64 32, i64 192, i32 0, metadata !90} ; [ DW_TAG_member ] +!90 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !91} ; [ DW_TAG_pointer_type ] +!91 = metadata !{i32 786451, metadata !40, metadata !"MyWork", metadata !24, i32 36, i64 384, i64 32, i32 0, i32 0, i32 0, metadata !92, i32 16, i32 0} ; [ DW_TAG_structure_type ] !92 = metadata !{metadata !93, metadata !98, metadata !101, metadata !107, metadata !123} -!93 = metadata !{i32 589852, metadata !91, null, metadata !24, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !94} ; [ DW_TAG_inheritance ] -!94 = metadata !{i32 589843, metadata !40, metadata !"twork", metadata !95, i32 43, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !96, i32 16, i32 0} ; [ DW_TAG_structure_type ] -!95 = metadata !{i32 589865, metadata !"header13.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!93 = metadata !{i32 786460, metadata !91, null, metadata !24, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !94} ; [ DW_TAG_inheritance ] +!94 = metadata !{i32 786451, metadata !40, metadata !"twork", metadata !95, i32 43, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !96, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!95 = metadata !{i32 786473, metadata !"header13.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !96 = metadata !{metadata !97} -!97 = metadata !{i32 589852, metadata !94, null, metadata !95, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] -!98 = metadata !{i32 589837, metadata !24, metadata !"_itemID", metadata !24, i32 38, i64 64, i64 32, i64 32, i32 1, metadata !99, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!99 = metadata !{i32 589846, metadata !0, metadata !"uint64_t", metadata !40, i32 55, i64 0, i64 0, i64 0, i32 0, metadata !100} ; [ DW_TAG_typedef ] -!100 = metadata !{i32 589860, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!101 = metadata !{i32 589837, metadata !24, metadata !"_library", metadata !24, i32 39, i64 32, i64 32, i64 96, i32 1, metadata !102, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!102 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !103} ; [ DW_TAG_pointer_type ] -!103 = metadata !{i32 589843, metadata !40, metadata !"MyLibrary2", metadata !104, i32 22, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !105, i32 16, i32 0} ; [ DW_TAG_structure_type ] -!104 = metadata !{i32 589865, metadata !"header14.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!97 = metadata !{i32 786460, metadata !94, null, metadata !95, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!98 = metadata !{i32 786445, metadata !24, metadata !"_itemID", metadata !24, i32 38, i64 64, i64 32, i64 32, i32 1, metadata !99, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!99 = metadata !{i32 786454, metadata !0, metadata !"uint64_t", metadata !40, i32 55, i64 0, i64 0, i64 0, i32 0, metadata !100} ; [ DW_TAG_typedef ] +!100 = metadata !{i32 786468, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!101 = metadata !{i32 786445, metadata !24, metadata !"_library", metadata !24, i32 39, i64 32, i64 32, i64 96, i32 1, metadata !102, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!102 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !103} ; [ DW_TAG_pointer_type ] +!103 = metadata !{i32 786451, metadata !40, metadata !"MyLibrary2", metadata !104, i32 22, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !105, i32 16, i32 0} ; [ DW_TAG_structure_type ] +!104 = metadata !{i32 786473, metadata !"header14.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !105 = metadata !{metadata !106} -!106 = metadata !{i32 589852, metadata !103, null, metadata !104, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] -!107 = metadata !{i32 589837, metadata !24, metadata !"_bounds", metadata !24, i32 40, i64 128, i64 32, i64 128, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!108 = metadata !{i32 589846, metadata !0, metadata !"CR", metadata !40, i32 33, i64 0, i64 0, i64 0, i32 0, metadata !109} ; [ DW_TAG_typedef ] -!109 = metadata !{i32 589843, metadata !0, metadata !"CR", metadata !77, i32 29, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !110, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!106 = metadata !{i32 786460, metadata !103, null, metadata !104, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !64} ; [ DW_TAG_inheritance ] +!107 = metadata !{i32 786445, metadata !24, metadata !"_bounds", metadata !24, i32 40, i64 128, i64 32, i64 128, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!108 = metadata !{i32 786454, metadata !0, metadata !"CR", metadata !40, i32 33, i64 0, i64 0, i64 0, i32 0, metadata !109} ; [ DW_TAG_typedef ] +!109 = metadata !{i32 786451, metadata !0, metadata !"CR", metadata !77, i32 29, i64 128, i64 32, i32 0, i32 0, i32 0, metadata !110, i32 0, i32 0} ; [ DW_TAG_structure_type ] !110 = metadata !{metadata !111, metadata !117} -!111 = metadata !{i32 589837, metadata !77, metadata !"origin", metadata !77, i32 30, i64 64, i64 32, i64 0, i32 0, metadata !112} ; [ DW_TAG_member ] -!112 = metadata !{i32 589846, metadata !0, metadata !"CP", metadata !77, i32 17, i64 0, i64 0, i64 0, i32 0, metadata !113} ; [ DW_TAG_typedef ] -!113 = metadata !{i32 589843, metadata !0, metadata !"CP", metadata !77, i32 13, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !114, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!111 = metadata !{i32 786445, metadata !77, metadata !"origin", metadata !77, i32 30, i64 64, i64 32, i64 0, i32 0, metadata !112} ; [ DW_TAG_member ] +!112 = metadata !{i32 786454, metadata !0, metadata !"CP", metadata !77, i32 17, i64 0, i64 0, i64 0, i32 0, metadata !113} ; [ DW_TAG_typedef ] +!113 = metadata !{i32 786451, metadata !0, metadata !"CP", metadata !77, i32 13, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !114, i32 0, i32 0} ; [ DW_TAG_structure_type ] !114 = metadata !{metadata !115, metadata !116} -!115 = metadata !{i32 589837, metadata !77, metadata !"x", metadata !77, i32 14, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] -!116 = metadata !{i32 589837, metadata !77, metadata !"y", metadata !77, i32 15, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] -!117 = metadata !{i32 589837, metadata !77, metadata !"size", metadata !77, i32 31, i64 64, i64 32, i64 64, i32 0, metadata !118} ; [ DW_TAG_member ] -!118 = metadata !{i32 589846, metadata !0, metadata !"Size", metadata !77, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !119} ; [ DW_TAG_typedef ] -!119 = metadata !{i32 589843, metadata !0, metadata !"Size", metadata !77, i32 21, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !120, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!115 = metadata !{i32 786445, metadata !77, metadata !"x", metadata !77, i32 14, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] +!116 = metadata !{i32 786445, metadata !77, metadata !"y", metadata !77, i32 15, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] +!117 = metadata !{i32 786445, metadata !77, metadata !"size", metadata !77, i32 31, i64 64, i64 32, i64 64, i32 0, metadata !118} ; [ DW_TAG_member ] +!118 = metadata !{i32 786454, metadata !0, metadata !"Size", metadata !77, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !119} ; [ DW_TAG_typedef ] +!119 = metadata !{i32 786451, metadata !0, metadata !"Size", metadata !77, i32 21, i64 64, i64 32, i32 0, i32 0, i32 0, metadata !120, i32 0, i32 0} ; [ DW_TAG_structure_type ] !120 = metadata !{metadata !121, metadata !122} -!121 = metadata !{i32 589837, metadata !77, metadata !"width", metadata !77, i32 22, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] -!122 = metadata !{i32 589837, metadata !77, metadata !"height", metadata !77, i32 23, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] -!123 = metadata !{i32 589837, metadata !24, metadata !"_data", metadata !24, i32 40, i64 128, i64 32, i64 256, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] -!124 = metadata !{i32 589837, metadata !24, metadata !"semi", metadata !24, i32 609, i64 32, i64 32, i64 224, i32 0, metadata !125} ; [ DW_TAG_member ] -!125 = metadata !{i32 589846, metadata !0, metadata !"d_t", metadata !24, i32 35, i64 0, i64 0, i64 0, i32 0, metadata !126} ; [ DW_TAG_typedef ] -!126 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !127} ; [ DW_TAG_pointer_type ] -!127 = metadata !{i32 589843, metadata !0, metadata !"my_struct", metadata !128, i32 49, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] -!128 = metadata !{i32 589865, metadata !"header15.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] +!121 = metadata !{i32 786445, metadata !77, metadata !"width", metadata !77, i32 22, i64 32, i64 32, i64 0, i32 0, metadata !76} ; [ DW_TAG_member ] +!122 = metadata !{i32 786445, metadata !77, metadata !"height", metadata !77, i32 23, i64 32, i64 32, i64 32, i32 0, metadata !76} ; [ DW_TAG_member ] +!123 = metadata !{i32 786445, metadata !24, metadata !"_data", metadata !24, i32 40, i64 128, i64 32, i64 256, i32 1, metadata !108, metadata !"", metadata !"", metadata !"", i32 0} ; [ DW_TAG_member ] +!124 = metadata !{i32 786445, metadata !24, metadata !"semi", metadata !24, i32 609, i64 32, i64 32, i64 224, i32 0, metadata !125} ; [ DW_TAG_member ] +!125 = metadata !{i32 786454, metadata !0, metadata !"d_t", metadata !24, i32 35, i64 0, i64 0, i64 0, i32 0, metadata !126} ; [ DW_TAG_typedef ] +!126 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !127} ; [ DW_TAG_pointer_type ] +!127 = metadata !{i32 786451, metadata !0, metadata !"my_struct", metadata !128, i32 49, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!128 = metadata !{i32 786473, metadata !"header15.h", metadata !"/Volumes/Sandbox/llvm", metadata !0} ; [ DW_TAG_file_type ] !129 = metadata !{i32 609, i32 144, metadata !23, null} -!130 = metadata !{i32 590081, metadata !23, metadata !"loadedMydata", metadata !24, i32 33555041, metadata !59, i32 0} ; [ DW_TAG_arg_variable ] +!130 = metadata !{i32 786689, metadata !23, metadata !"loadedMydata", metadata !24, i32 33555041, metadata !59, i32 0, null} ; [ DW_TAG_arg_variable ] !131 = metadata !{i32 609, i32 155, metadata !23, null} -!132 = metadata !{i32 590081, metadata !23, metadata !"bounds", metadata !24, i32 50332257, metadata !108, i32 0} ; [ DW_TAG_arg_variable ] +!132 = metadata !{i32 786689, metadata !23, metadata !"bounds", metadata !24, i32 50332257, metadata !108, i32 0, null} ; [ DW_TAG_arg_variable ] !133 = metadata !{i32 609, i32 175, metadata !23, null} -!134 = metadata !{i32 590081, metadata !23, metadata !"data", metadata !24, i32 67109473, metadata !108, i32 0} ; [ DW_TAG_arg_variable ] +!134 = metadata !{i32 786689, metadata !23, metadata !"data", metadata !24, i32 67109473, metadata !108, i32 0, null} ; [ DW_TAG_arg_variable ] !135 = metadata !{i32 609, i32 190, metadata !23, null} -!136 = metadata !{i32 590080, metadata !23, metadata !"mydata", metadata !24, i32 604, metadata !50, i32 0, i64 1, i64 20, i64 2, i64 1, i64 4, i64 2, i64 1, i64 24} ; [ DW_TAG_auto_variable ] +!136 = metadata !{i32 786688, metadata !23, metadata !"mydata", metadata !24, i32 604, metadata !50, i32 0, null, i64 1, i64 20, i64 2, i64 1, i64 4, i64 2, i64 1, i64 24} ; [ DW_TAG_auto_variable ] !137 = metadata !{i32 604, i32 49, metadata !23, null} -!138 = metadata !{i32 590080, metadata !23, metadata !"self", metadata !40, i32 604, metadata !90, i32 0, i64 1, i64 24} ; [ DW_TAG_auto_variable ] -!139 = metadata !{i32 590080, metadata !23, metadata !"semi", metadata !24, i32 607, metadata !125, i32 0, i64 1, i64 28} ; [ DW_TAG_auto_variable ] +!138 = metadata !{i32 786688, metadata !23, metadata !"self", metadata !40, i32 604, metadata !90, i32 0, null, i64 1, i64 24} ; [ DW_TAG_auto_variable ] +!139 = metadata !{i32 786688, metadata !23, metadata !"semi", metadata !24, i32 607, metadata !125, i32 0, null, i64 1, i64 28} ; [ DW_TAG_auto_variable ] !140 = metadata !{i32 607, i32 30, metadata !23, null} !141 = metadata !{i32 610, i32 17, metadata !142, null} -!142 = metadata !{i32 589835, metadata !23, i32 609, i32 200, metadata !24, i32 94} ; [ DW_TAG_lexical_block ] +!142 = metadata !{i32 786443, metadata !23, i32 609, i32 200, metadata !24, i32 94} ; [ DW_TAG_lexical_block ] !143 = metadata !{i32 611, i32 17, metadata !142, null} !144 = metadata !{i32 612, i32 17, metadata !142, null} !145 = metadata !{i32 613, i32 17, metadata !142, null} diff --git a/test/CodeGen/ARM/debug-info-branch-folding.ll b/test/CodeGen/ARM/debug-info-branch-folding.ll index a3a1fc0b2f..f241c069c3 100644 --- a/test/CodeGen/ARM/debug-info-branch-folding.ll +++ b/test/CodeGen/ARM/debug-info-branch-folding.ll @@ -3,7 +3,7 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32- target triple = "thumbv7-apple-macosx10.6.7" ;CHECK: vadd.f32 q4, q8, q8 -;CHECK-NEXT: Ltmp1 +;CHECK-NEXT: LBB0_1 ;CHECK:@DEBUG_VALUE: x <- Q4+0 ;CHECK-NEXT:@DEBUG_VALUE: y <- Q4+0 @@ -38,58 +38,58 @@ declare i32 @printf(i8* nocapture, ...) nounwind declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !10, !14} -!llvm.dbg.lv.test0001 = !{!18} -!llvm.dbg.lv.main = !{!19, !20, !24, !26, !27, !28, !29} -!llvm.dbg.lv.printFV = !{!30} +!50 = metadata !{metadata !0, metadata !10, metadata !14} +!51 = metadata !{metadata !18} +!52 = metadata !{metadata !19, metadata !20, metadata !24, metadata !26, metadata !27, metadata !28, metadata !29} +!53 = metadata !{metadata !30} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"test0001", metadata !"test0001", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, <4 x float> (float)* @test0001, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"build2.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"build2.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"test0001", metadata !"test0001", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, <4 x float> (float)* @test0001, null, null, metadata !51, i32 0} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"build2.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"build2.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !50, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589846, metadata !2, metadata !"v4f32", metadata !1, i32 14, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] -!6 = metadata !{i32 590083, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 128, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_vector_type ] -!7 = metadata !{i32 589860, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!5 = metadata !{i32 786454, metadata !2, metadata !"v4f32", metadata !1, i32 14, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] +!6 = metadata !{i32 786691, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 128, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_vector_type ] +!7 = metadata !{i32 786468, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] !8 = metadata !{metadata !9} -!9 = metadata !{i32 589857, i64 0, i64 4} ; [ DW_TAG_subrange_type ] -!10 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 59, metadata !11, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**, i1)* @main, null} ; [ DW_TAG_subprogram ] -!11 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!9 = metadata !{i32 786465, i64 0, i64 4} ; [ DW_TAG_subrange_type ] +!10 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 59, metadata !11, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**, i1)* @main, null, null, metadata !52, i32 0} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !12 = metadata !{metadata !13} -!13 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 589870, i32 0, metadata !15, metadata !"printFV", metadata !"printFV", metadata !"", metadata !15, i32 41, metadata !16, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ] -!15 = metadata !{i32 589865, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!16 = metadata !{i32 589845, metadata !15, metadata !"", metadata !15, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !17, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!13 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786478, i32 0, metadata !15, metadata !"printFV", metadata !"printFV", metadata !"", metadata !15, i32 41, metadata !16, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null, null, null, metadata !53, i32 0} ; [ DW_TAG_subprogram ] +!15 = metadata !{i32 786473, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!16 = metadata !{i32 786453, metadata !15, metadata !"", metadata !15, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !17, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !17 = metadata !{null} -!18 = metadata !{i32 590081, metadata !0, metadata !"a", metadata !1, i32 16777219, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 590081, metadata !10, metadata !"argc", metadata !1, i32 16777275, metadata !13, i32 0} ; [ DW_TAG_arg_variable ] -!20 = metadata !{i32 590081, metadata !10, metadata !"argv", metadata !1, i32 33554491, metadata !21, i32 0} ; [ DW_TAG_arg_variable ] -!21 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] -!22 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] -!23 = metadata !{i32 589860, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!24 = metadata !{i32 590080, metadata !25, metadata !"i", metadata !1, i32 60, metadata !13, i32 0} ; [ DW_TAG_auto_variable ] -!25 = metadata !{i32 589835, metadata !10, i32 59, i32 33, metadata !1, i32 14} ; [ DW_TAG_lexical_block ] -!26 = metadata !{i32 590080, metadata !25, metadata !"j", metadata !1, i32 60, metadata !13, i32 0} ; [ DW_TAG_auto_variable ] -!27 = metadata !{i32 590080, metadata !25, metadata !"x", metadata !1, i32 61, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!28 = metadata !{i32 590080, metadata !25, metadata !"y", metadata !1, i32 62, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!29 = metadata !{i32 590080, metadata !25, metadata !"z", metadata !1, i32 63, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!30 = metadata !{i32 590081, metadata !14, metadata !"F", metadata !15, i32 16777257, metadata !31, i32 0} ; [ DW_TAG_arg_variable ] -!31 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] -!32 = metadata !{i32 589846, metadata !2, metadata !"FV", metadata !15, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !33} ; [ DW_TAG_typedef ] -!33 = metadata !{i32 589847, metadata !2, metadata !"", metadata !15, i32 22, i64 128, i64 128, i64 0, i32 0, i32 0, metadata !34, i32 0, i32 0} ; [ DW_TAG_union_type ] +!18 = metadata !{i32 786689, metadata !0, metadata !"a", metadata !1, i32 16777219, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786689, metadata !10, metadata !"argc", metadata !1, i32 16777275, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 786689, metadata !10, metadata !"argv", metadata !1, i32 33554491, metadata !21, i32 0, null} ; [ DW_TAG_arg_variable ] +!21 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] +!22 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] +!23 = metadata !{i32 786468, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!24 = metadata !{i32 786688, metadata !25, metadata !"i", metadata !1, i32 60, metadata !13, i32 0, null} ; [ DW_TAG_auto_variable ] +!25 = metadata !{i32 786443, metadata !10, i32 59, i32 33, metadata !1, i32 14} ; [ DW_TAG_lexical_block ] +!26 = metadata !{i32 786688, metadata !25, metadata !"j", metadata !1, i32 60, metadata !13, i32 0, null} ; [ DW_TAG_auto_variable ] +!27 = metadata !{i32 786688, metadata !25, metadata !"x", metadata !1, i32 61, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!28 = metadata !{i32 786688, metadata !25, metadata !"y", metadata !1, i32 62, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 786688, metadata !25, metadata !"z", metadata !1, i32 63, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!30 = metadata !{i32 786689, metadata !14, metadata !"F", metadata !15, i32 16777257, metadata !31, i32 0, null} ; [ DW_TAG_arg_variable ] +!31 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] +!32 = metadata !{i32 786454, metadata !2, metadata !"FV", metadata !15, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !33} ; [ DW_TAG_typedef ] +!33 = metadata !{i32 786455, metadata !2, metadata !"", metadata !15, i32 22, i64 128, i64 128, i64 0, i32 0, i32 0, metadata !34, i32 0, i32 0} ; [ DW_TAG_union_type ] !34 = metadata !{metadata !35, metadata !37} -!35 = metadata !{i32 589837, metadata !15, metadata !"V", metadata !15, i32 23, i64 128, i64 128, i64 0, i32 0, metadata !36} ; [ DW_TAG_member ] -!36 = metadata !{i32 589846, metadata !2, metadata !"v4sf", metadata !15, i32 3, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] -!37 = metadata !{i32 589837, metadata !15, metadata !"A", metadata !15, i32 24, i64 128, i64 32, i64 0, i32 0, metadata !38} ; [ DW_TAG_member ] -!38 = metadata !{i32 589825, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 32, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_array_type ] +!35 = metadata !{i32 786445, metadata !15, metadata !"V", metadata !15, i32 23, i64 128, i64 128, i64 0, i32 0, metadata !36} ; [ DW_TAG_member ] +!36 = metadata !{i32 786454, metadata !2, metadata !"v4sf", metadata !15, i32 3, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] +!37 = metadata !{i32 786445, metadata !15, metadata !"A", metadata !15, i32 24, i64 128, i64 32, i64 0, i32 0, metadata !38} ; [ DW_TAG_member ] +!38 = metadata !{i32 786433, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 32, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_array_type ] !39 = metadata !{i32 79, i32 7, metadata !40, null} -!40 = metadata !{i32 589835, metadata !41, i32 75, i32 35, metadata !1, i32 18} ; [ DW_TAG_lexical_block ] -!41 = metadata !{i32 589835, metadata !42, i32 75, i32 5, metadata !1, i32 17} ; [ DW_TAG_lexical_block ] -!42 = metadata !{i32 589835, metadata !43, i32 71, i32 32, metadata !1, i32 16} ; [ DW_TAG_lexical_block ] -!43 = metadata !{i32 589835, metadata !25, i32 71, i32 3, metadata !1, i32 15} ; [ DW_TAG_lexical_block ] +!40 = metadata !{i32 786443, metadata !41, i32 75, i32 35, metadata !1, i32 18} ; [ DW_TAG_lexical_block ] +!41 = metadata !{i32 786443, metadata !42, i32 75, i32 5, metadata !1, i32 17} ; [ DW_TAG_lexical_block ] +!42 = metadata !{i32 786443, metadata !43, i32 71, i32 32, metadata !1, i32 16} ; [ DW_TAG_lexical_block ] +!43 = metadata !{i32 786443, metadata !25, i32 71, i32 3, metadata !1, i32 15} ; [ DW_TAG_lexical_block ] !44 = metadata !{i32 75, i32 5, metadata !42, null} !45 = metadata !{i32 42, i32 2, metadata !46, metadata !48} -!46 = metadata !{i32 589835, metadata !47, i32 42, i32 2, metadata !15, i32 20} ; [ DW_TAG_lexical_block ] -!47 = metadata !{i32 589835, metadata !14, i32 41, i32 28, metadata !15, i32 19} ; [ DW_TAG_lexical_block ] +!46 = metadata !{i32 786443, metadata !47, i32 42, i32 2, metadata !15, i32 20} ; [ DW_TAG_lexical_block ] +!47 = metadata !{i32 786443, metadata !14, i32 41, i32 28, metadata !15, i32 19} ; [ DW_TAG_lexical_block ] !48 = metadata !{i32 95, i32 3, metadata !25, null} !49 = metadata !{i32 99, i32 3, metadata !25, null} diff --git a/test/CodeGen/ARM/debug-info-d16-reg.ll b/test/CodeGen/ARM/debug-info-d16-reg.ll index 325eea00c8..80096906e5 100644 --- a/test/CodeGen/ARM/debug-info-d16-reg.ll +++ b/test/CodeGen/ARM/debug-info-d16-reg.ll @@ -56,44 +56,45 @@ entry: declare i32 @puts(i8* nocapture) nounwind -!llvm.dbg.sp = !{!0, !9, !10} -!llvm.dbg.lv.printer = !{!16, !17, !18} -!llvm.dbg.lv.inlineprinter = !{!19, !20, !21} -!llvm.dbg.lv.main = !{!22, !23, !24} +!llvm.dbg.cu = !{!2} +!42 = metadata !{metadata !0, metadata !9, metadata !10} +!43 = metadata !{metadata !16, metadata !17, metadata !18} +!44 = metadata !{metadata !19, metadata !20, metadata !21} +!45 = metadata !{metadata !22, metadata !23, metadata !24} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"printer", metadata !"printer", metadata !"printer", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i8*, double, i8)* @printer} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"a.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"/tmp/a.c", metadata !"/tmp", metadata !"(LLVM build 00)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"printer", metadata !"printer", metadata !"printer", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i8*, double, i8)* @printer, null, null, metadata !43, i32 12} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"a.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"/tmp/a.c", metadata !"/tmp", metadata !"(LLVM build 00)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !42, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5, metadata !6, metadata !7, metadata !8} -!5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589839, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!7 = metadata !{i32 589860, metadata !1, metadata !"double", metadata !1, i32 0, i64 64, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 589860, metadata !1, metadata !"unsigned char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] -!9 = metadata !{i32 589870, i32 0, metadata !1, metadata !"inlineprinter", metadata !"inlineprinter", metadata !"inlineprinter", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i8*, double, i8)* @inlineprinter} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 18, metadata !11, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i32, i8**)* @main} ; [ DW_TAG_subprogram ] -!11 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786468, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 786468, metadata !1, metadata !"double", metadata !1, i32 0, i64 64, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786468, metadata !1, metadata !"unsigned char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"inlineprinter", metadata !"inlineprinter", metadata !"inlineprinter", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i8*, double, i8)* @inlineprinter, null, null, metadata !44, i32 5} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 18, metadata !11, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i32, i8**)* @main, null, null, metadata !45, i32 18} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_subroutine_type ] !12 = metadata !{metadata !5, metadata !5, metadata !13} -!13 = metadata !{i32 589839, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] -!14 = metadata !{i32 589839, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !15} ; [ DW_TAG_pointer_type ] -!15 = metadata !{i32 589860, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!16 = metadata !{i32 590081, metadata !0, metadata !"ptr", metadata !1, i32 11, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] -!17 = metadata !{i32 590081, metadata !0, metadata !"val", metadata !1, i32 11, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!18 = metadata !{i32 590081, metadata !0, metadata !"c", metadata !1, i32 11, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 590081, metadata !9, metadata !"ptr", metadata !1, i32 4, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] -!20 = metadata !{i32 590081, metadata !9, metadata !"val", metadata !1, i32 4, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!21 = metadata !{i32 590081, metadata !9, metadata !"c", metadata !1, i32 4, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] -!22 = metadata !{i32 590081, metadata !10, metadata !"argc", metadata !1, i32 17, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!23 = metadata !{i32 590081, metadata !10, metadata !"argv", metadata !1, i32 17, metadata !13, i32 0} ; [ DW_TAG_arg_variable ] -!24 = metadata !{i32 590080, metadata !25, metadata !"dval", metadata !1, i32 19, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] -!25 = metadata !{i32 589835, metadata !10, i32 18, i32 0, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] +!14 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !15} ; [ DW_TAG_pointer_type ] +!15 = metadata !{i32 786468, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!16 = metadata !{i32 786689, metadata !0, metadata !"ptr", metadata !1, i32 11, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 786689, metadata !0, metadata !"val", metadata !1, i32 11, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 786689, metadata !0, metadata !"c", metadata !1, i32 11, metadata !8, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786689, metadata !9, metadata !"ptr", metadata !1, i32 4, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 786689, metadata !9, metadata !"val", metadata !1, i32 4, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!21 = metadata !{i32 786689, metadata !9, metadata !"c", metadata !1, i32 4, metadata !8, i32 0, null} ; [ DW_TAG_arg_variable ] +!22 = metadata !{i32 786689, metadata !10, metadata !"argc", metadata !1, i32 17, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!23 = metadata !{i32 786689, metadata !10, metadata !"argv", metadata !1, i32 17, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!24 = metadata !{i32 786688, metadata !25, metadata !"dval", metadata !1, i32 19, metadata !7, i32 0, null} ; [ DW_TAG_auto_variable ] +!25 = metadata !{i32 786443, metadata !10, i32 18, i32 0, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] !26 = metadata !{i32 4, i32 0, metadata !9, null} !27 = metadata !{i32 6, i32 0, metadata !28, null} -!28 = metadata !{i32 589835, metadata !9, i32 5, i32 0, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786443, metadata !9, i32 5, i32 0, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] !29 = metadata !{i32 7, i32 0, metadata !28, null} !30 = metadata !{i32 11, i32 0, metadata !0, null} !31 = metadata !{i32 13, i32 0, metadata !32, null} -!32 = metadata !{i32 589835, metadata !0, i32 12, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!32 = metadata !{i32 786443, metadata !0, i32 12, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !33 = metadata !{i32 14, i32 0, metadata !32, null} !34 = metadata !{i32 17, i32 0, metadata !10, null} !35 = metadata !{i32 19, i32 0, metadata !25, null} diff --git a/test/CodeGen/ARM/debug-info-qreg.ll b/test/CodeGen/ARM/debug-info-qreg.ll index c6bfe3a25e..89010dd364 100644 --- a/test/CodeGen/ARM/debug-info-qreg.ll +++ b/test/CodeGen/ARM/debug-info-qreg.ll @@ -35,58 +35,59 @@ declare i32 @printf(i8* nocapture, ...) nounwind declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !10, !14} -!llvm.dbg.lv.test0001 = !{!18} -!llvm.dbg.lv.main = !{!19, !20, !24, !26, !27, !28, !29} -!llvm.dbg.lv.printFV = !{!30} +!llvm.dbg.cu = !{!2} +!50 = metadata !{metadata !0, metadata !10, metadata !14} +!51 = metadata !{metadata !18} +!52 = metadata !{metadata !19, metadata !20, metadata !24, metadata !26, metadata !27, metadata !28, metadata !29} +!53 = metadata !{metadata !30} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"test0001", metadata !"test0001", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, <4 x float> (float)* @test0001, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"build2.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"build2.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"test0001", metadata !"test0001", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, <4 x float> (float)* @test0001, null, null, metadata !51, i32 3} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"build2.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"build2.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !50, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589846, metadata !2, metadata !"v4f32", metadata !1, i32 14, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] -!6 = metadata !{i32 590083, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 128, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_vector_type ] -!7 = metadata !{i32 589860, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!5 = metadata !{i32 786454, metadata !2, metadata !"v4f32", metadata !1, i32 14, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] +!6 = metadata !{i32 786691, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 128, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_vector_type ] +!7 = metadata !{i32 786468, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] !8 = metadata !{metadata !9} -!9 = metadata !{i32 589857, i64 0, i64 4} ; [ DW_TAG_subrange_type ] -!10 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 59, metadata !11, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**)* @main, null} ; [ DW_TAG_subprogram ] -!11 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!9 = metadata !{i32 786465, i64 0, i64 4} ; [ DW_TAG_subrange_type ] +!10 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 59, metadata !11, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**)* @main, null, null, metadata !52, i32 59} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !12 = metadata !{metadata !13} -!13 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 589870, i32 0, metadata !15, metadata !"printFV", metadata !"printFV", metadata !"", metadata !15, i32 41, metadata !16, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ] -!15 = metadata !{i32 589865, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!16 = metadata !{i32 589845, metadata !15, metadata !"", metadata !15, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !17, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!13 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786478, i32 0, metadata !15, metadata !"printFV", metadata !"printFV", metadata !"", metadata !15, i32 41, metadata !16, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null, null, null, metadata !53, i32 41} ; [ DW_TAG_subprogram ] +!15 = metadata !{i32 786473, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!16 = metadata !{i32 786453, metadata !15, metadata !"", metadata !15, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !17, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !17 = metadata !{null} -!18 = metadata !{i32 590081, metadata !0, metadata !"a", metadata !1, i32 16777219, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 590081, metadata !10, metadata !"argc", metadata !1, i32 16777275, metadata !13, i32 0} ; [ DW_TAG_arg_variable ] -!20 = metadata !{i32 590081, metadata !10, metadata !"argv", metadata !1, i32 33554491, metadata !21, i32 0} ; [ DW_TAG_arg_variable ] -!21 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] -!22 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] -!23 = metadata !{i32 589860, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!24 = metadata !{i32 590080, metadata !25, metadata !"i", metadata !1, i32 60, metadata !13, i32 0} ; [ DW_TAG_auto_variable ] -!25 = metadata !{i32 589835, metadata !10, i32 59, i32 33, metadata !1, i32 14} ; [ DW_TAG_lexical_block ] -!26 = metadata !{i32 590080, metadata !25, metadata !"j", metadata !1, i32 60, metadata !13, i32 0} ; [ DW_TAG_auto_variable ] -!27 = metadata !{i32 590080, metadata !25, metadata !"x", metadata !1, i32 61, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!28 = metadata !{i32 590080, metadata !25, metadata !"y", metadata !1, i32 62, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!29 = metadata !{i32 590080, metadata !25, metadata !"z", metadata !1, i32 63, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!30 = metadata !{i32 590081, metadata !14, metadata !"F", metadata !15, i32 16777257, metadata !31, i32 0} ; [ DW_TAG_arg_variable ] -!31 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] -!32 = metadata !{i32 589846, metadata !2, metadata !"FV", metadata !15, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !33} ; [ DW_TAG_typedef ] -!33 = metadata !{i32 589847, metadata !2, metadata !"", metadata !15, i32 22, i64 128, i64 128, i64 0, i32 0, i32 0, metadata !34, i32 0, i32 0} ; [ DW_TAG_union_type ] +!18 = metadata !{i32 786689, metadata !0, metadata !"a", metadata !1, i32 16777219, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786689, metadata !10, metadata !"argc", metadata !1, i32 16777275, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 786689, metadata !10, metadata !"argv", metadata !1, i32 33554491, metadata !21, i32 0, null} ; [ DW_TAG_arg_variable ] +!21 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] +!22 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] +!23 = metadata !{i32 786468, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!24 = metadata !{i32 786688, metadata !25, metadata !"i", metadata !1, i32 60, metadata !13, i32 0, null} ; [ DW_TAG_auto_variable ] +!25 = metadata !{i32 786443, metadata !10, i32 59, i32 33, metadata !1, i32 14} ; [ DW_TAG_lexical_block ] +!26 = metadata !{i32 786688, metadata !25, metadata !"j", metadata !1, i32 60, metadata !13, i32 0, null} ; [ DW_TAG_auto_variable ] +!27 = metadata !{i32 786688, metadata !25, metadata !"x", metadata !1, i32 61, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!28 = metadata !{i32 786688, metadata !25, metadata !"y", metadata !1, i32 62, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 786688, metadata !25, metadata !"z", metadata !1, i32 63, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!30 = metadata !{i32 786689, metadata !14, metadata !"F", metadata !15, i32 16777257, metadata !31, i32 0, null} ; [ DW_TAG_arg_variable ] +!31 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !32} ; [ DW_TAG_pointer_type ] +!32 = metadata !{i32 786454, metadata !2, metadata !"FV", metadata !15, i32 25, i64 0, i64 0, i64 0, i32 0, metadata !33} ; [ DW_TAG_typedef ] +!33 = metadata !{i32 786455, metadata !2, metadata !"", metadata !15, i32 22, i64 128, i64 128, i64 0, i32 0, i32 0, metadata !34, i32 0, i32 0} ; [ DW_TAG_union_type ] !34 = metadata !{metadata !35, metadata !37} -!35 = metadata !{i32 589837, metadata !15, metadata !"V", metadata !15, i32 23, i64 128, i64 128, i64 0, i32 0, metadata !36} ; [ DW_TAG_member ] -!36 = metadata !{i32 589846, metadata !2, metadata !"v4sf", metadata !15, i32 3, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] -!37 = metadata !{i32 589837, metadata !15, metadata !"A", metadata !15, i32 24, i64 128, i64 32, i64 0, i32 0, metadata !38} ; [ DW_TAG_member ] -!38 = metadata !{i32 589825, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 32, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_array_type ] +!35 = metadata !{i32 786445, metadata !15, metadata !"V", metadata !15, i32 23, i64 128, i64 128, i64 0, i32 0, metadata !36} ; [ DW_TAG_member ] +!36 = metadata !{i32 786454, metadata !2, metadata !"v4sf", metadata !15, i32 3, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_typedef ] +!37 = metadata !{i32 786445, metadata !15, metadata !"A", metadata !15, i32 24, i64 128, i64 32, i64 0, i32 0, metadata !38} ; [ DW_TAG_member ] +!38 = metadata !{i32 786433, metadata !2, metadata !"", metadata !2, i32 0, i64 128, i64 32, i32 0, i32 0, metadata !7, metadata !8, i32 0, i32 0} ; [ DW_TAG_array_type ] !39 = metadata !{i32 79, i32 7, metadata !40, null} -!40 = metadata !{i32 589835, metadata !41, i32 75, i32 35, metadata !1, i32 18} ; [ DW_TAG_lexical_block ] -!41 = metadata !{i32 589835, metadata !42, i32 75, i32 5, metadata !1, i32 17} ; [ DW_TAG_lexical_block ] -!42 = metadata !{i32 589835, metadata !43, i32 71, i32 32, metadata !1, i32 16} ; [ DW_TAG_lexical_block ] -!43 = metadata !{i32 589835, metadata !25, i32 71, i32 3, metadata !1, i32 15} ; [ DW_TAG_lexical_block ] +!40 = metadata !{i32 786443, metadata !41, i32 75, i32 35, metadata !1, i32 18} ; [ DW_TAG_lexical_block ] +!41 = metadata !{i32 786443, metadata !42, i32 75, i32 5, metadata !1, i32 17} ; [ DW_TAG_lexical_block ] +!42 = metadata !{i32 786443, metadata !43, i32 71, i32 32, metadata !1, i32 16} ; [ DW_TAG_lexical_block ] +!43 = metadata !{i32 786443, metadata !25, i32 71, i32 3, metadata !1, i32 15} ; [ DW_TAG_lexical_block ] !44 = metadata !{i32 75, i32 5, metadata !42, null} !45 = metadata !{i32 42, i32 2, metadata !46, metadata !48} -!46 = metadata !{i32 589835, metadata !47, i32 42, i32 2, metadata !15, i32 20} ; [ DW_TAG_lexical_block ] -!47 = metadata !{i32 589835, metadata !14, i32 41, i32 28, metadata !15, i32 19} ; [ DW_TAG_lexical_block ] +!46 = metadata !{i32 786443, metadata !47, i32 42, i32 2, metadata !15, i32 20} ; [ DW_TAG_lexical_block ] +!47 = metadata !{i32 786443, metadata !14, i32 41, i32 28, metadata !15, i32 19} ; [ DW_TAG_lexical_block ] !48 = metadata !{i32 95, i32 3, metadata !25, null} !49 = metadata !{i32 99, i32 3, metadata !25, null} diff --git a/test/CodeGen/ARM/debug-info-s16-reg.ll b/test/CodeGen/ARM/debug-info-s16-reg.ll index db41143fb3..68fabee15f 100644 --- a/test/CodeGen/ARM/debug-info-s16-reg.ll +++ b/test/CodeGen/ARM/debug-info-s16-reg.ll @@ -61,46 +61,47 @@ declare i32 @puts(i8* nocapture) nounwind optsize declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !6, !7} -!llvm.dbg.lv.inlineprinter = !{!8, !10, !12} -!llvm.dbg.lv.printer = !{!14, !15, !16} -!llvm.dbg.lv.main = !{!17, !18, !22} +!llvm.dbg.cu = !{!2} +!47 = metadata !{metadata !0, metadata !6, metadata !7} +!48 = metadata !{metadata !8, metadata !10, metadata !12} +!49 = metadata !{metadata !14, metadata !15, metadata !16} +!50 = metadata !{metadata !17, metadata !18, metadata !22} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"inlineprinter", metadata !"inlineprinter", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i8*, float, i8)* @inlineprinter, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"a.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"inlineprinter", metadata !"inlineprinter", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i8*, float, i8)* @inlineprinter, null, null, metadata !48, i32 5} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"a.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 129915)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !47, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"printer", metadata !"printer", metadata !"", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i8*, float, i8)* @printer, null} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 18, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**)* @main, null} ; [ DW_TAG_subprogram ] -!8 = metadata !{i32 590081, metadata !0, metadata !"ptr", metadata !1, i32 16777220, metadata !9, i32 0} ; [ DW_TAG_arg_variable ] -!9 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!10 = metadata !{i32 590081, metadata !0, metadata !"val", metadata !1, i32 33554436, metadata !11, i32 0} ; [ DW_TAG_arg_variable ] -!11 = metadata !{i32 589860, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!12 = metadata !{i32 590081, metadata !0, metadata !"c", metadata !1, i32 50331652, metadata !13, i32 0} ; [ DW_TAG_arg_variable ] -!13 = metadata !{i32 589860, metadata !2, metadata !"unsigned char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 590081, metadata !6, metadata !"ptr", metadata !1, i32 16777227, metadata !9, i32 0} ; [ DW_TAG_arg_variable ] -!15 = metadata !{i32 590081, metadata !6, metadata !"val", metadata !1, i32 33554443, metadata !11, i32 0} ; [ DW_TAG_arg_variable ] -!16 = metadata !{i32 590081, metadata !6, metadata !"c", metadata !1, i32 50331659, metadata !13, i32 0} ; [ DW_TAG_arg_variable ] -!17 = metadata !{i32 590081, metadata !7, metadata !"argc", metadata !1, i32 16777233, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!18 = metadata !{i32 590081, metadata !7, metadata !"argv", metadata !1, i32 33554449, metadata !19, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !20} ; [ DW_TAG_pointer_type ] -!20 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !21} ; [ DW_TAG_pointer_type ] -!21 = metadata !{i32 589860, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!22 = metadata !{i32 590080, metadata !23, metadata !"dval", metadata !1, i32 19, metadata !11, i32 0} ; [ DW_TAG_auto_variable ] -!23 = metadata !{i32 589835, metadata !7, i32 18, i32 1, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !1, metadata !"printer", metadata !"printer", metadata !"", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i8*, float, i8)* @printer, null, null, metadata !49, i32 12} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 18, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i8**)* @main, null, null, metadata !50, i32 18} ; [ DW_TAG_subprogram ] +!8 = metadata !{i32 786689, metadata !0, metadata !"ptr", metadata !1, i32 16777220, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!9 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!10 = metadata !{i32 786689, metadata !0, metadata !"val", metadata !1, i32 33554436, metadata !11, i32 0, null} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 786468, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!12 = metadata !{i32 786689, metadata !0, metadata !"c", metadata !1, i32 50331652, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!13 = metadata !{i32 786468, metadata !2, metadata !"unsigned char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786689, metadata !6, metadata !"ptr", metadata !1, i32 16777227, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!15 = metadata !{i32 786689, metadata !6, metadata !"val", metadata !1, i32 33554443, metadata !11, i32 0, null} ; [ DW_TAG_arg_variable ] +!16 = metadata !{i32 786689, metadata !6, metadata !"c", metadata !1, i32 50331659, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 786689, metadata !7, metadata !"argc", metadata !1, i32 16777233, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 786689, metadata !7, metadata !"argv", metadata !1, i32 33554449, metadata !19, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !20} ; [ DW_TAG_pointer_type ] +!20 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !21} ; [ DW_TAG_pointer_type ] +!21 = metadata !{i32 786468, metadata !2, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!22 = metadata !{i32 786688, metadata !23, metadata !"dval", metadata !1, i32 19, metadata !11, i32 0, null} ; [ DW_TAG_auto_variable ] +!23 = metadata !{i32 786443, metadata !7, i32 18, i32 1, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] !24 = metadata !{i32 4, i32 22, metadata !0, null} !25 = metadata !{i32 4, i32 33, metadata !0, null} !26 = metadata !{i32 4, i32 52, metadata !0, null} !27 = metadata !{i32 6, i32 3, metadata !28, null} -!28 = metadata !{i32 589835, metadata !0, i32 5, i32 1, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786443, metadata !0, i32 5, i32 1, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !29 = metadata !{i32 7, i32 3, metadata !28, null} !30 = metadata !{i32 11, i32 42, metadata !6, null} !31 = metadata !{i32 11, i32 53, metadata !6, null} !32 = metadata !{i32 11, i32 72, metadata !6, null} !33 = metadata !{i32 13, i32 3, metadata !34, null} -!34 = metadata !{i32 589835, metadata !6, i32 12, i32 1, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!34 = metadata !{i32 786443, metadata !6, i32 12, i32 1, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] !35 = metadata !{i32 14, i32 3, metadata !34, null} !36 = metadata !{i32 17, i32 15, metadata !7, null} !37 = metadata !{i32 17, i32 28, metadata !7, null} diff --git a/test/CodeGen/ARM/debug-info-sreg2.ll b/test/CodeGen/ARM/debug-info-sreg2.ll index ae7af0afad..e40d617619 100644 --- a/test/CodeGen/ARM/debug-info-sreg2.ll +++ b/test/CodeGen/ARM/debug-info-sreg2.ll @@ -40,20 +40,20 @@ declare float @_Z2f3f(float) optsize declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1} -!llvm.dbg.lv._Z3foov = !{!5, !8} +!16 = metadata !{metadata !1} +!17 = metadata !{metadata !5, metadata !8} -!0 = metadata !{i32 589841, i32 0, i32 4, metadata !"k.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 130845)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3foov", metadata !2, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @_Z3foov, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"k.cc", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"k.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 130845)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !16, null, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3foov", metadata !2, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @_Z3foov, null, null, metadata !17, i32 5} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"k.cc", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{null} -!5 = metadata !{i32 590080, metadata !6, metadata !"k", metadata !2, i32 6, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] -!6 = metadata !{i32 589835, metadata !1, i32 5, i32 12, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] -!7 = metadata !{i32 589860, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 590080, metadata !9, metadata !"y", metadata !2, i32 8, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] -!9 = metadata !{i32 589835, metadata !10, i32 7, i32 25, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] -!10 = metadata !{i32 589835, metadata !6, i32 7, i32 3, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786688, metadata !6, metadata !"k", metadata !2, i32 6, metadata !7, i32 0, null} ; [ DW_TAG_auto_variable ] +!6 = metadata !{i32 786443, metadata !1, i32 5, i32 12, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 786468, metadata !0, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786688, metadata !9, metadata !"y", metadata !2, i32 8, metadata !7, i32 0, null} ; [ DW_TAG_auto_variable ] +!9 = metadata !{i32 786443, metadata !10, i32 7, i32 25, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 786443, metadata !6, i32 7, i32 3, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] !11 = metadata !{i32 6, i32 18, metadata !6, null} !12 = metadata !{i32 7, i32 3, metadata !6, null} !13 = metadata !{i32 8, i32 20, metadata !9, null} diff --git a/test/CodeGen/ARM/eh-dispcont.ll b/test/CodeGen/ARM/eh-dispcont.ll new file mode 100644 index 0000000000..935965bbdf --- /dev/null +++ b/test/CodeGen/ARM/eh-dispcont.ll @@ -0,0 +1,89 @@ +; RUN: llc -mtriple armv7-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=ARM-PIC +; RUN: llc -mtriple armv7-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=ARM-NOPIC +; RUN: llc -mtriple armv7-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=ARM-NOPIC +; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=pic -o - %s | FileCheck %s -check-prefix=THUMB1-PIC +; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=static -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC +; RUN: llc -mtriple thumbv6-apple-ios -relocation-model=dynamic-no-pic -o - %s | FileCheck %s -check-prefix=THUMB1-NOPIC + +@_ZTIi = external constant i8* + +define i32 @main() #0 { +entry: + %exception = tail call i8* @__cxa_allocate_exception(i32 4) #1 + %0 = bitcast i8* %exception to i32* + store i32 1, i32* %0, align 4 + invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2 + to label %unreachable unwind label %lpad + +lpad: ; preds = %entry + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + catch i8* null + %2 = extractvalue { i8*, i32 } %1, 0 + %3 = tail call i8* @__cxa_begin_catch(i8* %2) #1 + tail call void @__cxa_end_catch() + ret i32 0 + +unreachable: ; preds = %entry + unreachable +} + +declare i8* @__cxa_allocate_exception(i32) + +declare void @__cxa_throw(i8*, i8*, i8*) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +declare i32 @__gxx_personality_sj0(...) + +attributes #0 = { ssp } +attributes #1 = { nounwind } +attributes #2 = { noreturn } + +; ARM-PIC: cxa_throw +; ARM-PIC: trap +; ARM-PIC: adr [[REG1:r[0-9]+]], [[LJTI:.*]] +; ARM-PIC: ldr [[REG0:r[0-9]+]], [r{{[0-9]+}}, [[REG1]]] +; ARM-PIC: add pc, [[REG0]], [[REG1]] +; ARM-PIC: [[LJTI]] +; ARM-PIC: .data_region jt32 +; ARM-PIC: .long [[LABEL:LBB0_[0-9]]]-[[LJTI]] +; ARM-PIC: .end_data_region +; ARM-PIC: [[LABEL]] + +; ARM-NOPIC: cxa_throw +; ARM-NOPIC: trap +; ARM-NOPIC: adr [[REG1:r[0-9]+]], [[LJTI:.*]] +; ARM-NOPIC: ldr [[REG0:r[0-9]+]], [r{{[0-9]+}}, [[REG1]]] +; ARM-NOPIC: mov pc, [[REG0]] +; ARM-NOPIC: [[LJTI]] +; ARM-NOPIC: .data_region jt32 +; ARM-NOPIC: .long [[LABEL:LBB0_[0-9]]] +; ARM-NOPIC: .end_data_region +; ARM-NOPIC: [[LABEL]] + +; THUMB1-PIC: cxa_throw +; THUMB1-PIC: trap +; THUMB1-PIC: adr [[REG0:r[0-9]+]], [[LJTI:.*]] +; THUMB1-PIC: adds [[REG1:r[0-9]+]], [[REG1]], [[REG0]] +; THUMB1-PIC: ldr [[REG1]] +; THUMB1-PIC: adds [[REG0]], [[REG1]], [[REG0]] +; THUMB1-PIC: mov pc, [[REG0]] +; THUMB1-PIC: [[LJTI]] +; THUMB1-PIC: .data_region jt32 +; THUMB1-PIC: .long [[LABEL:LBB0_[0-9]]]-[[LJTI]] +; THUMB1-PIC: .end_data_region +; THUMB1-PIC: [[LABEL]] + +; THUMB1-NOPIC: cxa_throw +; THUMB1-NOPIC: trap +; THUMB1-NOPIC: adr [[REG1:r[0-9]+]], [[LJTI:.*]] +; THUMB1-NOPIC: adds [[REG0:r[0-9]+]], [[REG0]], [[REG1]] +; THUMB1-NOPIC: ldr [[REG0]] +; THUMB1-NOPIC: mov pc, [[REG0]] +; THUMB1-NOPIC: [[LJTI]] +; THUMB1-NOPIC: .data_region jt32 +; THUMB1-NOPIC: .long [[LABEL:LBB0_[0-9]]]+1 +; THUMB1-NOPIC: .end_data_region +; THUMB1-NOPIC: [[LABEL]] diff --git a/test/CodeGen/ARM/ehabi-filters.ll b/test/CodeGen/ARM/ehabi-filters.ll index d15aa7b32c..c42839d9fe 100644 --- a/test/CodeGen/ARM/ehabi-filters.ll +++ b/test/CodeGen/ARM/ehabi-filters.ll @@ -15,7 +15,7 @@ declare void @__cxa_throw(i8*, i8*, i8*) declare void @__cxa_call_unexpected(i8*) define i32 @main() { -; CHECK main: +; CHECK: main: entry: %exception.i = tail call i8* @__cxa_allocate_exception(i32 4) nounwind %0 = bitcast i8* %exception.i to i32* diff --git a/test/CodeGen/ARM/ehabi-mc-cantunwind.ll b/test/CodeGen/ARM/ehabi-mc-cantunwind.ll new file mode 100644 index 0000000000..698d76e565 --- /dev/null +++ b/test/CodeGen/ARM/ehabi-mc-cantunwind.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple arm-unknown-linux-gnueabi \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -filetype=obj -o - %s \ +; RUN: | llvm-objdump -s - \ +; RUN: | FileCheck %s + +define void @test() nounwind { +entry: + ret void +} + +; CHECK: section .text +; CHECK: section .ARM.exidx +; CHECK-NEXT: 0000 00000000 01000000 diff --git a/test/CodeGen/ARM/ehabi-mc-section-group.ll b/test/CodeGen/ARM/ehabi-mc-section-group.ll new file mode 100644 index 0000000000..5e4b5096c4 --- /dev/null +++ b/test/CodeGen/ARM/ehabi-mc-section-group.ll @@ -0,0 +1,79 @@ +; Test section group of the function with linkonce_odr + +; The instantiation of C++ function template will come with linkonce_odr, +; which indicates that the linker can remove the duplicated instantiation. +; However, to make this feature work, we have to group the section properly. +; .text, .ARM.extab, and .ARM.exidx should be grouped together. + +; RUN: llc -mtriple arm-unknown-linux-gnueabi \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -filetype=obj -o - %s \ +; RUN: | elf-dump --dump-section-data \ +; RUN: | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64" +target triple = "armv4t--linux-gnueabi" + +define void @_Z11instantiatev() { +entry: + tail call void @_Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_(i32 1, i32 2, i32 3, i32 4, i32 5, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01) + ret void +} + +define linkonce_odr void @_Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5, double %v1, double %v2, double %v3, double %v4, double %v5) { +entry: + invoke void @_Z5printiiiii(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5) + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) nounwind + invoke void @_Z5printddddd(double %v1, double %v2, double %v3, double %v4, double %v5) + to label %invoke.cont2 unwind label %lpad1 + +invoke.cont2: ; preds = %lpad + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %entry, %invoke.cont2 + ret void + +lpad1: ; preds = %lpad + %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + invoke void @__cxa_end_catch() + to label %eh.resume unwind label %terminate.lpad + +eh.resume: ; preds = %lpad1 + resume { i8*, i32 } %3 + +terminate.lpad: ; preds = %lpad1 + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + tail call void @_ZSt9terminatev() noreturn nounwind + unreachable +} + +declare void @_Z5printiiiii(i32, i32, i32, i32, i32) + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @_Z5printddddd(double, double, double, double, double) + +declare void @__cxa_end_catch() + +declare void @_ZSt9terminatev() + +; CHECK: # Section 1 +; CHECK-NEXT: (('sh_name', 0x0000002f) # '.group' +; CHECK: ('_section_data', '01000000 0a000000 0c000000 0e000000') +; CHECK: # Section 10 +; CHECK-NEXT: (('sh_name', 0x000000e1) # '.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_' +; CHECK: # Section 12 +; CHECK-NEXT: (('sh_name', 0x000000d7) # '.ARM.extab.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_' +; CHECK: # Section 14 +; CHECK-NEXT: (('sh_name', 0x00000065) # '.ARM.exidx.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_' diff --git a/test/CodeGen/ARM/ehabi-mc-section.ll b/test/CodeGen/ARM/ehabi-mc-section.ll new file mode 100644 index 0000000000..fc51b240ff --- /dev/null +++ b/test/CodeGen/ARM/ehabi-mc-section.ll @@ -0,0 +1,59 @@ +; RUN: llc -mtriple arm-unknown-linux-gnueabi \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -filetype=obj -o - %s \ +; RUN: | llvm-objdump -s - \ +; RUN: | FileCheck %s + +define void @_Z4testiiiiiddddd(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5, double %v1, double %v2, double %v3, double %v4, double %v5) section ".test_section" { +entry: + invoke void @_Z5printiiiii(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5) + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) nounwind + invoke void @_Z5printddddd(double %v1, double %v2, double %v3, double %v4, double %v5) + to label %invoke.cont2 unwind label %lpad1 + +invoke.cont2: ; preds = %lpad + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %entry, %invoke.cont2 + ret void + +lpad1: ; preds = %lpad + %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + invoke void @__cxa_end_catch() + to label %eh.resume unwind label %terminate.lpad + +eh.resume: ; preds = %lpad1 + resume { i8*, i32 } %3 + +terminate.lpad: ; preds = %lpad1 + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + tail call void @_ZSt9terminatev() noreturn nounwind + unreachable +} + +declare void @_Z5printiiiii(i32, i32, i32, i32, i32) + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @_Z5printddddd(double, double, double, double, double) + +declare void @__cxa_end_catch() + +declare void @_ZSt9terminatev() + +; CHECK: section .test_section +; CHECK: section .ARM.extab.test_section +; CHECK-NEXT: 0000 00000000 b0b0b000 +; CHECK: section .ARM.exidx.test_section +; CHECK-NEXT: 0000 00000000 00000000 diff --git a/test/CodeGen/ARM/ehabi-mc-sh_link.ll b/test/CodeGen/ARM/ehabi-mc-sh_link.ll new file mode 100644 index 0000000000..f90e5f384c --- /dev/null +++ b/test/CodeGen/ARM/ehabi-mc-sh_link.ll @@ -0,0 +1,47 @@ +; Test the sh_link in Elf32_Shdr. + +; The .ARM.exidx section should be linked with corresponding text section. +; The sh_link in Elf32_Shdr should be filled with the section index of +; the text section. + +; RUN: llc -mtriple arm-unknown-linux-gnueabi \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -filetype=obj -o - %s \ +; RUN: | elf-dump --dump-section-data \ +; RUN: | FileCheck %s + +define void @test1() nounwind { +entry: + ret void +} + +define void @test2() nounwind section ".test_section" { +entry: + ret void +} + +; CHECK: # Section 1 +; CHECK-NEXT: (('sh_name', 0x00000010) # '.text' + +; CHECK: (('sh_name', 0x00000005) # '.ARM.exidx' +; CHECK-NEXT: ('sh_type', 0x70000001) +; CHECK-NEXT: ('sh_flags', 0x00000082) +; CHECK-NEXT: ('sh_addr', 0x00000000) +; CHECK-NEXT: ('sh_offset', 0x0000005c) +; CHECK-NEXT: ('sh_size', 0x00000008) +; CHECK-NEXT: ('sh_link', 0x00000001) +; CHECK-NEXT: ('sh_info', 0x00000000) +; CHECK-NEXT: ('sh_addralign', 0x00000004) + +; CHECK: # Section 7 +; CHECK-NEXT: (('sh_name', 0x00000039) # '.test_section' + +; CHECK: (('sh_name', 0x0000002f) # '.ARM.exidx.test_section' +; CHECK-NEXT: ('sh_type', 0x70000001) +; CHECK-NEXT: ('sh_flags', 0x00000082) +; CHECK-NEXT: ('sh_addr', 0x00000000) +; CHECK-NEXT: ('sh_offset', 0x00000068) +; CHECK-NEXT: ('sh_size', 0x00000008) +; CHECK-NEXT: ('sh_link', 0x00000007) +; CHECK-NEXT: ('sh_info', 0x00000000) +; CHECK-NEXT: ('sh_addralign', 0x00000004) diff --git a/test/CodeGen/ARM/ehabi-mc.ll b/test/CodeGen/ARM/ehabi-mc.ll new file mode 100644 index 0000000000..0dc2ef7838 --- /dev/null +++ b/test/CodeGen/ARM/ehabi-mc.ll @@ -0,0 +1,59 @@ +; RUN: llc -mtriple arm-unknown-linux-gnueabi \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -filetype=obj -o - %s \ +; RUN: | llvm-objdump -s - \ +; RUN: | FileCheck %s + +define void @_Z4testiiiiiddddd(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5, double %v1, double %v2, double %v3, double %v4, double %v5) { +entry: + invoke void @_Z5printiiiii(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5) + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) nounwind + invoke void @_Z5printddddd(double %v1, double %v2, double %v3, double %v4, double %v5) + to label %invoke.cont2 unwind label %lpad1 + +invoke.cont2: ; preds = %lpad + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %entry, %invoke.cont2 + ret void + +lpad1: ; preds = %lpad + %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + invoke void @__cxa_end_catch() + to label %eh.resume unwind label %terminate.lpad + +eh.resume: ; preds = %lpad1 + resume { i8*, i32 } %3 + +terminate.lpad: ; preds = %lpad1 + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + tail call void @_ZSt9terminatev() noreturn nounwind + unreachable +} + +declare void @_Z5printiiiii(i32, i32, i32, i32, i32) + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @_Z5printddddd(double, double, double, double, double) + +declare void @__cxa_end_catch() + +declare void @_ZSt9terminatev() + +; CHECK: section .text +; CHECK: section .ARM.extab +; CHECK-NEXT: 0000 00000000 b0b0b000 +; CHECK: section .ARM.exidx +; CHECK-NEXT: 0000 00000000 00000000 diff --git a/test/CodeGen/ARM/fabss.ll b/test/CodeGen/ARM/fabss.ll index 46c2f1c65f..c3e00ce470 100644 --- a/test/CodeGen/ARM/fabss.ll +++ b/test/CodeGen/ARM/fabss.ll @@ -14,12 +14,12 @@ entry: declare float @fabsf(float) ; VFP2: test: -; VFP2: vabs.f32 s2, s2 +; VFP2: vabs.f32 s ; NFP1: test: -; NFP1: vabs.f32 d1, d1 +; NFP1: vabs.f32 d ; NFP0: test: -; NFP0: vabs.f32 s2, s2 +; NFP0: vabs.f32 s ; CORTEXA8: test: ; CORTEXA8: vadd.f32 [[D1:d[0-9]+]] diff --git a/test/CodeGen/ARM/fast-isel-intrinsic.ll b/test/CodeGen/ARM/fast-isel-intrinsic.ll index 7d38cc2a7f..48105dd389 100644 --- a/test/CodeGen/ARM/fast-isel-intrinsic.ll +++ b/test/CodeGen/ARM/fast-isel-intrinsic.ll @@ -231,3 +231,22 @@ define void @t6() nounwind ssp { call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false) ret void } + +; rdar://13202135 +define void @t7() nounwind ssp { +; Just make sure this doesn't assert when we have an odd length and an alignment of 2. + call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8]* @temp, i32 0, i32 16), i32 3, i32 2, i1 false) + ret void +} + +define i32 @t8(i32 %x) nounwind { +entry: +; ARM: t8 +; ARM-NOT: FastISel missed call: %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) +; THUMB: t8 +; THUMB-NOT: FastISel missed call: %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) + %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) + ret i32 %expval +} + +declare i32 @llvm.expect.i32(i32, i32) nounwind readnone diff --git a/test/CodeGen/ARM/fast-isel-ldrh-strh-arm.ll b/test/CodeGen/ARM/fast-isel-ldrh-strh-arm.ll index e8cc2b238d..0b5267ddc9 100644 --- a/test/CodeGen/ARM/fast-isel-ldrh-strh-arm.ll +++ b/test/CodeGen/ARM/fast-isel-ldrh-strh-arm.ll @@ -103,7 +103,7 @@ entry: ; ARM: t11 %add.ptr = getelementptr inbounds i16* %a, i64 8 store i16 0, i16* %add.ptr, align 2 -; ARM strh r{{[1-9]}}, [r0, #16] +; ARM: strh r{{[1-9]}}, [r0, #16] ret void } diff --git a/test/CodeGen/ARM/fdivs.ll b/test/CodeGen/ARM/fdivs.ll index 8fab002135..8f13f395e0 100644 --- a/test/CodeGen/ARM/fdivs.ll +++ b/test/CodeGen/ARM/fdivs.ll @@ -10,14 +10,14 @@ entry: } ; VFP2: test: -; VFP2: vdiv.f32 s0, s2, s0 +; VFP2: vdiv.f32 s{{.}}, s{{.}}, s{{.}} ; NFP1: test: -; NFP1: vdiv.f32 s0, s2, s0 +; NFP1: vdiv.f32 s{{.}}, s{{.}}, s{{.}} ; NFP0: test: -; NFP0: vdiv.f32 s0, s2, s0 +; NFP0: vdiv.f32 s{{.}}, s{{.}}, s{{.}} ; CORTEXA8: test: -; CORTEXA8: vdiv.f32 s0, s2, s0 +; CORTEXA8: vdiv.f32 s{{.}}, s{{.}}, s{{.}} ; CORTEXA9: test: ; CORTEXA9: vdiv.f32 s{{.}}, s{{.}}, s{{.}} diff --git a/test/CodeGen/ARM/fnmscs.ll b/test/CodeGen/ARM/fnmscs.ll index 6081712829..9ce9b7ae7d 100644 --- a/test/CodeGen/ARM/fnmscs.ll +++ b/test/CodeGen/ARM/fnmscs.ll @@ -46,8 +46,8 @@ entry: ; NEON: vnmla.f64 ; A8: t3: -; A8: vnmul.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} -; A8: vsub.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} +; A8: vnmul.f64 d +; A8: vsub.f64 d %0 = fmul double %a, %b %1 = fsub double -0.0, %0 %2 = fsub double %1, %acc @@ -63,8 +63,8 @@ entry: ; NEON: vnmla.f64 ; A8: t4: -; A8: vnmul.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} -; A8: vsub.f64 d1{{[67]}}, d1{{[67]}}, d1{{[67]}} +; A8: vnmul.f64 d +; A8: vsub.f64 d %0 = fmul double %a, %b %1 = fmul double -1.0, %0 %2 = fsub double %1, %acc diff --git a/test/CodeGen/ARM/global-merge-addrspace.ll b/test/CodeGen/ARM/global-merge-addrspace.ll new file mode 100644 index 0000000000..0efa690bde --- /dev/null +++ b/test/CodeGen/ARM/global-merge-addrspace.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -mtriple=thumb-apple-darwin | FileCheck %s +; Test the GlobalMerge pass. Check that the pass does not crash when using +; multiple address spaces. + +; CHECK: _MergedGlobals: +@g1 = internal addrspace(1) global i32 1 +@g2 = internal addrspace(1) global i32 2 + + +; CHECK: _MergedGlobals1: +@g3 = internal addrspace(2) global i32 3 +@g4 = internal addrspace(2) global i32 4 diff --git a/test/CodeGen/ARM/indirect-reg-input.ll b/test/CodeGen/ARM/indirect-reg-input.ll new file mode 100644 index 0000000000..86728fa619 --- /dev/null +++ b/test/CodeGen/ARM/indirect-reg-input.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=arm -mcpu=cortex-a8 2>&1 | FileCheck %s + +; Check for error message: +; CHECK: error: inline asm not supported yet: don't know how to handle tied indirect register inputs + +%struct.my_stack = type { %struct.myjmp_buf } +%struct.myjmp_buf = type { [6 x i32] } + +define void @switch_to_stack(%struct.my_stack* %stack) nounwind { +entry: + %regs = getelementptr inbounds %struct.my_stack* %stack, i32 0, i32 0 + tail call void asm "\0A", "=*r,*0"(%struct.myjmp_buf* %regs, %struct.myjmp_buf* %regs) + ret void +} diff --git a/test/CodeGen/ARM/inlineasm-64bit.ll b/test/CodeGen/ARM/inlineasm-64bit.ll new file mode 100644 index 0000000000..be5eb81573 --- /dev/null +++ b/test/CodeGen/ARM/inlineasm-64bit.ll @@ -0,0 +1,54 @@ +; RUN: llc < %s -O3 -mtriple=arm-linux-gnueabi | FileCheck %s + +; check if regs are passing correctly +define void @i64_write(i64* %p, i64 %val) nounwind { +; CHECK: i64_write: +; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; CHECK: strexd [[REG1]], {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} + %1 = tail call i64 asm sideeffect "1: ldrexd $0, ${0:H}, [$2]\0A strexd $0, $3, ${3:H}, [$2]\0A teq $0, #0\0A bne 1b", "=&r,=*Qo,r,r,~{cc}"(i64* %p, i64* %p, i64 %val) nounwind + ret void +} + +; check if register allocation can reuse the registers +define void @multi_writes(i64* %p, i64 %val1, i64 %val2, i64 %val3, i64 %val4, i64 %val5, i64 %val6) nounwind { +entry: +; CHECK: multi_writes: +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] + +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] + +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; check: strexd {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}, [r{{[0-9]+}}] + + tail call void asm sideeffect " strexd $1, ${1:H}, [$0]\0A strexd $2, ${2:H}, [$0]\0A strexd $3, ${3:H}, [$0]\0A strexd $4, ${4:H}, [$0]\0A strexd $5, ${5:H}, [$0]\0A strexd $6, ${6:H}, [$0]\0A", "r,r,r,r,r,r,r"(i64* %p, i64 %val1, i64 %val2, i64 %val3, i64 %val4, i64 %val5, i64 %val6) nounwind + %incdec.ptr = getelementptr inbounds i64* %p, i32 1 + tail call void asm sideeffect " strexd $1, ${1:H}, [$0]\0A strexd $2, ${2:H}, [$0]\0A strexd $3, ${3:H}, [$0]\0A strexd $4, ${4:H}, [$0]\0A strexd $5, ${5:H}, [$0]\0A strexd $6, ${6:H}, [$0]\0A", "r,r,r,r,r,r,r"(i64* %incdec.ptr, i64 %val1, i64 %val2, i64 %val3, i64 %val4, i64 %val5, i64 %val6) nounwind + tail call void asm sideeffect " strexd $1, ${1:H}, [$0]\0A strexd $2, ${2:H}, [$0]\0A strexd $3, ${3:H}, [$0]\0A strexd $4, ${4:H}, [$0]\0A strexd $5, ${5:H}, [$0]\0A strexd $6, ${6:H}, [$0]\0A", "r,r,r,r,r,r,r"(i64* %incdec.ptr, i64 %val1, i64 %val2, i64 %val3, i64 %val4, i64 %val5, i64 %val6) nounwind + ret void +} + + +; check if callee-saved registers used by inline asm are saved/restored +define void @foo(i64* %p, i64 %i) nounwind { +; CHECK:foo: +; CHECK: push {{{r[4-9]|r10|r11}} +; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], {{r[0-9]?[13579]}}, [r{{[0-9]+}}] +; CHECK: strexd [[REG1]], {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} +; CHECK: pop {{{r[4-9]|r10|r11}} + %1 = tail call { i64, i64 } asm sideeffect "@ atomic64_set\0A1: ldrexd $0, ${0:H}, [$3]\0Aldrexd $1, ${1:H}, [$3]\0A strexd $0, $4, ${4:H}, [$3]\0A teq $0, #0\0A bne 1b", "=&r,=&r,=*Qo,r,r,~{cc}"(i64* %p, i64* %p, i64 %i) nounwind + ret void +} diff --git a/test/CodeGen/ARM/inlineasm3.ll b/test/CodeGen/ARM/inlineasm3.ll index 2fcc45f4af..390a44e375 100644 --- a/test/CodeGen/ARM/inlineasm3.ll +++ b/test/CodeGen/ARM/inlineasm3.ll @@ -30,7 +30,7 @@ entry: define hidden void @conv4_8_E() nounwind { entry: -%asmtmp31 = call %0 asm "vld1.u8 {$0}, [$1, :128]!\0A", "=w,=r,1"(<16 x i8>* undef) nounwind +%asmtmp31 = call %0 asm "vld1.u8 {$0}, [$1:128]!\0A", "=w,=r,1"(<16 x i8>* undef) nounwind unreachable } diff --git a/test/CodeGen/ARM/invoke-donothing-assert.ll b/test/CodeGen/ARM/invoke-donothing-assert.ll new file mode 100644 index 0000000000..0b607f7edf --- /dev/null +++ b/test/CodeGen/ARM/invoke-donothing-assert.ll @@ -0,0 +1,73 @@ +; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s +; This testcase makes sure we can handle invoke @llvm.donothing without +; assertion failure. +; <rdar://problem/13228754> & <rdar://problem/13316637> + +; CHECK: .globl _foo +define void @foo() { +invoke.cont: + invoke void @callA() + to label %invoke.cont25 unwind label %lpad2 +invoke.cont25: + invoke void @llvm.donothing() + to label %invoke.cont27 unwind label %lpad15 + +invoke.cont27: + invoke void @callB() + to label %invoke.cont75 unwind label %lpad15 + +invoke.cont75: + ret void + +lpad2: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + cleanup + br label %eh.resume + +lpad15: + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + cleanup + br label %eh.resume + +eh.resume: + resume { i8*, i32 } zeroinitializer +} + +; CHECK: .globl _bar +define linkonce_odr void @bar(i32* %a) { +if.end.i.i.i: + invoke void @llvm.donothing() + to label %call.i.i.i.noexc unwind label %eh.resume + +call.i.i.i.noexc: + br i1 false, label %cleanup, label %new.notnull.i.i + +new.notnull.i.i: + br label %cleanup + +cleanup: + %0 = load i32* %a, align 4 + %inc294 = add nsw i32 %0, 4 + store i32 %inc294, i32* %a, align 4 + br i1 false, label %_ZN3lol5ArrayIivvvvvvvED1Ev.exit, label %delete.notnull.i.i.i1409 + +delete.notnull.i.i.i1409: + br label %_ZN3lol5ArrayIivvvvvvvED1Ev.exit + +_ZN3lol5ArrayIivvvvvvvED1Ev.exit: + ret void + +eh.resume: + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + cleanup + %2 = extractvalue { i8*, i32 } %1, 0 + %3 = extractvalue { i8*, i32 } %1, 1 + %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0 + %lpad.val395 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1 + resume { i8*, i32 } %lpad.val395 +} + +declare void @callA() +declare void @callB() +declare void @llvm.donothing() nounwind readnone +declare i32 @__gxx_personality_sj0(...) diff --git a/test/CodeGen/ARM/neon_cmp.ll b/test/CodeGen/ARM/neon_cmp.ll new file mode 100644 index 0000000000..046b5da228 --- /dev/null +++ b/test/CodeGen/ARM/neon_cmp.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -march=arm -mcpu=cortex-a9 | FileCheck %s +; bug 15283 +; radar://13191881 +; CHECK: vfcmp +define void @vfcmp(<2 x double>* %a, <2 x double>* %b) { + %wide.load = load <2 x double>* %a, align 4 + %wide.load2 = load <2 x double>* %b, align 4 +; CHECK-NOT: vdup.32 +; CHECK-NOT: vmovn.i64 + %v1 = fcmp olt <2 x double> %wide.load, %wide.load2 + %v2 = zext <2 x i1> %v1 to <2 x i32> + %v3 = sitofp <2 x i32> %v2 to <2 x double> + store <2 x double> %v3, <2 x double>* %b, align 4 + ret void +} diff --git a/test/CodeGen/ARM/neon_fpconv.ll b/test/CodeGen/ARM/neon_fpconv.ll index 1948ad8471..149f4c7770 100644 --- a/test/CodeGen/ARM/neon_fpconv.ll +++ b/test/CodeGen/ARM/neon_fpconv.ll @@ -15,3 +15,28 @@ define <2 x double> @vextend(<2 x float> %a) { ret <2 x double> %ve } +; We used to generate vmovs between scalar and vfp/neon registers. +; CHECK: vsitofp_double +define void @vsitofp_double(<2 x i32>* %loadaddr, + <2 x double>* %storeaddr) { + %v0 = load <2 x i32>* %loadaddr +; CHECK: vldr +; CHECK-NEXT: vcvt.f64.s32 +; CHECK-NEXT: vcvt.f64.s32 +; CHECK-NEXT: vst + %r = sitofp <2 x i32> %v0 to <2 x double> + store <2 x double> %r, <2 x double>* %storeaddr + ret void +} +; CHECK: vuitofp_double +define void @vuitofp_double(<2 x i32>* %loadaddr, + <2 x double>* %storeaddr) { + %v0 = load <2 x i32>* %loadaddr +; CHECK: vldr +; CHECK-NEXT: vcvt.f64.u32 +; CHECK-NEXT: vcvt.f64.u32 +; CHECK-NEXT: vst + %r = uitofp <2 x i32> %v0 to <2 x double> + store <2 x double> %r, <2 x double>* %storeaddr + ret void +} diff --git a/test/CodeGen/ARM/neon_ld2.ll b/test/CodeGen/ARM/neon_ld2.ll index 497619ed74..25a670b097 100644 --- a/test/CodeGen/ARM/neon_ld2.ll +++ b/test/CodeGen/ARM/neon_ld2.ll @@ -7,10 +7,10 @@ ; CHECK: vadd.i64 q ; CHECK: vst1.64 ; SWIFT: t1 -; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}} -; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}} +; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+:128\]}} +; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+:128\]}} ; SWIFT: vadd.i64 q -; SWIFT: vst1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}} +; SWIFT: vst1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+:128\]}} define void @t1(<4 x i32>* %r, <2 x i64>* %a, <2 x i64>* %b) nounwind { entry: %0 = load <2 x i64>* %a, align 16 ; <<2 x i64>> [#uses=1] @@ -28,8 +28,8 @@ entry: ; CHECK: vmov r0, r1, d ; CHECK: vmov r2, r3, d ; SWIFT: t2 -; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}} -; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}} +; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+:128\]}} +; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+:128\]}} ; SWIFT: vsub.i64 q ; SWIFT: vmov r0, r1, d ; SWIFT: vmov r2, r3, d diff --git a/test/CodeGen/ARM/reg_sequence.ll b/test/CodeGen/ARM/reg_sequence.ll index 6d6586e4f2..fd2083cf9f 100644 --- a/test/CodeGen/ARM/reg_sequence.ll +++ b/test/CodeGen/ARM/reg_sequence.ll @@ -242,8 +242,8 @@ define arm_aapcs_vfpcc float @t9(%0* nocapture, %3* nocapture) nounwind { ; CHECK: vldr ; CHECK-NOT: vmov d{{.*}}, d16 ; CHECK: vmov.i32 d17 -; CHECK-NEXT: vst1.64 {d16, d17}, [r0, :128] -; CHECK-NEXT: vst1.64 {d16, d17}, [r0, :128] +; CHECK-NEXT: vst1.64 {d16, d17}, [r0:128] +; CHECK-NEXT: vst1.64 {d16, d17}, [r0:128] %3 = bitcast double 0.000000e+00 to <2 x float> ; <<2 x float>> [#uses=2] %4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x float>> [#uses=1] store <4 x float> %4, <4 x float>* undef, align 16 diff --git a/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll b/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll new file mode 100644 index 0000000000..d8241d0dc3 --- /dev/null +++ b/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll @@ -0,0 +1,67 @@ +; RUN: llc < %s -O1 -mtriple thumbv7-apple-ios6 +; Just make sure no one tries to make the assumption that the normal edge of an +; invoke is never a critical edge. Previously, this code would assert. + +%struct.__CFString = type opaque + +declare void @bar(%struct.__CFString*, %struct.__CFString*) + +define noalias i8* @foo(i8* nocapture %inRefURL) noreturn ssp { +entry: + %call = tail call %struct.__CFString* @bar3() + %call2 = invoke i8* @bar2() + to label %for.cond unwind label %lpad + +for.cond: ; preds = %entry, %for.cond + invoke void @bar(%struct.__CFString* undef, %struct.__CFString* null) + to label %for.cond unwind label %lpad5 + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + cleanup + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = extractvalue { i8*, i32 } %0, 1 + br label %ehcleanup + +lpad5: ; preds = %for.cond + %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + cleanup + %4 = extractvalue { i8*, i32 } %3, 0 + %5 = extractvalue { i8*, i32 } %3, 1 + invoke void @release(i8* %call2) + to label %ehcleanup unwind label %terminate.lpad.i.i16 + +terminate.lpad.i.i16: ; preds = %lpad5 + %6 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + catch i8* null + tail call void @terminatev() noreturn nounwind + unreachable + +ehcleanup: ; preds = %lpad5, %lpad + %exn.slot.0 = phi i8* [ %1, %lpad ], [ %4, %lpad5 ] + %ehselector.slot.0 = phi i32 [ %2, %lpad ], [ %5, %lpad5 ] + %7 = bitcast %struct.__CFString* %call to i8* + invoke void @release(i8* %7) + to label %_ZN5SmartIPK10__CFStringED1Ev.exit unwind label %terminate.lpad.i.i + +terminate.lpad.i.i: ; preds = %ehcleanup + %8 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) + catch i8* null + tail call void @terminatev() noreturn nounwind + unreachable + +_ZN5SmartIPK10__CFStringED1Ev.exit: ; preds = %ehcleanup + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn.slot.0, 0 + %lpad.val12 = insertvalue { i8*, i32 } %lpad.val, i32 %ehselector.slot.0, 1 + resume { i8*, i32 } %lpad.val12 +} + +declare %struct.__CFString* @bar3() + +declare i8* @bar2() + +declare i32 @__gxx_personality_sj0(...) + +declare void @release(i8*) + +declare void @terminatev() diff --git a/test/CodeGen/ARM/spill-q.ll b/test/CodeGen/ARM/spill-q.ll index 057ea11389..e93cdbc10a 100644 --- a/test/CodeGen/ARM/spill-q.ll +++ b/test/CodeGen/ARM/spill-q.ll @@ -12,8 +12,8 @@ declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly define void @aaa(%quuz* %this, i8* %block) { ; CHECK: aaa: ; CHECK: bic {{.*}}, #15 -; CHECK: vst1.64 {{.*}}sp, :128 -; CHECK: vld1.64 {{.*}}sp, :128 +; CHECK: vst1.64 {{.*}}sp:128 +; CHECK: vld1.64 {{.*}}sp:128 entry: %aligned_vec = alloca <4 x float>, align 16 %"alloca point" = bitcast i32 0 to i32 diff --git a/test/CodeGen/ARM/trap.ll b/test/CodeGen/ARM/trap.ll index 21865f8e4a..a4e3c3c0ef 100644 --- a/test/CodeGen/ARM/trap.ll +++ b/test/CodeGen/ARM/trap.ll @@ -1,5 +1,23 @@ ; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=INSTR ; RUN: llc < %s -mtriple=arm-apple-darwin -trap-func=_trap | FileCheck %s -check-prefix=FUNC +; RUN: llc -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7-unknown-nacl - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-NACL +; RUN: llc -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-NACL +; RUN: llc -mtriple=armv7 -mattr=+nacl-trap -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-NACL +; RUN: llc -fast-isel -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7-unknown-nacl - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-NACL +; RUN: llc -mtriple=armv7 -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7 - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-ALL +; RUN: llc -fast-isel -mtriple=armv7 -filetype=obj %s -o - \ +; RUN: | llvm-objdump -disassemble -triple armv7 - \ +; RUN: | FileCheck %s -check-prefix=ENCODING-ALL ; rdar://7961298 ; rdar://9249183 @@ -10,6 +28,11 @@ entry: ; FUNC: t: ; FUNC: bl __trap + +; ENCODING-NACL: f0 de fe e7 + +; ENCODING-ALL: fe de ff e7 + call void @llvm.trap() unreachable } @@ -21,6 +44,11 @@ entry: ; FUNC: t2: ; FUNC: bl __trap + +; ENCODING-NACL: f0 de fe e7 + +; ENCODING-ALL: fe de ff e7 + call void @llvm.debugtrap() unreachable } diff --git a/test/CodeGen/ARM/vector-DAGCombine.ll b/test/CodeGen/ARM/vector-DAGCombine.ll index a38a0feae0..42964deb0b 100644 --- a/test/CodeGen/ARM/vector-DAGCombine.ll +++ b/test/CodeGen/ARM/vector-DAGCombine.ll @@ -133,3 +133,30 @@ define i16 @foldBuildVectors() { %3 = extractelement <8 x i16> %2, i32 0 ret i16 %3 } + +; Test that we are generating vrev and vext for reverse shuffles of v8i16 +; shuffles. +; CHECK: reverse_v8i16 +define void @reverse_v8i16(<8 x i16>* %loadaddr, <8 x i16>* %storeaddr) { + %v0 = load <8 x i16>* %loadaddr + ; CHECK: vrev64.16 + ; CHECK: vext.16 + %v1 = shufflevector <8 x i16> %v0, <8 x i16> undef, + <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> + store <8 x i16> %v1, <8 x i16>* %storeaddr + ret void +} + +; Test that we are generating vrev and vext for reverse shuffles of v16i8 +; shuffles. +; CHECK: reverse_v16i8 +define void @reverse_v16i8(<16 x i8>* %loadaddr, <16 x i8>* %storeaddr) { + %v0 = load <16 x i8>* %loadaddr + ; CHECK: vrev64.8 + ; CHECK: vext.8 + %v1 = shufflevector <16 x i8> %v0, <16 x i8> undef, + <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, + i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> + store <16 x i8> %v1, <16 x i8>* %storeaddr + ret void +} diff --git a/test/CodeGen/ARM/vfloatintrinsics.ll b/test/CodeGen/ARM/vfloatintrinsics.ll new file mode 100644 index 0000000000..6f53b2ccd9 --- /dev/null +++ b/test/CodeGen/ARM/vfloatintrinsics.ll @@ -0,0 +1,377 @@ +; RUN: llc -mcpu=swift -march=arm < %s | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32" +target triple = "thumbv7-apple-ios6.1.0" + +;;; Float vectors + +%v2f32 = type <2 x float> +; CHECK: test_v2f32.sqrt: +define %v2f32 @test_v2f32.sqrt(%v2f32 %a) { + ; CHECK: sqrt + %1 = call %v2f32 @llvm.sqrt.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.powi: +define %v2f32 @test_v2f32.powi(%v2f32 %a, i32 %b) { + ; CHECK: pow + %1 = call %v2f32 @llvm.powi.v2f32(%v2f32 %a, i32 %b) + ret %v2f32 %1 +} +; CHECK: test_v2f32.sin: +define %v2f32 @test_v2f32.sin(%v2f32 %a) { + ; CHECK: sin + %1 = call %v2f32 @llvm.sin.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.cos: +define %v2f32 @test_v2f32.cos(%v2f32 %a) { + ; CHECK: cos + %1 = call %v2f32 @llvm.cos.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.pow: +define %v2f32 @test_v2f32.pow(%v2f32 %a, %v2f32 %b) { + ; CHECK: pow + %1 = call %v2f32 @llvm.pow.v2f32(%v2f32 %a, %v2f32 %b) + ret %v2f32 %1 +} +; CHECK: test_v2f32.exp: +define %v2f32 @test_v2f32.exp(%v2f32 %a) { + ; CHECK: exp + %1 = call %v2f32 @llvm.exp.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.exp2: +define %v2f32 @test_v2f32.exp2(%v2f32 %a) { + ; CHECK: exp + %1 = call %v2f32 @llvm.exp2.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.log: +define %v2f32 @test_v2f32.log(%v2f32 %a) { + ; CHECK: log + %1 = call %v2f32 @llvm.log.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.log10: +define %v2f32 @test_v2f32.log10(%v2f32 %a) { + ; CHECK: log + %1 = call %v2f32 @llvm.log10.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.log2: +define %v2f32 @test_v2f32.log2(%v2f32 %a) { + ; CHECK: log + %1 = call %v2f32 @llvm.log2.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.fma: +define %v2f32 @test_v2f32.fma(%v2f32 %a, %v2f32 %b, %v2f32 %c) { + ; CHECK: fma + %1 = call %v2f32 @llvm.fma.v2f32(%v2f32 %a, %v2f32 %b, %v2f32 %c) + ret %v2f32 %1 +} +; CHECK: test_v2f32.fabs: +define %v2f32 @test_v2f32.fabs(%v2f32 %a) { + ; CHECK: fabs + %1 = call %v2f32 @llvm.fabs.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.floor: +define %v2f32 @test_v2f32.floor(%v2f32 %a) { + ; CHECK: floor + %1 = call %v2f32 @llvm.floor.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.fceil: +define %v2f32 @test_v2f32.fceil(%v2f32 %a) { + ; CHECK: ceil + %1 = call %v2f32 @llvm.fceil.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.trunc: +define %v2f32 @test_v2f32.trunc(%v2f32 %a) { + ; CHECK: trunc + %1 = call %v2f32 @llvm.trunc.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.rint: +define %v2f32 @test_v2f32.rint(%v2f32 %a) { + ; CHECK: rint + %1 = call %v2f32 @llvm.rint.v2f32(%v2f32 %a) + ret %v2f32 %1 +} +; CHECK: test_v2f32.nearbyint: +define %v2f32 @test_v2f32.nearbyint(%v2f32 %a) { + ; CHECK: nearbyint + %1 = call %v2f32 @llvm.nearbyint.v2f32(%v2f32 %a) + ret %v2f32 %1 +} + +declare %v2f32 @llvm.sqrt.v2f32(%v2f32) #0 +declare %v2f32 @llvm.powi.v2f32(%v2f32, i32) #0 +declare %v2f32 @llvm.sin.v2f32(%v2f32) #0 +declare %v2f32 @llvm.cos.v2f32(%v2f32) #0 +declare %v2f32 @llvm.pow.v2f32(%v2f32, %v2f32) #0 +declare %v2f32 @llvm.exp.v2f32(%v2f32) #0 +declare %v2f32 @llvm.exp2.v2f32(%v2f32) #0 +declare %v2f32 @llvm.log.v2f32(%v2f32) #0 +declare %v2f32 @llvm.log10.v2f32(%v2f32) #0 +declare %v2f32 @llvm.log2.v2f32(%v2f32) #0 +declare %v2f32 @llvm.fma.v2f32(%v2f32, %v2f32, %v2f32) #0 +declare %v2f32 @llvm.fabs.v2f32(%v2f32) #0 +declare %v2f32 @llvm.floor.v2f32(%v2f32) #0 +declare %v2f32 @llvm.fceil.v2f32(%v2f32) #0 +declare %v2f32 @llvm.trunc.v2f32(%v2f32) #0 +declare %v2f32 @llvm.rint.v2f32(%v2f32) #0 +declare %v2f32 @llvm.nearbyint.v2f32(%v2f32) #0 + +;;; + +%v4f32 = type <4 x float> +; CHECK: test_v4f32.sqrt: +define %v4f32 @test_v4f32.sqrt(%v4f32 %a) { + ; CHECK: sqrt + %1 = call %v4f32 @llvm.sqrt.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.powi: +define %v4f32 @test_v4f32.powi(%v4f32 %a, i32 %b) { + ; CHECK: pow + %1 = call %v4f32 @llvm.powi.v4f32(%v4f32 %a, i32 %b) + ret %v4f32 %1 +} +; CHECK: test_v4f32.sin: +define %v4f32 @test_v4f32.sin(%v4f32 %a) { + ; CHECK: sin + %1 = call %v4f32 @llvm.sin.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.cos: +define %v4f32 @test_v4f32.cos(%v4f32 %a) { + ; CHECK: cos + %1 = call %v4f32 @llvm.cos.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.pow: +define %v4f32 @test_v4f32.pow(%v4f32 %a, %v4f32 %b) { + ; CHECK: pow + %1 = call %v4f32 @llvm.pow.v4f32(%v4f32 %a, %v4f32 %b) + ret %v4f32 %1 +} +; CHECK: test_v4f32.exp: +define %v4f32 @test_v4f32.exp(%v4f32 %a) { + ; CHECK: exp + %1 = call %v4f32 @llvm.exp.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.exp2: +define %v4f32 @test_v4f32.exp2(%v4f32 %a) { + ; CHECK: exp + %1 = call %v4f32 @llvm.exp2.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.log: +define %v4f32 @test_v4f32.log(%v4f32 %a) { + ; CHECK: log + %1 = call %v4f32 @llvm.log.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.log10: +define %v4f32 @test_v4f32.log10(%v4f32 %a) { + ; CHECK: log + %1 = call %v4f32 @llvm.log10.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.log2: +define %v4f32 @test_v4f32.log2(%v4f32 %a) { + ; CHECK: log + %1 = call %v4f32 @llvm.log2.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.fma: +define %v4f32 @test_v4f32.fma(%v4f32 %a, %v4f32 %b, %v4f32 %c) { + ; CHECK: fma + %1 = call %v4f32 @llvm.fma.v4f32(%v4f32 %a, %v4f32 %b, %v4f32 %c) + ret %v4f32 %1 +} +; CHECK: test_v4f32.fabs: +define %v4f32 @test_v4f32.fabs(%v4f32 %a) { + ; CHECK: fabs + %1 = call %v4f32 @llvm.fabs.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.floor: +define %v4f32 @test_v4f32.floor(%v4f32 %a) { + ; CHECK: floor + %1 = call %v4f32 @llvm.floor.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.fceil: +define %v4f32 @test_v4f32.fceil(%v4f32 %a) { + ; CHECK: ceil + %1 = call %v4f32 @llvm.fceil.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.trunc: +define %v4f32 @test_v4f32.trunc(%v4f32 %a) { + ; CHECK: trunc + %1 = call %v4f32 @llvm.trunc.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.rint: +define %v4f32 @test_v4f32.rint(%v4f32 %a) { + ; CHECK: rint + %1 = call %v4f32 @llvm.rint.v4f32(%v4f32 %a) + ret %v4f32 %1 +} +; CHECK: test_v4f32.nearbyint: +define %v4f32 @test_v4f32.nearbyint(%v4f32 %a) { + ; CHECK: nearbyint + %1 = call %v4f32 @llvm.nearbyint.v4f32(%v4f32 %a) + ret %v4f32 %1 +} + +declare %v4f32 @llvm.sqrt.v4f32(%v4f32) #0 +declare %v4f32 @llvm.powi.v4f32(%v4f32, i32) #0 +declare %v4f32 @llvm.sin.v4f32(%v4f32) #0 +declare %v4f32 @llvm.cos.v4f32(%v4f32) #0 +declare %v4f32 @llvm.pow.v4f32(%v4f32, %v4f32) #0 +declare %v4f32 @llvm.exp.v4f32(%v4f32) #0 +declare %v4f32 @llvm.exp2.v4f32(%v4f32) #0 +declare %v4f32 @llvm.log.v4f32(%v4f32) #0 +declare %v4f32 @llvm.log10.v4f32(%v4f32) #0 +declare %v4f32 @llvm.log2.v4f32(%v4f32) #0 +declare %v4f32 @llvm.fma.v4f32(%v4f32, %v4f32, %v4f32) #0 +declare %v4f32 @llvm.fabs.v4f32(%v4f32) #0 +declare %v4f32 @llvm.floor.v4f32(%v4f32) #0 +declare %v4f32 @llvm.fceil.v4f32(%v4f32) #0 +declare %v4f32 @llvm.trunc.v4f32(%v4f32) #0 +declare %v4f32 @llvm.rint.v4f32(%v4f32) #0 +declare %v4f32 @llvm.nearbyint.v4f32(%v4f32) #0 + +;;; Double vector + +%v2f64 = type <2 x double> +; CHECK: test_v2f64.sqrt: +define %v2f64 @test_v2f64.sqrt(%v2f64 %a) { + ; CHECK: sqrt + %1 = call %v2f64 @llvm.sqrt.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.powi: +define %v2f64 @test_v2f64.powi(%v2f64 %a, i32 %b) { + ; CHECK: pow + %1 = call %v2f64 @llvm.powi.v2f64(%v2f64 %a, i32 %b) + ret %v2f64 %1 +} +; CHECK: test_v2f64.sin: +define %v2f64 @test_v2f64.sin(%v2f64 %a) { + ; CHECK: sin + %1 = call %v2f64 @llvm.sin.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.cos: +define %v2f64 @test_v2f64.cos(%v2f64 %a) { + ; CHECK: cos + %1 = call %v2f64 @llvm.cos.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.pow: +define %v2f64 @test_v2f64.pow(%v2f64 %a, %v2f64 %b) { + ; CHECK: pow + %1 = call %v2f64 @llvm.pow.v2f64(%v2f64 %a, %v2f64 %b) + ret %v2f64 %1 +} +; CHECK: test_v2f64.exp: +define %v2f64 @test_v2f64.exp(%v2f64 %a) { + ; CHECK: exp + %1 = call %v2f64 @llvm.exp.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.exp2: +define %v2f64 @test_v2f64.exp2(%v2f64 %a) { + ; CHECK: exp + %1 = call %v2f64 @llvm.exp2.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.log: +define %v2f64 @test_v2f64.log(%v2f64 %a) { + ; CHECK: log + %1 = call %v2f64 @llvm.log.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.log10: +define %v2f64 @test_v2f64.log10(%v2f64 %a) { + ; CHECK: log + %1 = call %v2f64 @llvm.log10.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.log2: +define %v2f64 @test_v2f64.log2(%v2f64 %a) { + ; CHECK: log + %1 = call %v2f64 @llvm.log2.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.fma: +define %v2f64 @test_v2f64.fma(%v2f64 %a, %v2f64 %b, %v2f64 %c) { + ; CHECK: fma + %1 = call %v2f64 @llvm.fma.v2f64(%v2f64 %a, %v2f64 %b, %v2f64 %c) + ret %v2f64 %1 +} +; CHECK: test_v2f64.fabs: +define %v2f64 @test_v2f64.fabs(%v2f64 %a) { + ; CHECK: fabs + %1 = call %v2f64 @llvm.fabs.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.floor: +define %v2f64 @test_v2f64.floor(%v2f64 %a) { + ; CHECK: floor + %1 = call %v2f64 @llvm.floor.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.fceil: +define %v2f64 @test_v2f64.fceil(%v2f64 %a) { + ; CHECK: ceil + %1 = call %v2f64 @llvm.fceil.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.trunc: +define %v2f64 @test_v2f64.trunc(%v2f64 %a) { + ; CHECK: trunc + %1 = call %v2f64 @llvm.trunc.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.rint: +define %v2f64 @test_v2f64.rint(%v2f64 %a) { + ; CHECK: rint + %1 = call %v2f64 @llvm.rint.v2f64(%v2f64 %a) + ret %v2f64 %1 +} +; CHECK: test_v2f64.nearbyint: +define %v2f64 @test_v2f64.nearbyint(%v2f64 %a) { + ; CHECK: nearbyint + %1 = call %v2f64 @llvm.nearbyint.v2f64(%v2f64 %a) + ret %v2f64 %1 +} + +declare %v2f64 @llvm.sqrt.v2f64(%v2f64) #0 +declare %v2f64 @llvm.powi.v2f64(%v2f64, i32) #0 +declare %v2f64 @llvm.sin.v2f64(%v2f64) #0 +declare %v2f64 @llvm.cos.v2f64(%v2f64) #0 +declare %v2f64 @llvm.pow.v2f64(%v2f64, %v2f64) #0 +declare %v2f64 @llvm.exp.v2f64(%v2f64) #0 +declare %v2f64 @llvm.exp2.v2f64(%v2f64) #0 +declare %v2f64 @llvm.log.v2f64(%v2f64) #0 +declare %v2f64 @llvm.log10.v2f64(%v2f64) #0 +declare %v2f64 @llvm.log2.v2f64(%v2f64) #0 +declare %v2f64 @llvm.fma.v2f64(%v2f64, %v2f64, %v2f64) #0 +declare %v2f64 @llvm.fabs.v2f64(%v2f64) #0 +declare %v2f64 @llvm.floor.v2f64(%v2f64) #0 +declare %v2f64 @llvm.fceil.v2f64(%v2f64) #0 +declare %v2f64 @llvm.trunc.v2f64(%v2f64) #0 +declare %v2f64 @llvm.rint.v2f64(%v2f64) #0 +declare %v2f64 @llvm.nearbyint.v2f64(%v2f64) #0 + +attributes #0 = { nounwind readonly } diff --git a/test/CodeGen/ARM/vld1.ll b/test/CodeGen/ARM/vld1.ll index e524395c50..994f05dacb 100644 --- a/test/CodeGen/ARM/vld1.ll +++ b/test/CodeGen/ARM/vld1.ll @@ -4,7 +4,7 @@ define <8 x i8> @vld1i8(i8* %A) nounwind { ;CHECK: vld1i8: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld1.8 {d16}, [r0, :64] +;CHECK: vld1.8 {d16}, [r0:64] %tmp1 = call <8 x i8> @llvm.arm.neon.vld1.v8i8(i8* %A, i32 16) ret <8 x i8> %tmp1 } @@ -68,7 +68,7 @@ define <1 x i64> @vld1i64(i64* %A) nounwind { define <16 x i8> @vld1Qi8(i8* %A) nounwind { ;CHECK: vld1Qi8: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vld1.8 {d16, d17}, [r0, :64] +;CHECK: vld1.8 {d16, d17}, [r0:64] %tmp1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %A, i32 8) ret <16 x i8> %tmp1 } @@ -76,7 +76,7 @@ define <16 x i8> @vld1Qi8(i8* %A) nounwind { ;Check for a post-increment updating load. define <16 x i8> @vld1Qi8_update(i8** %ptr) nounwind { ;CHECK: vld1Qi8_update: -;CHECK: vld1.8 {d16, d17}, [{{r[0-9]+}}, :64]! +;CHECK: vld1.8 {d16, d17}, [{{r[0-9]+}}:64]! %A = load i8** %ptr %tmp1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %A, i32 8) %tmp2 = getelementptr i8* %A, i32 16 @@ -87,7 +87,7 @@ define <16 x i8> @vld1Qi8_update(i8** %ptr) nounwind { define <8 x i16> @vld1Qi16(i16* %A) nounwind { ;CHECK: vld1Qi16: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vld1.16 {d16, d17}, [r0, :128] +;CHECK: vld1.16 {d16, d17}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %tmp0, i32 32) ret <8 x i16> %tmp1 diff --git a/test/CodeGen/ARM/vld2.ll b/test/CodeGen/ARM/vld2.ll index 29b379465d..caa016e929 100644 --- a/test/CodeGen/ARM/vld2.ll +++ b/test/CodeGen/ARM/vld2.ll @@ -14,7 +14,7 @@ define <8 x i8> @vld2i8(i8* %A) nounwind { ;CHECK: vld2i8: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vld2.8 {d16, d17}, [r0, :64] +;CHECK: vld2.8 {d16, d17}, [r0:64] %tmp1 = call %struct.__neon_int8x8x2_t @llvm.arm.neon.vld2.v8i8(i8* %A, i32 8) %tmp2 = extractvalue %struct.__neon_int8x8x2_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x8x2_t %tmp1, 1 @@ -25,7 +25,7 @@ define <8 x i8> @vld2i8(i8* %A) nounwind { define <4 x i16> @vld2i16(i16* %A) nounwind { ;CHECK: vld2i16: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vld2.16 {d16, d17}, [r0, :128] +;CHECK: vld2.16 {d16, d17}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = call %struct.__neon_int16x4x2_t @llvm.arm.neon.vld2.v4i16(i8* %tmp0, i32 32) %tmp2 = extractvalue %struct.__neon_int16x4x2_t %tmp1, 0 @@ -74,7 +74,7 @@ define <2 x float> @vld2f_update(float** %ptr) nounwind { define <1 x i64> @vld2i64(i64* %A) nounwind { ;CHECK: vld2i64: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vld1.64 {d16, d17}, [r0, :128] +;CHECK: vld1.64 {d16, d17}, [r0:128] %tmp0 = bitcast i64* %A to i8* %tmp1 = call %struct.__neon_int64x1x2_t @llvm.arm.neon.vld2.v1i64(i8* %tmp0, i32 32) %tmp2 = extractvalue %struct.__neon_int64x1x2_t %tmp1, 0 @@ -86,7 +86,7 @@ define <1 x i64> @vld2i64(i64* %A) nounwind { define <16 x i8> @vld2Qi8(i8* %A) nounwind { ;CHECK: vld2Qi8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld2.8 {d16, d17, d18, d19}, [r0, :64] +;CHECK: vld2.8 {d16, d17, d18, d19}, [r0:64] %tmp1 = call %struct.__neon_int8x16x2_t @llvm.arm.neon.vld2.v16i8(i8* %A, i32 8) %tmp2 = extractvalue %struct.__neon_int8x16x2_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x16x2_t %tmp1, 1 @@ -97,7 +97,7 @@ define <16 x i8> @vld2Qi8(i8* %A) nounwind { ;Check for a post-increment updating load with register increment. define <16 x i8> @vld2Qi8_update(i8** %ptr, i32 %inc) nounwind { ;CHECK: vld2Qi8_update: -;CHECK: vld2.8 {d16, d17, d18, d19}, [r2, :128], r1 +;CHECK: vld2.8 {d16, d17, d18, d19}, [r2:128], r1 %A = load i8** %ptr %tmp1 = call %struct.__neon_int8x16x2_t @llvm.arm.neon.vld2.v16i8(i8* %A, i32 16) %tmp2 = extractvalue %struct.__neon_int8x16x2_t %tmp1, 0 @@ -111,7 +111,7 @@ define <16 x i8> @vld2Qi8_update(i8** %ptr, i32 %inc) nounwind { define <8 x i16> @vld2Qi16(i16* %A) nounwind { ;CHECK: vld2Qi16: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld2.16 {d16, d17, d18, d19}, [r0, :128] +;CHECK: vld2.16 {d16, d17, d18, d19}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = call %struct.__neon_int16x8x2_t @llvm.arm.neon.vld2.v8i16(i8* %tmp0, i32 16) %tmp2 = extractvalue %struct.__neon_int16x8x2_t %tmp1, 0 @@ -123,7 +123,7 @@ define <8 x i16> @vld2Qi16(i16* %A) nounwind { define <4 x i32> @vld2Qi32(i32* %A) nounwind { ;CHECK: vld2Qi32: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld2.32 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vld2.32 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i32* %A to i8* %tmp1 = call %struct.__neon_int32x4x2_t @llvm.arm.neon.vld2.v4i32(i8* %tmp0, i32 64) %tmp2 = extractvalue %struct.__neon_int32x4x2_t %tmp1, 0 diff --git a/test/CodeGen/ARM/vld3.ll b/test/CodeGen/ARM/vld3.ll index b495319830..ad63e1f716 100644 --- a/test/CodeGen/ARM/vld3.ll +++ b/test/CodeGen/ARM/vld3.ll @@ -15,7 +15,7 @@ define <8 x i8> @vld3i8(i8* %A) nounwind { ;CHECK: vld3i8: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld3.8 {d16, d17, d18}, [r0, :64] +;CHECK: vld3.8 {d16, d17, d18}, [r0:64] %tmp1 = call %struct.__neon_int8x8x3_t @llvm.arm.neon.vld3.v8i8(i8* %A, i32 32) %tmp2 = extractvalue %struct.__neon_int8x8x3_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x8x3_t %tmp1, 2 @@ -74,7 +74,7 @@ define <2 x float> @vld3f(float* %A) nounwind { define <1 x i64> @vld3i64(i64* %A) nounwind { ;CHECK: vld3i64: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld1.64 {d16, d17, d18}, [r0, :64] +;CHECK: vld1.64 {d16, d17, d18}, [r0:64] %tmp0 = bitcast i64* %A to i8* %tmp1 = call %struct.__neon_int64x1x3_t @llvm.arm.neon.vld3.v1i64(i8* %tmp0, i32 16) %tmp2 = extractvalue %struct.__neon_int64x1x3_t %tmp1, 0 @@ -86,8 +86,8 @@ define <1 x i64> @vld3i64(i64* %A) nounwind { define <16 x i8> @vld3Qi8(i8* %A) nounwind { ;CHECK: vld3Qi8: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld3.8 {d16, d18, d20}, [r0, :64]! -;CHECK: vld3.8 {d17, d19, d21}, [r0, :64] +;CHECK: vld3.8 {d16, d18, d20}, [r0:64]! +;CHECK: vld3.8 {d17, d19, d21}, [r0:64] %tmp1 = call %struct.__neon_int8x16x3_t @llvm.arm.neon.vld3.v16i8(i8* %A, i32 32) %tmp2 = extractvalue %struct.__neon_int8x16x3_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x16x3_t %tmp1, 2 diff --git a/test/CodeGen/ARM/vld4.ll b/test/CodeGen/ARM/vld4.ll index 59a73db318..9ee5fe46ee 100644 --- a/test/CodeGen/ARM/vld4.ll +++ b/test/CodeGen/ARM/vld4.ll @@ -14,7 +14,7 @@ define <8 x i8> @vld4i8(i8* %A) nounwind { ;CHECK: vld4i8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld4.8 {d16, d17, d18, d19}, [r0, :64] +;CHECK: vld4.8 {d16, d17, d18, d19}, [r0:64] %tmp1 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4.v8i8(i8* %A, i32 8) %tmp2 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 2 @@ -25,7 +25,7 @@ define <8 x i8> @vld4i8(i8* %A) nounwind { ;Check for a post-increment updating load with register increment. define <8 x i8> @vld4i8_update(i8** %ptr, i32 %inc) nounwind { ;CHECK: vld4i8_update: -;CHECK: vld4.8 {d16, d17, d18, d19}, [r2, :128], r1 +;CHECK: vld4.8 {d16, d17, d18, d19}, [r2:128], r1 %A = load i8** %ptr %tmp1 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4.v8i8(i8* %A, i32 16) %tmp2 = extractvalue %struct.__neon_int8x8x4_t %tmp1, 0 @@ -39,7 +39,7 @@ define <8 x i8> @vld4i8_update(i8** %ptr, i32 %inc) nounwind { define <4 x i16> @vld4i16(i16* %A) nounwind { ;CHECK: vld4i16: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld4.16 {d16, d17, d18, d19}, [r0, :128] +;CHECK: vld4.16 {d16, d17, d18, d19}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = call %struct.__neon_int16x4x4_t @llvm.arm.neon.vld4.v4i16(i8* %tmp0, i32 16) %tmp2 = extractvalue %struct.__neon_int16x4x4_t %tmp1, 0 @@ -51,7 +51,7 @@ define <4 x i16> @vld4i16(i16* %A) nounwind { define <2 x i32> @vld4i32(i32* %A) nounwind { ;CHECK: vld4i32: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld4.32 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vld4.32 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i32* %A to i8* %tmp1 = call %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4.v2i32(i8* %tmp0, i32 32) %tmp2 = extractvalue %struct.__neon_int32x2x4_t %tmp1, 0 @@ -74,7 +74,7 @@ define <2 x float> @vld4f(float* %A) nounwind { define <1 x i64> @vld4i64(i64* %A) nounwind { ;CHECK: vld4i64: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld1.64 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vld1.64 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i64* %A to i8* %tmp1 = call %struct.__neon_int64x1x4_t @llvm.arm.neon.vld4.v1i64(i8* %tmp0, i32 64) %tmp2 = extractvalue %struct.__neon_int64x1x4_t %tmp1, 0 @@ -86,8 +86,8 @@ define <1 x i64> @vld4i64(i64* %A) nounwind { define <16 x i8> @vld4Qi8(i8* %A) nounwind { ;CHECK: vld4Qi8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vld4.8 {d16, d18, d20, d22}, [r0, :256]! -;CHECK: vld4.8 {d17, d19, d21, d23}, [r0, :256] +;CHECK: vld4.8 {d16, d18, d20, d22}, [r0:256]! +;CHECK: vld4.8 {d17, d19, d21, d23}, [r0:256] %tmp1 = call %struct.__neon_int8x16x4_t @llvm.arm.neon.vld4.v16i8(i8* %A, i32 64) %tmp2 = extractvalue %struct.__neon_int8x16x4_t %tmp1, 0 %tmp3 = extractvalue %struct.__neon_int8x16x4_t %tmp1, 2 @@ -111,8 +111,8 @@ define <8 x i16> @vld4Qi16(i16* %A) nounwind { ;Check for a post-increment updating load. define <8 x i16> @vld4Qi16_update(i16** %ptr) nounwind { ;CHECK: vld4Qi16_update: -;CHECK: vld4.16 {d16, d18, d20, d22}, [r1, :64]! -;CHECK: vld4.16 {d17, d19, d21, d23}, [r1, :64]! +;CHECK: vld4.16 {d16, d18, d20, d22}, [r1:64]! +;CHECK: vld4.16 {d17, d19, d21, d23}, [r1:64]! %A = load i16** %ptr %tmp0 = bitcast i16* %A to i8* %tmp1 = call %struct.__neon_int16x8x4_t @llvm.arm.neon.vld4.v8i16(i8* %tmp0, i32 8) diff --git a/test/CodeGen/ARM/vlddup.ll b/test/CodeGen/ARM/vlddup.ll index c69473f87f..7c7319c090 100644 --- a/test/CodeGen/ARM/vlddup.ll +++ b/test/CodeGen/ARM/vlddup.ll @@ -13,7 +13,7 @@ define <8 x i8> @vld1dupi8(i8* %A) nounwind { define <4 x i16> @vld1dupi16(i16* %A) nounwind { ;CHECK: vld1dupi16: ;Check the alignment value. Max for this instruction is 16 bits: -;CHECK: vld1.16 {d16[]}, [r0, :16] +;CHECK: vld1.16 {d16[]}, [r0:16] %tmp1 = load i16* %A, align 8 %tmp2 = insertelement <4 x i16> undef, i16 %tmp1, i32 0 %tmp3 = shufflevector <4 x i16> %tmp2, <4 x i16> undef, <4 x i32> zeroinitializer @@ -23,7 +23,7 @@ define <4 x i16> @vld1dupi16(i16* %A) nounwind { define <2 x i32> @vld1dupi32(i32* %A) nounwind { ;CHECK: vld1dupi32: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vld1.32 {d16[]}, [r0, :32] +;CHECK: vld1.32 {d16[]}, [r0:32] %tmp1 = load i32* %A, align 8 %tmp2 = insertelement <2 x i32> undef, i32 %tmp1, i32 0 %tmp3 = shufflevector <2 x i32> %tmp2, <2 x i32> undef, <2 x i32> zeroinitializer @@ -32,7 +32,7 @@ define <2 x i32> @vld1dupi32(i32* %A) nounwind { define <2 x float> @vld1dupf(float* %A) nounwind { ;CHECK: vld1dupf: -;CHECK: vld1.32 {d16[]}, [r0, :32] +;CHECK: vld1.32 {d16[]}, [r0:32] %tmp0 = load float* %A %tmp1 = insertelement <2 x float> undef, float %tmp0, i32 0 %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> zeroinitializer @@ -51,7 +51,7 @@ define <16 x i8> @vld1dupQi8(i8* %A) nounwind { define <4 x float> @vld1dupQf(float* %A) nounwind { ;CHECK: vld1dupQf: -;CHECK: vld1.32 {d16[], d17[]}, [r0, :32] +;CHECK: vld1.32 {d16[], d17[]}, [r0:32] %tmp0 = load float* %A %tmp1 = insertelement <4 x float> undef, float %tmp0, i32 0 %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> zeroinitializer @@ -109,7 +109,7 @@ define <4 x i16> @vld2dupi16_update(i16** %ptr) nounwind { define <2 x i32> @vld2dupi32(i8* %A) nounwind { ;CHECK: vld2dupi32: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld2.32 {d16[], d17[]}, [r0, :64] +;CHECK: vld2.32 {d16[], d17[]}, [r0:64] %tmp0 = tail call %struct.__neon_int2x32x2_t @llvm.arm.neon.vld2lane.v2i32(i8* %A, <2 x i32> undef, <2 x i32> undef, i32 0, i32 16) %tmp1 = extractvalue %struct.__neon_int2x32x2_t %tmp0, 0 %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer @@ -194,7 +194,7 @@ define <2 x i32> @vld4dupi32(i8* %A) nounwind { ;CHECK: vld4dupi32: ;Check the alignment value. An 8-byte alignment is allowed here even though ;it is smaller than the total size of the memory being loaded. -;CHECK: vld4.32 {d16[], d17[], d18[], d19[]}, [r0, :64] +;CHECK: vld4.32 {d16[], d17[], d18[], d19[]}, [r0:64] %tmp0 = tail call %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4lane.v2i32(i8* %A, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 0, i32 8) %tmp1 = extractvalue %struct.__neon_int32x2x4_t %tmp0, 0 %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer diff --git a/test/CodeGen/ARM/vldlane.ll b/test/CodeGen/ARM/vldlane.ll index 7bd0cbda02..f35fa92f5d 100644 --- a/test/CodeGen/ARM/vldlane.ll +++ b/test/CodeGen/ARM/vldlane.ll @@ -14,7 +14,7 @@ define <8 x i8> @vld1lanei8(i8* %A, <8 x i8>* %B) nounwind { define <4 x i16> @vld1lanei16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vld1lanei16: ;Check the alignment value. Max for this instruction is 16 bits: -;CHECK: vld1.16 {d16[2]}, [r0, :16] +;CHECK: vld1.16 {d16[2]}, [r0:16] %tmp1 = load <4 x i16>* %B %tmp2 = load i16* %A, align 8 %tmp3 = insertelement <4 x i16> %tmp1, i16 %tmp2, i32 2 @@ -24,7 +24,7 @@ define <4 x i16> @vld1lanei16(i16* %A, <4 x i16>* %B) nounwind { define <2 x i32> @vld1lanei32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vld1lanei32: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vld1.32 {d16[1]}, [r0, :32] +;CHECK: vld1.32 {d16[1]}, [r0:32] %tmp1 = load <2 x i32>* %B %tmp2 = load i32* %A, align 8 %tmp3 = insertelement <2 x i32> %tmp1, i32 %tmp2, i32 1 @@ -34,7 +34,7 @@ define <2 x i32> @vld1lanei32(i32* %A, <2 x i32>* %B) nounwind { define <2 x i32> @vld1lanei32a32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vld1lanei32a32: ;Check the alignment value. Legal values are none or :32. -;CHECK: vld1.32 {d16[1]}, [r0, :32] +;CHECK: vld1.32 {d16[1]}, [r0:32] %tmp1 = load <2 x i32>* %B %tmp2 = load i32* %A, align 4 %tmp3 = insertelement <2 x i32> %tmp1, i32 %tmp2, i32 1 @@ -43,7 +43,7 @@ define <2 x i32> @vld1lanei32a32(i32* %A, <2 x i32>* %B) nounwind { define <2 x float> @vld1lanef(float* %A, <2 x float>* %B) nounwind { ;CHECK: vld1lanef: -;CHECK: vld1.32 {d16[1]}, [r0, :32] +;CHECK: vld1.32 {d16[1]}, [r0:32] %tmp1 = load <2 x float>* %B %tmp2 = load float* %A, align 4 %tmp3 = insertelement <2 x float> %tmp1, float %tmp2, i32 1 @@ -61,7 +61,7 @@ define <16 x i8> @vld1laneQi8(i8* %A, <16 x i8>* %B) nounwind { define <8 x i16> @vld1laneQi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vld1laneQi16: -;CHECK: vld1.16 {d17[1]}, [r0, :16] +;CHECK: vld1.16 {d17[1]}, [r0:16] %tmp1 = load <8 x i16>* %B %tmp2 = load i16* %A, align 8 %tmp3 = insertelement <8 x i16> %tmp1, i16 %tmp2, i32 5 @@ -70,7 +70,7 @@ define <8 x i16> @vld1laneQi16(i16* %A, <8 x i16>* %B) nounwind { define <4 x i32> @vld1laneQi32(i32* %A, <4 x i32>* %B) nounwind { ;CHECK: vld1laneQi32: -;CHECK: vld1.32 {d17[1]}, [r0, :32] +;CHECK: vld1.32 {d17[1]}, [r0:32] %tmp1 = load <4 x i32>* %B %tmp2 = load i32* %A, align 8 %tmp3 = insertelement <4 x i32> %tmp1, i32 %tmp2, i32 3 @@ -79,7 +79,7 @@ define <4 x i32> @vld1laneQi32(i32* %A, <4 x i32>* %B) nounwind { define <4 x float> @vld1laneQf(float* %A, <4 x float>* %B) nounwind { ;CHECK: vld1laneQf: -;CHECK: vld1.32 {d16[0]}, [r0, :32] +;CHECK: vld1.32 {d16[0]}, [r0:32] %tmp1 = load <4 x float>* %B %tmp2 = load float* %A %tmp3 = insertelement <4 x float> %tmp1, float %tmp2, i32 0 @@ -98,7 +98,7 @@ define <4 x float> @vld1laneQf(float* %A, <4 x float>* %B) nounwind { define <8 x i8> @vld2lanei8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vld2lanei8: ;Check the alignment value. Max for this instruction is 16 bits: -;CHECK: vld2.8 {d16[1], d17[1]}, [r0, :16] +;CHECK: vld2.8 {d16[1], d17[1]}, [r0:16] %tmp1 = load <8 x i8>* %B %tmp2 = call %struct.__neon_int8x8x2_t @llvm.arm.neon.vld2lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 4) %tmp3 = extractvalue %struct.__neon_int8x8x2_t %tmp2, 0 @@ -110,7 +110,7 @@ define <8 x i8> @vld2lanei8(i8* %A, <8 x i8>* %B) nounwind { define <4 x i16> @vld2lanei16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vld2lanei16: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vld2.16 {d16[1], d17[1]}, [r0, :32] +;CHECK: vld2.16 {d16[1], d17[1]}, [r0:32] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <4 x i16>* %B %tmp2 = call %struct.__neon_int16x4x2_t @llvm.arm.neon.vld2lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8) @@ -176,7 +176,7 @@ define <8 x i16> @vld2laneQi16(i16* %A, <8 x i16>* %B) nounwind { define <4 x i32> @vld2laneQi32(i32* %A, <4 x i32>* %B) nounwind { ;CHECK: vld2laneQi32: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld2.32 {d17[0], d19[0]}, [{{r[0-9]+}}, :64] +;CHECK: vld2.32 {d17[0], d19[0]}, [{{r[0-9]+}}:64] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <4 x i32>* %B %tmp2 = call %struct.__neon_int32x4x2_t @llvm.arm.neon.vld2lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 16) @@ -354,7 +354,7 @@ declare %struct.__neon_float32x4x3_t @llvm.arm.neon.vld3lane.v4f32(i8*, <4 x flo define <8 x i8> @vld4lanei8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vld4lanei8: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vld4.8 {d{{.*}}[1], d{{.*}}[1], d{{.*}}[1], d{{.*}}[1]}, [{{r[0-9]+}}, :32] +;CHECK: vld4.8 {d{{.*}}[1], d{{.*}}[1], d{{.*}}[1], d{{.*}}[1]}, [{{r[0-9]+}}:32] %tmp1 = load <8 x i8>* %B %tmp2 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8) %tmp3 = extractvalue %struct.__neon_int8x8x4_t %tmp2, 0 @@ -370,7 +370,7 @@ define <8 x i8> @vld4lanei8(i8* %A, <8 x i8>* %B) nounwind { ;Check for a post-increment updating load. define <8 x i8> @vld4lanei8_update(i8** %ptr, <8 x i8>* %B) nounwind { ;CHECK: vld4lanei8_update: -;CHECK: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [{{r[0-9]+}}, :32]! +;CHECK: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [{{r[0-9]+}}:32]! %A = load i8** %ptr %tmp1 = load <8 x i8>* %B %tmp2 = call %struct.__neon_int8x8x4_t @llvm.arm.neon.vld4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8) @@ -408,7 +408,7 @@ define <2 x i32> @vld4lanei32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vld4lanei32: ;Check the alignment value. An 8-byte alignment is allowed here even though ;it is smaller than the total size of the memory being loaded. -;CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [{{r[0-9]+}}, :64] +;CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [{{r[0-9]+}}:64] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <2 x i32>* %B %tmp2 = call %struct.__neon_int32x2x4_t @llvm.arm.neon.vld4lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 8) @@ -441,7 +441,7 @@ define <2 x float> @vld4lanef(float* %A, <2 x float>* %B) nounwind { define <8 x i16> @vld4laneQi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vld4laneQi16: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [{{r[0-9]+}}, :64] +;CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [{{r[0-9]+}}:64] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B %tmp2 = call %struct.__neon_int16x8x4_t @llvm.arm.neon.vld4lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 1, i32 16) diff --git a/test/CodeGen/ARM/vst1.ll b/test/CodeGen/ARM/vst1.ll index 364d44b711..e1f3e88907 100644 --- a/test/CodeGen/ARM/vst1.ll +++ b/test/CodeGen/ARM/vst1.ll @@ -3,7 +3,7 @@ define void @vst1i8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst1i8: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vst1.8 {d16}, [r0, :64] +;CHECK: vst1.8 {d16}, [r0:64] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst1.v8i8(i8* %A, <8 x i8> %tmp1, i32 16) ret void @@ -61,7 +61,7 @@ define void @vst1i64(i64* %A, <1 x i64>* %B) nounwind { define void @vst1Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK: vst1Qi8: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst1.8 {d16, d17}, [r0, :64] +;CHECK: vst1.8 {d16, d17}, [r0:64] %tmp1 = load <16 x i8>* %B call void @llvm.arm.neon.vst1.v16i8(i8* %A, <16 x i8> %tmp1, i32 8) ret void @@ -70,7 +70,7 @@ define void @vst1Qi8(i8* %A, <16 x i8>* %B) nounwind { define void @vst1Qi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vst1Qi16: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst1.16 {d16, d17}, [r0, :128] +;CHECK: vst1.16 {d16, d17}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B call void @llvm.arm.neon.vst1.v8i16(i8* %tmp0, <8 x i16> %tmp1, i32 32) @@ -80,7 +80,7 @@ define void @vst1Qi16(i16* %A, <8 x i16>* %B) nounwind { ;Check for a post-increment updating store with register increment. define void @vst1Qi16_update(i16** %ptr, <8 x i16>* %B, i32 %inc) nounwind { ;CHECK: vst1Qi16_update: -;CHECK: vst1.16 {d16, d17}, [r1, :64], r2 +;CHECK: vst1.16 {d16, d17}, [r1:64], r2 %A = load i16** %ptr %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B diff --git a/test/CodeGen/ARM/vst2.ll b/test/CodeGen/ARM/vst2.ll index fb05a20f66..a31f8635fe 100644 --- a/test/CodeGen/ARM/vst2.ll +++ b/test/CodeGen/ARM/vst2.ll @@ -3,7 +3,7 @@ define void @vst2i8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst2i8: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst2.8 {d16, d17}, [r0, :64] +;CHECK: vst2.8 {d16, d17}, [r0:64] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst2.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 8) ret void @@ -24,7 +24,7 @@ define void @vst2i8_update(i8** %ptr, <8 x i8>* %B, i32 %inc) nounwind { define void @vst2i16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vst2i16: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst2.16 {d16, d17}, [r0, :128] +;CHECK: vst2.16 {d16, d17}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <4 x i16>* %B call void @llvm.arm.neon.vst2.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 32) @@ -52,7 +52,7 @@ define void @vst2f(float* %A, <2 x float>* %B) nounwind { define void @vst2i64(i64* %A, <1 x i64>* %B) nounwind { ;CHECK: vst2i64: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst1.64 {d16, d17}, [r0, :128] +;CHECK: vst1.64 {d16, d17}, [r0:128] %tmp0 = bitcast i64* %A to i8* %tmp1 = load <1 x i64>* %B call void @llvm.arm.neon.vst2.v1i64(i8* %tmp0, <1 x i64> %tmp1, <1 x i64> %tmp1, i32 32) @@ -62,7 +62,7 @@ define void @vst2i64(i64* %A, <1 x i64>* %B) nounwind { ;Check for a post-increment updating store. define void @vst2i64_update(i64** %ptr, <1 x i64>* %B) nounwind { ;CHECK: vst2i64_update: -;CHECK: vst1.64 {d16, d17}, [r1, :64]! +;CHECK: vst1.64 {d16, d17}, [r1:64]! %A = load i64** %ptr %tmp0 = bitcast i64* %A to i8* %tmp1 = load <1 x i64>* %B @@ -75,7 +75,7 @@ define void @vst2i64_update(i64** %ptr, <1 x i64>* %B) nounwind { define void @vst2Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK: vst2Qi8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst2.8 {d16, d17, d18, d19}, [r0, :64] +;CHECK: vst2.8 {d16, d17, d18, d19}, [r0:64] %tmp1 = load <16 x i8>* %B call void @llvm.arm.neon.vst2.v16i8(i8* %A, <16 x i8> %tmp1, <16 x i8> %tmp1, i32 8) ret void @@ -84,7 +84,7 @@ define void @vst2Qi8(i8* %A, <16 x i8>* %B) nounwind { define void @vst2Qi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vst2Qi16: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst2.16 {d16, d17, d18, d19}, [r0, :128] +;CHECK: vst2.16 {d16, d17, d18, d19}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B call void @llvm.arm.neon.vst2.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 16) @@ -94,7 +94,7 @@ define void @vst2Qi16(i16* %A, <8 x i16>* %B) nounwind { define void @vst2Qi32(i32* %A, <4 x i32>* %B) nounwind { ;CHECK: vst2Qi32: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst2.32 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vst2.32 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <4 x i32>* %B call void @llvm.arm.neon.vst2.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 64) diff --git a/test/CodeGen/ARM/vst3.ll b/test/CodeGen/ARM/vst3.ll index f117ab205d..281bb730fe 100644 --- a/test/CodeGen/ARM/vst3.ll +++ b/test/CodeGen/ARM/vst3.ll @@ -4,7 +4,7 @@ define void @vst3i8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst3i8: ;Check the alignment value. Max for this instruction is 64 bits: ;This test runs at -O0 so do not check for specific register numbers. -;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}, :64] +;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}:64] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst3.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 32) ret void @@ -54,7 +54,7 @@ define void @vst3i64(i64* %A, <1 x i64>* %B) nounwind { ;CHECK: vst3i64: ;Check the alignment value. Max for this instruction is 64 bits: ;This test runs at -O0 so do not check for specific register numbers. -;CHECK: vst1.64 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}, :64] +;CHECK: vst1.64 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}:64] %tmp0 = bitcast i64* %A to i8* %tmp1 = load <1 x i64>* %B call void @llvm.arm.neon.vst3.v1i64(i8* %tmp0, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, i32 16) @@ -65,8 +65,8 @@ define void @vst3Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK: vst3Qi8: ;Check the alignment value. Max for this instruction is 64 bits: ;This test runs at -O0 so do not check for specific register numbers. -;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}, :64]! -;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}, :64] +;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}:64]! +;CHECK: vst3.8 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}:64] %tmp1 = load <16 x i8>* %B call void @llvm.arm.neon.vst3.v16i8(i8* %A, <16 x i8> %tmp1, <16 x i8> %tmp1, <16 x i8> %tmp1, i32 32) ret void diff --git a/test/CodeGen/ARM/vst4.ll b/test/CodeGen/ARM/vst4.ll index e94acb66bf..7dedb2fafe 100644 --- a/test/CodeGen/ARM/vst4.ll +++ b/test/CodeGen/ARM/vst4.ll @@ -3,7 +3,7 @@ define void @vst4i8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst4i8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst4.8 {d16, d17, d18, d19}, [r0, :64] +;CHECK: vst4.8 {d16, d17, d18, d19}, [r0:64] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst4.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 8) ret void @@ -12,7 +12,7 @@ define void @vst4i8(i8* %A, <8 x i8>* %B) nounwind { ;Check for a post-increment updating store with register increment. define void @vst4i8_update(i8** %ptr, <8 x i8>* %B, i32 %inc) nounwind { ;CHECK: vst4i8_update: -;CHECK: vst4.8 {d16, d17, d18, d19}, [r1, :128], r2 +;CHECK: vst4.8 {d16, d17, d18, d19}, [r1:128], r2 %A = load i8** %ptr %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst4.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 16) @@ -24,7 +24,7 @@ define void @vst4i8_update(i8** %ptr, <8 x i8>* %B, i32 %inc) nounwind { define void @vst4i16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vst4i16: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst4.16 {d16, d17, d18, d19}, [r0, :128] +;CHECK: vst4.16 {d16, d17, d18, d19}, [r0:128] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <4 x i16>* %B call void @llvm.arm.neon.vst4.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 16) @@ -34,7 +34,7 @@ define void @vst4i16(i16* %A, <4 x i16>* %B) nounwind { define void @vst4i32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vst4i32: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst4.32 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vst4.32 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <2 x i32>* %B call void @llvm.arm.neon.vst4.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 32) @@ -53,7 +53,7 @@ define void @vst4f(float* %A, <2 x float>* %B) nounwind { define void @vst4i64(i64* %A, <1 x i64>* %B) nounwind { ;CHECK: vst4i64: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst1.64 {d16, d17, d18, d19}, [r0, :256] +;CHECK: vst1.64 {d16, d17, d18, d19}, [r0:256] %tmp0 = bitcast i64* %A to i8* %tmp1 = load <1 x i64>* %B call void @llvm.arm.neon.vst4.v1i64(i8* %tmp0, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, i32 64) @@ -63,8 +63,8 @@ define void @vst4i64(i64* %A, <1 x i64>* %B) nounwind { define void @vst4Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK: vst4Qi8: ;Check the alignment value. Max for this instruction is 256 bits: -;CHECK: vst4.8 {d16, d18, d20, d22}, [r0, :256]! -;CHECK: vst4.8 {d17, d19, d21, d23}, [r0, :256] +;CHECK: vst4.8 {d16, d18, d20, d22}, [r0:256]! +;CHECK: vst4.8 {d17, d19, d21, d23}, [r0:256] %tmp1 = load <16 x i8>* %B call void @llvm.arm.neon.vst4.v16i8(i8* %A, <16 x i8> %tmp1, <16 x i8> %tmp1, <16 x i8> %tmp1, <16 x i8> %tmp1, i32 64) ret void diff --git a/test/CodeGen/ARM/vstlane.ll b/test/CodeGen/ARM/vstlane.ll index 758b355736..67f251f706 100644 --- a/test/CodeGen/ARM/vstlane.ll +++ b/test/CodeGen/ARM/vstlane.ll @@ -26,7 +26,7 @@ define void @vst1lanei8_update(i8** %ptr, <8 x i8>* %B) nounwind { define void @vst1lanei16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vst1lanei16: ;Check the alignment value. Max for this instruction is 16 bits: -;CHECK: vst1.16 {d16[2]}, [r0, :16] +;CHECK: vst1.16 {d16[2]}, [r0:16] %tmp1 = load <4 x i16>* %B %tmp2 = extractelement <4 x i16> %tmp1, i32 2 store i16 %tmp2, i16* %A, align 8 @@ -36,7 +36,7 @@ define void @vst1lanei16(i16* %A, <4 x i16>* %B) nounwind { define void @vst1lanei32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vst1lanei32: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vst1.32 {d16[1]}, [r0, :32] +;CHECK: vst1.32 {d16[1]}, [r0:32] %tmp1 = load <2 x i32>* %B %tmp2 = extractelement <2 x i32> %tmp1, i32 1 store i32 %tmp2, i32* %A, align 8 @@ -45,7 +45,7 @@ define void @vst1lanei32(i32* %A, <2 x i32>* %B) nounwind { define void @vst1lanef(float* %A, <2 x float>* %B) nounwind { ;CHECK: vst1lanef: -;CHECK: vst1.32 {d16[1]}, [r0, :32] +;CHECK: vst1.32 {d16[1]}, [r0:32] %tmp1 = load <2 x float>* %B %tmp2 = extractelement <2 x float> %tmp1, i32 1 store float %tmp2, float* %A @@ -64,7 +64,7 @@ define void @vst1laneQi8(i8* %A, <16 x i8>* %B) nounwind { define void @vst1laneQi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vst1laneQi16: -;CHECK: vst1.16 {d17[1]}, [r0, :16] +;CHECK: vst1.16 {d17[1]}, [r0:16] %tmp1 = load <8 x i16>* %B %tmp2 = extractelement <8 x i16> %tmp1, i32 5 store i16 %tmp2, i16* %A, align 8 @@ -74,7 +74,7 @@ define void @vst1laneQi16(i16* %A, <8 x i16>* %B) nounwind { define void @vst1laneQi32(i32* %A, <4 x i32>* %B) nounwind { ;CHECK: vst1laneQi32: ; // Can use scalar load. No need to use vectors. -; // CHE-CK: vst1.32 {d17[1]}, [r0, :32] +; // CHE-CK: vst1.32 {d17[1]}, [r0:32] %tmp1 = load <4 x i32>* %B %tmp2 = extractelement <4 x i32> %tmp1, i32 3 store i32 %tmp2, i32* %A, align 8 @@ -85,7 +85,7 @@ define void @vst1laneQi32(i32* %A, <4 x i32>* %B) nounwind { define void @vst1laneQi32_update(i32** %ptr, <4 x i32>* %B) nounwind { ;CHECK: vst1laneQi32_update: ; // Can use scalar load. No need to use vectors. -; // CHE-CK: vst1.32 {d17[1]}, [r1, :32]! +; // CHE-CK: vst1.32 {d17[1]}, [r1:32]! %A = load i32** %ptr %tmp1 = load <4 x i32>* %B %tmp2 = extractelement <4 x i32> %tmp1, i32 3 @@ -108,7 +108,7 @@ define void @vst1laneQf(float* %A, <4 x float>* %B) nounwind { define void @vst2lanei8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst2lanei8: ;Check the alignment value. Max for this instruction is 16 bits: -;CHECK: vst2.8 {d16[1], d17[1]}, [r0, :16] +;CHECK: vst2.8 {d16[1], d17[1]}, [r0:16] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst2lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 4) ret void @@ -117,7 +117,7 @@ define void @vst2lanei8(i8* %A, <8 x i8>* %B) nounwind { define void @vst2lanei16(i16* %A, <4 x i16>* %B) nounwind { ;CHECK: vst2lanei16: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vst2.16 {d16[1], d17[1]}, [r0, :32] +;CHECK: vst2.16 {d16[1], d17[1]}, [r0:32] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <4 x i16>* %B call void @llvm.arm.neon.vst2lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8) @@ -168,7 +168,7 @@ define void @vst2laneQi16(i16* %A, <8 x i16>* %B) nounwind { define void @vst2laneQi32(i32* %A, <4 x i32>* %B) nounwind { ;CHECK: vst2laneQi32: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vst2.32 {d17[0], d19[0]}, [r0, :64] +;CHECK: vst2.32 {d17[0], d19[0]}, [r0:64] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <4 x i32>* %B call void @llvm.arm.neon.vst2lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 16) @@ -283,7 +283,7 @@ declare void @llvm.arm.neon.vst3lane.v4f32(i8*, <4 x float>, <4 x float>, <4 x f define void @vst4lanei8(i8* %A, <8 x i8>* %B) nounwind { ;CHECK: vst4lanei8: ;Check the alignment value. Max for this instruction is 32 bits: -;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] +;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0:32] %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8) ret void @@ -292,7 +292,7 @@ define void @vst4lanei8(i8* %A, <8 x i8>* %B) nounwind { ;Check for a post-increment updating store. define void @vst4lanei8_update(i8** %ptr, <8 x i8>* %B) nounwind { ;CHECK: vst4lanei8_update: -;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r1, :32]! +;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r1:32]! %A = load i8** %ptr %tmp1 = load <8 x i8>* %B call void @llvm.arm.neon.vst4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8) @@ -313,7 +313,7 @@ define void @vst4lanei16(i16* %A, <4 x i16>* %B) nounwind { define void @vst4lanei32(i32* %A, <2 x i32>* %B) nounwind { ;CHECK: vst4lanei32: ;Check the alignment value. Max for this instruction is 128 bits: -;CHECK: vst4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] +;CHECK: vst4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0:128] %tmp0 = bitcast i32* %A to i8* %tmp1 = load <2 x i32>* %B call void @llvm.arm.neon.vst4lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 16) @@ -332,7 +332,7 @@ define void @vst4lanef(float* %A, <2 x float>* %B) nounwind { define void @vst4laneQi16(i16* %A, <8 x i16>* %B) nounwind { ;CHECK: vst4laneQi16: ;Check the alignment value. Max for this instruction is 64 bits: -;CHECK: vst4.16 {d17[3], d19[3], d21[3], d23[3]}, [r0, :64] +;CHECK: vst4.16 {d17[3], d19[3], d21[3], d23[3]}, [r0:64] %tmp0 = bitcast i16* %A to i8* %tmp1 = load <8 x i16>* %B call void @llvm.arm.neon.vst4lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 7, i32 16) diff --git a/test/CodeGen/Generic/dag-combine-crash.ll b/test/CodeGen/Generic/dag-combine-crash.ll new file mode 100644 index 0000000000..a7810b5c05 --- /dev/null +++ b/test/CodeGen/Generic/dag-combine-crash.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s + +define void @main() { +if.end: + br label %block.i.i + +block.i.i: + %tmpbb = load i8* undef + %tmp54 = zext i8 %tmpbb to i64 + %tmp59 = and i64 %tmp54, 8 + %tmp60 = add i64 %tmp59, 3691045929300498764 + %tmp62 = sub i64 %tmp60, 3456506383779105993 + %tmp63 = xor i64 1050774804270620004, %tmp62 + %tmp65 = xor i64 %tmp62, 234539545521392771 + %tmp67 = or i64 %tmp65, %tmp63 + %tmp71 = xor i64 %tmp67, 6781485823212740913 + %tmp72 = trunc i64 %tmp71 to i32 + %tmp74 = lshr i32 2, %tmp72 + store i32 %tmp74, i32* undef + br label %block.i.i +} diff --git a/test/CodeGen/Generic/inline-asm-mem-clobber.ll b/test/CodeGen/Generic/inline-asm-mem-clobber.ll new file mode 100644 index 0000000000..e523d031dc --- /dev/null +++ b/test/CodeGen/Generic/inline-asm-mem-clobber.ll @@ -0,0 +1,21 @@ +; RUN: llc -O2 < %s | FileCheck %s + +@G = common global i32 0, align 4 + +define i32 @foo(i8* %p) nounwind uwtable { +entry: + %p.addr = alloca i8*, align 8 + %rv = alloca i32, align 4 + store i8* %p, i8** %p.addr, align 8 + store i32 0, i32* @G, align 4 + %0 = load i8** %p.addr, align 8 +; CHECK: blah + %1 = call i32 asm "blah", "=r,r,~{memory}"(i8* %0) nounwind +; CHECK: @G + store i32 %1, i32* %rv, align 4 + %2 = load i32* %rv, align 4 + %3 = load i32* @G, align 4 + %add = add nsw i32 %2, %3 + ret i32 %add +} + diff --git a/test/CodeGen/Hexagon/absaddr-store.ll b/test/CodeGen/Hexagon/absaddr-store.ll new file mode 100644 index 0000000000..5c2554df8a --- /dev/null +++ b/test/CodeGen/Hexagon/absaddr-store.ll @@ -0,0 +1,46 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate load instructions with absolute addressing mode. + +@a = external global i32 +@b = external global i8 +@c = external global i16 +@d = external global i64 + +define zeroext i8 @absStoreByte() nounwind { +; CHECK: memb(##b){{ *}}={{ *}}r{{[0-9]+}} +entry: + %0 = load i8* @b, align 1 + %conv = zext i8 %0 to i32 + %mul = mul nsw i32 100, %conv + %conv1 = trunc i32 %mul to i8 + store i8 %conv1, i8* @b, align 1 + ret i8 %conv1 +} + +define signext i16 @absStoreHalf() nounwind { +; CHECK: memh(##c){{ *}}={{ *}}r{{[0-9]+}} +entry: + %0 = load i16* @c, align 2 + %conv = sext i16 %0 to i32 + %mul = mul nsw i32 100, %conv + %conv1 = trunc i32 %mul to i16 + store i16 %conv1, i16* @c, align 2 + ret i16 %conv1 +} + +define i32 @absStoreWord() nounwind { +; CHECK: memw(##a){{ *}}={{ *}}r{{[0-9]+}} +entry: + %0 = load i32* @a, align 4 + %mul = mul nsw i32 100, %0 + store i32 %mul, i32* @a, align 4 + ret i32 %mul +} + +define void @absStoreDouble() nounwind { +; CHECK: memd(##d){{ *}}={{ *}}r{{[0-9]+}}:{{[0-9]+}} +entry: + store i64 100, i64* @d, align 8 + ret void +} + diff --git a/test/CodeGen/Hexagon/adde.ll b/test/CodeGen/Hexagon/adde.ll new file mode 100644 index 0000000000..9cee3e215d --- /dev/null +++ b/test/CodeGen/Hexagon/adde.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK: r{{[0-9]+:[0-9]+}} = #0 +; CHECK: r{{[0-9]+:[0-9]+}} = #1 +; CHECK: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) + + +define void @check_adde_addc (i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) { +entry: + %tmp1 = zext i64 %AL to i128 + %tmp23 = zext i64 %AH to i128 + %tmp4 = shl i128 %tmp23, 64 + %tmp5 = or i128 %tmp4, %tmp1 + %tmp67 = zext i64 %BL to i128 + %tmp89 = zext i64 %BH to i128 + %tmp11 = shl i128 %tmp89, 64 + %tmp12 = or i128 %tmp11, %tmp67 + %tmp15 = add i128 %tmp12, %tmp5 + %tmp1617 = trunc i128 %tmp15 to i64 + store i64 %tmp1617, i64* %RL + %tmp21 = lshr i128 %tmp15, 64 + %tmp2122 = trunc i128 %tmp21 to i64 + store i64 %tmp2122, i64* %RH + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/args.ll b/test/CodeGen/Hexagon/args.ll index 767a442612..f8c9e44c83 100644 --- a/test/CodeGen/Hexagon/args.ll +++ b/test/CodeGen/Hexagon/args.ll @@ -1,11 +1,11 @@ -; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-hexagon-misched < %s | FileCheck %s +; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-dfa-sched -disable-hexagon-misched < %s | FileCheck %s ; CHECK: memw(r29{{ *}}+{{ *}}#0){{ *}}={{ *}}#7 -; CHECK: r5 = #6 ; CHECK: r0 = #1 ; CHECK: r1 = #2 ; CHECK: r2 = #3 ; CHECK: r3 = #4 ; CHECK: r4 = #5 +; CHECK: r5 = #6 define void @foo() nounwind { diff --git a/test/CodeGen/Hexagon/block-addr.ll b/test/CodeGen/Hexagon/block-addr.ll new file mode 100644 index 0000000000..54a12bf484 --- /dev/null +++ b/test/CodeGen/Hexagon/block-addr.ll @@ -0,0 +1,64 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK: r{{[0-9]+}} = CONST32(#.LJTI{{[0-9]+_[0-9]+}}) +; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}+r{{[0-9]+<<#[0-9]+}}) +; CHECK: jumpr r{{[0-9]+}} + +define void @main() #0 { +entry: + %ret = alloca i32, align 4 + br label %while.body + +while.body: + %ret.0.load17 = load volatile i32* %ret, align 4 + switch i32 %ret.0.load17, label %label6 [ + i32 0, label %label0 + i32 1, label %label1 + i32 2, label %label2 + i32 3, label %label3 + i32 4, label %label4 + i32 5, label %label5 + ] + +label0: + %ret.0.load18 = load volatile i32* %ret, align 4 + %inc = add nsw i32 %ret.0.load18, 1 + store volatile i32 %inc, i32* %ret, align 4 + br label %while.body + +label1: + %ret.0.load19 = load volatile i32* %ret, align 4 + %inc2 = add nsw i32 %ret.0.load19, 1 + store volatile i32 %inc2, i32* %ret, align 4 + br label %while.body + +label2: + %ret.0.load20 = load volatile i32* %ret, align 4 + %inc4 = add nsw i32 %ret.0.load20, 1 + store volatile i32 %inc4, i32* %ret, align 4 + br label %while.body + +label3: + %ret.0.load21 = load volatile i32* %ret, align 4 + %inc6 = add nsw i32 %ret.0.load21, 1 + store volatile i32 %inc6, i32* %ret, align 4 + br label %while.body + +label4: + %ret.0.load22 = load volatile i32* %ret, align 4 + %inc8 = add nsw i32 %ret.0.load22, 1 + store volatile i32 %inc8, i32* %ret, align 4 + br label %while.body + +label5: + %ret.0.load23 = load volatile i32* %ret, align 4 + %inc10 = add nsw i32 %ret.0.load23, 1 + store volatile i32 %inc10, i32* %ret, align 4 + br label %while.body + +label6: + store volatile i32 0, i32* %ret, align 4 + br label %while.body +} + +attributes #0 = { noreturn nounwind "target-cpu"="hexagonv4" } diff --git a/test/CodeGen/Hexagon/cext-check.ll b/test/CodeGen/Hexagon/cext-check.ll new file mode 100644 index 0000000000..7c4b19e5a4 --- /dev/null +++ b/test/CodeGen/Hexagon/cext-check.ll @@ -0,0 +1,57 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we constant extended instructions only when necessary. + +define i32 @cext_test1(i32* %a) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##8000) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##4092) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300) +entry: + %0 = load i32* %a, align 4 + %tobool = icmp ne i32 %0, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: + %arrayidx1 = getelementptr inbounds i32* %a, i32 2000 + %1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %1, 300000 + br label %return + +if.end: + %arrayidx2 = getelementptr inbounds i32* %a, i32 1023 + %2 = load i32* %arrayidx2, align 4 + %add3 = add nsw i32 %2, 300 + br label %return + +return: + %retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ] + ret i32 %retval.0 +} + +define i32 @cext_test2(i8* %a) nounwind { +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1023) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1024) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##6000) +entry: + %tobool = icmp ne i8* %a, null + br i1 %tobool, label %if.then, label %if.end + +if.then: + %arrayidx = getelementptr inbounds i8* %a, i32 1023 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 300000 + br label %return + +if.end: + %arrayidx1 = getelementptr inbounds i8* %a, i32 1024 + %1 = load i8* %arrayidx1, align 1 + %conv2 = zext i8 %1 to i32 + %add3 = add nsw i32 %conv2, 6000 + br label %return + +return: + %retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ] + ret i32 %retval.0 +} diff --git a/test/CodeGen/Hexagon/cext-valid-packet1.ll b/test/CodeGen/Hexagon/cext-valid-packet1.ll new file mode 100644 index 0000000000..a479d37e4a --- /dev/null +++ b/test/CodeGen/Hexagon/cext-valid-packet1.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s + +; Check that the packetizer generates valid packets with constant +; extended instructions. +; CHECK: { +; CHECK-NEXT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}, ##{{[0-9]+}}) +; CHECK-NEXT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}, ##{{[0-9]+}}) +; CHECK-NEXT: } + +define i32 @check-packet1(i32 %a, i32 %b, i32 %c) nounwind readnone { +entry: + %add = add nsw i32 %a, 200000 + %add1 = add nsw i32 %b, 200001 + %add2 = add nsw i32 %c, 200002 + %cmp = icmp sgt i32 %add, %add1 + %b.addr.0 = select i1 %cmp, i32 %add1, i32 %add2 + ret i32 %b.addr.0 +} diff --git a/test/CodeGen/Hexagon/cext-valid-packet2.ll b/test/CodeGen/Hexagon/cext-valid-packet2.ll new file mode 100644 index 0000000000..2788a6b1c8 --- /dev/null +++ b/test/CodeGen/Hexagon/cext-valid-packet2.ll @@ -0,0 +1,43 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that the packetizer generates valid packets with constant +; extended add and base+offset store instructions. + +; CHECK: { +; CHECK-NEXT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}, ##{{[0-9]+}}) +; CHECK-NEXT: memw(r{{[0-9]+}}+{{ *}}##{{[0-9]+}}){{ *}}={{ *}}r{{[0-9]+}}.new +; CHECK-NEXT: } + +define i32 @test(i32* nocapture %a, i32* nocapture %b, i32 %c) nounwind { +entry: + %add = add nsw i32 %c, 200002 + %0 = load i32* %a, align 4 + %add1 = add nsw i32 %0, 200000 + %arrayidx2 = getelementptr inbounds i32* %a, i32 3000 + store i32 %add1, i32* %arrayidx2, align 4 + %1 = load i32* %b, align 4 + %add4 = add nsw i32 %1, 200001 + %arrayidx5 = getelementptr inbounds i32* %a, i32 1 + store i32 %add4, i32* %arrayidx5, align 4 + %arrayidx7 = getelementptr inbounds i32* %b, i32 1 + %2 = load i32* %arrayidx7, align 4 + %cmp = icmp sgt i32 %add4, %2 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %arrayidx8 = getelementptr inbounds i32* %a, i32 2 + %3 = load i32* %arrayidx8, align 4 + %arrayidx9 = getelementptr inbounds i32* %b, i32 2000 + %4 = load i32* %arrayidx9, align 4 + %sub = sub nsw i32 %3, %4 + %arrayidx10 = getelementptr inbounds i32* %a, i32 4000 + store i32 %sub, i32* %arrayidx10, align 4 + br label %if.end + +if.else: ; preds = %entry + %arrayidx11 = getelementptr inbounds i32* %b, i32 3200 + store i32 %add, i32* %arrayidx11, align 4 + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret i32 %add +} diff --git a/test/CodeGen/Hexagon/cmp-to-genreg.ll b/test/CodeGen/Hexagon/cmp-to-genreg.ll new file mode 100644 index 0000000000..97cf51ce1a --- /dev/null +++ b/test/CodeGen/Hexagon/cmp-to-genreg.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate compare to general register. + +define i32 @compare1(i32 %a) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}cmp.eq(r{{[0-9]+}},{{ *}}#120) +entry: + %cmp = icmp eq i32 %a, 120 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +define i32 @compare2(i32 %a) nounwind readnone { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}#120) +entry: + %cmp = icmp ne i32 %a, 120 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +define i32 @compare3(i32 %a, i32 %b) nounwind readnone { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}}) +entry: + %cmp = icmp eq i32 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +define i32 @compare4(i32 %a, i32 %b) nounwind readnone { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}}) +entry: + %cmp = icmp ne i32 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} diff --git a/test/CodeGen/Hexagon/cmp-to-predreg.ll b/test/CodeGen/Hexagon/cmp-to-predreg.ll new file mode 100644 index 0000000000..d430b90186 --- /dev/null +++ b/test/CodeGen/Hexagon/cmp-to-predreg.ll @@ -0,0 +1,43 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate compare to predicate register. + +define i32 @compare1(i32 %a, i32 %b) nounwind { +; CHECK: p{{[0-3]}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}}) +entry: + %cmp = icmp ne i32 %a, %b + %add = add nsw i32 %a, %b + %sub = sub nsw i32 %a, %b + %add.sub = select i1 %cmp, i32 %add, i32 %sub + ret i32 %add.sub +} + +define i32 @compare2(i32 %a) nounwind { +; CHECK: p{{[0-3]}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}#10) +entry: + %cmp = icmp ne i32 %a, 10 + %add = add nsw i32 %a, 10 + %sub = sub nsw i32 %a, 10 + %add.sub = select i1 %cmp, i32 %add, i32 %sub + ret i32 %add.sub +} + +define i32 @compare3(i32 %a, i32 %b) nounwind { +; CHECK: p{{[0-3]}}{{ *}}={{ *}}cmp.gt(r{{[0-9]+}},{{ *}}r{{[0-9]+}}) +entry: + %cmp = icmp sgt i32 %a, %b + %sub = sub nsw i32 %a, %b + %add = add nsw i32 %a, %b + %sub.add = select i1 %cmp, i32 %sub, i32 %add + ret i32 %sub.add +} + +define i32 @compare4(i32 %a) nounwind { +; CHECK: p{{[0-3]}}{{ *}}={{ *}}cmp.gt(r{{[0-9]+}},{{ *}}#10) +entry: + %cmp = icmp sgt i32 %a, 10 + %sub = sub nsw i32 %a, 10 + %add = add nsw i32 %a, 10 + %sub.add = select i1 %cmp, i32 %sub, i32 %add + ret i32 %sub.add +} + diff --git a/test/CodeGen/Hexagon/cmp_pred.ll b/test/CodeGen/Hexagon/cmp_pred.ll new file mode 100644 index 0000000000..37db3b499f --- /dev/null +++ b/test/CodeGen/Hexagon/cmp_pred.ll @@ -0,0 +1,115 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s +; Generate various cmpb instruction followed by if (p0) .. if (!p0)... +target triple = "hexagon" + +define i32 @Func_3Ugt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ugt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Uge(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp uge i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ult(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ult i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ule(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ule i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ueq(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp eq i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Une(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3UneC(i32 %Enum_Par_Val) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, 122 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3gt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK: mux + %cmp = icmp sgt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3ge(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp sge i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3lt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp slt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3le(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp sle i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3eq(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp eq i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3ne(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3neC(i32 %Enum_Par_Val) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, 122 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} diff --git a/test/CodeGen/Hexagon/cmp_pred_reg.ll b/test/CodeGen/Hexagon/cmp_pred_reg.ll new file mode 100644 index 0000000000..37db3b499f --- /dev/null +++ b/test/CodeGen/Hexagon/cmp_pred_reg.ll @@ -0,0 +1,115 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s +; Generate various cmpb instruction followed by if (p0) .. if (!p0)... +target triple = "hexagon" + +define i32 @Func_3Ugt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ugt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Uge(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp uge i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ult(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ult i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ule(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ule i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Ueq(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp eq i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3Une(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3UneC(i32 %Enum_Par_Val) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, 122 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3gt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK: mux + %cmp = icmp sgt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3ge(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp sge i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3lt(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp slt i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3le(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp sle i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3eq(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp eq i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3ne(i32 %Enum_Par_Val, i32 %pv2) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, %pv2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3neC(i32 %Enum_Par_Val) nounwind readnone { +entry: +; CHECK-NOT: mux + %cmp = icmp ne i32 %Enum_Par_Val, 122 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} diff --git a/test/CodeGen/Hexagon/cmpb_pred.ll b/test/CodeGen/Hexagon/cmpb_pred.ll new file mode 100644 index 0000000000..1e6144701f --- /dev/null +++ b/test/CodeGen/Hexagon/cmpb_pred.ll @@ -0,0 +1,92 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s +; Generate various cmpb instruction followed by if (p0) .. if (!p0)... +target triple = "hexagon" + +@Enum_global = external global i8 + +define i32 @Func_3(i32) nounwind readnone { +entry: +; CHECK-NOT: mux + %conv = and i32 %0, 255 + %cmp = icmp eq i32 %conv, 2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3b(i32) nounwind readonly { +entry: +; CHECK-NOT: mux + %1 = load i8* @Enum_global, align 1, !tbaa !0 + %2 = trunc i32 %0 to i8 + %cmp = icmp ne i8 %1, %2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3c(i32) nounwind readnone { +entry: +; CHECK-NOT: mux + %conv = and i32 %0, 255 + %cmp = icmp eq i32 %conv, 2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3d(i32) nounwind readonly { +entry: +; CHECK-NOT: mux + %1 = load i8* @Enum_global, align 1, !tbaa !0 + %2 = trunc i32 %0 to i8 + %cmp = icmp eq i8 %1, %2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3e(i32) nounwind readonly { +entry: +; CHECK-NOT: mux + %1 = load i8* @Enum_global, align 1, !tbaa !0 + %2 = trunc i32 %0 to i8 + %cmp = icmp eq i8 %1, %2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3f(i32) nounwind readnone { +entry: +; CHECK-NOT: mux + %conv = and i32 %0, 255 + %cmp = icmp ugt i32 %conv, 2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3g(i32) nounwind readnone { +entry: +; CHECK: mux + %conv = and i32 %0, 255 + %cmp = icmp ult i32 %conv, 3 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3h(i32) nounwind readnone { +entry: +; CHECK-NOT: mux + %conv = and i32 %0, 254 + %cmp = icmp ult i32 %conv, 2 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +define i32 @Func_3i(i32) nounwind readnone { +entry: +; CHECK-NOT: mux + %conv = and i32 %0, 254 + %cmp = icmp ugt i32 %conv, 1 + %selv = zext i1 %cmp to i32 + ret i32 %selv +} + +!0 = metadata !{metadata !"omnipotent char", metadata !1} +!1 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/Hexagon/combine_ir.ll b/test/CodeGen/Hexagon/combine_ir.ll new file mode 100644 index 0000000000..921ce9928e --- /dev/null +++ b/test/CodeGen/Hexagon/combine_ir.ll @@ -0,0 +1,55 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; CHECK: word +; CHECK: combine(#0 + +define void @word(i32* nocapture %a) nounwind { +entry: + %0 = load i32* %a, align 4, !tbaa !0 + %1 = zext i32 %0 to i64 + %add.ptr = getelementptr inbounds i32* %a, i32 1 + %2 = load i32* %add.ptr, align 4, !tbaa !0 + %3 = zext i32 %2 to i64 + %4 = shl nuw i64 %3, 32 + %ins = or i64 %4, %1 + tail call void @bar(i64 %ins) nounwind + ret void +} + +declare void @bar(i64) + +; CHECK: halfword +; CHECK: combine(#0 + +define void @halfword(i16* nocapture %a) nounwind { +entry: + %0 = load i16* %a, align 2, !tbaa !3 + %1 = zext i16 %0 to i64 + %add.ptr = getelementptr inbounds i16* %a, i32 1 + %2 = load i16* %add.ptr, align 2, !tbaa !3 + %3 = zext i16 %2 to i64 + %4 = shl nuw nsw i64 %3, 16 + %ins = or i64 %4, %1 + tail call void @bar(i64 %ins) nounwind + ret void +} + +; CHECK: byte +; CHECK: combine(#0 + +define void @byte(i8* nocapture %a) nounwind { +entry: + %0 = load i8* %a, align 1, !tbaa !1 + %1 = zext i8 %0 to i64 + %add.ptr = getelementptr inbounds i8* %a, i32 1 + %2 = load i8* %add.ptr, align 1, !tbaa !1 + %3 = zext i8 %2 to i64 + %4 = shl nuw nsw i64 %3, 8 + %ins = or i64 %4, %1 + tail call void @bar(i64 %ins) nounwind + ret void +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} +!3 = metadata !{metadata !"short", metadata !1} diff --git a/test/CodeGen/Hexagon/ctlz-cttz-ctpop.ll b/test/CodeGen/Hexagon/ctlz-cttz-ctpop.ll new file mode 100644 index 0000000000..e942f8d0c5 --- /dev/null +++ b/test/CodeGen/Hexagon/ctlz-cttz-ctpop.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s + +; CHECK: r{{[0-9]+}}:{{[0-9]+}} |= lsr(r{{[0-9]+}}:{{[0-9]+}}, #4) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} &= lsr(r{{[0-9]+}}:{{[0-9]+}}, #2) +; CHECK: r{{[0-9]+}} += lsr(r{{[0-9]+}}, #4) + +define i32 @foo(i64 %a, i32 %b) nounwind { +entry: + %tmp0 = tail call i64 @llvm.ctlz.i64( i64 %a, i1 true ) + %tmp1 = tail call i64 @llvm.cttz.i64( i64 %a, i1 true ) + %tmp2 = tail call i32 @llvm.ctlz.i32( i32 %b, i1 true ) + %tmp3 = tail call i32 @llvm.cttz.i32( i32 %b, i1 true ) + %tmp4 = tail call i64 @llvm.ctpop.i64( i64 %a ) + %tmp5 = tail call i32 @llvm.ctpop.i32( i32 %b ) + + + %tmp6 = trunc i64 %tmp0 to i32 + %tmp7 = trunc i64 %tmp1 to i32 + %tmp8 = trunc i64 %tmp4 to i32 + %tmp9 = add i32 %tmp6, %tmp7 + %tmp10 = add i32 %tmp9, %tmp8 + %tmp11 = add i32 %tmp10, %tmp2 + %tmp12 = add i32 %tmp11, %tmp3 + %tmp13 = add i32 %tmp12, %tmp5 + + ret i32 %tmp13 +} + +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone +declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone +declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone +declare i64 @llvm.ctpop.i64(i64) nounwind readnone +declare i32 @llvm.ctpop.i32(i32) nounwind readnone diff --git a/test/CodeGen/Hexagon/dualstore.ll b/test/CodeGen/Hexagon/dualstore.ll index 067499530f..f7d7e8bbe7 100644 --- a/test/CodeGen/Hexagon/dualstore.ll +++ b/test/CodeGen/Hexagon/dualstore.ll @@ -1,8 +1,8 @@ -; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-hexagon-misched < %s | FileCheck %s ; Check that we generate dual stores in one packet in V4 -; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#100000 -; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#500000 +; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##500000 +; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##100000 ; CHECK-NEXT: } @Reg = global i32 0, align 4 diff --git a/test/CodeGen/Hexagon/gp-plus-offset-load.ll b/test/CodeGen/Hexagon/gp-plus-offset-load.ll new file mode 100644 index 0000000000..a1b80a65f8 --- /dev/null +++ b/test/CodeGen/Hexagon/gp-plus-offset-load.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate load instructions with global + offset + +%struct.struc = type { i8, i8, i16, i32 } + +@foo = common global %struct.struc zeroinitializer, align 4 + +define void @loadWord(i32 %val1, i32 %val2, i32* nocapture %ival) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(##foo{{ *}}+{{ *}}4) +entry: + %cmp = icmp sgt i32 %val1, %val2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %0 = load i32* getelementptr inbounds (%struct.struc* @foo, i32 0, i32 3), align 4 + store i32 %0, i32* %ival, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +define void @loadByte(i32 %val1, i32 %val2, i8* nocapture %ival) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memb(##foo{{ *}}+{{ *}}1) +entry: + %cmp = icmp sgt i32 %val1, %val2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %0 = load i8* getelementptr inbounds (%struct.struc* @foo, i32 0, i32 1), align 1 + store i8 %0, i8* %ival, align 1 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +define void @loadHWord(i32 %val1, i32 %val2, i16* %ival) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memh(##foo{{ *}}+{{ *}}2) +entry: + %cmp = icmp sgt i32 %val1, %val2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %0 = load i16* getelementptr inbounds (%struct.struc* @foo, i32 0, i32 2), align 2 + store i16 %0, i16* %ival, align 2 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} diff --git a/test/CodeGen/Hexagon/gp-plus-offset-store.ll b/test/CodeGen/Hexagon/gp-plus-offset-store.ll new file mode 100644 index 0000000000..c782b30920 --- /dev/null +++ b/test/CodeGen/Hexagon/gp-plus-offset-store.ll @@ -0,0 +1,35 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate store instructions with global + offset + +%struct.struc = type { i8, i8, i16, i32 } + +@foo = common global %struct.struc zeroinitializer, align 4 + +define void @storeByte(i32 %val1, i32 %val2, i8 zeroext %ival) nounwind { +; CHECK: memb(##foo{{ *}}+{{ *}}1){{ *}}={{ *}}r{{[0-9]+}} +entry: + %cmp = icmp sgt i32 %val1, %val2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i8 %ival, i8* getelementptr inbounds (%struct.struc* @foo, i32 0, i32 1), align 1 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +define void @storeHW(i32 %val1, i32 %val2, i16 signext %ival) nounwind { +; CHECK: memh(##foo{{ *}}+{{ *}}2){{ *}}={{ *}}r{{[0-9]+}} +entry: + %cmp = icmp sgt i32 %val1, %val2 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i16 %ival, i16* getelementptr inbounds (%struct.struc* @foo, i32 0, i32 2), align 2 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + diff --git a/test/CodeGen/Hexagon/hwloop-cleanup.ll b/test/CodeGen/Hexagon/hwloop-cleanup.ll new file mode 100644 index 0000000000..6456ebff16 --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-cleanup.ll @@ -0,0 +1,86 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we remove the compare and induction variable instructions +; after generating hardware loops. +; Bug 6685. + +; CHECK: loop0 +; CHECK-NOT: r{{[0-9]+}}{{.}}={{.}}add(r{{[0-9]+}},{{.}}#-1) +; CHECK-NOT: cmp.eq +; CHECK: endloop0 + +define i32 @test1(i32* nocapture %b, i32 %n) nounwind readonly { +entry: + %cmp1 = icmp sgt i32 %n, 0 + br i1 %cmp1, label %for.body.preheader, label %for.end + +for.body.preheader: + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %sum.03 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] + %arrayidx.phi = phi i32* [ %arrayidx.inc, %for.body ], [ %b, %for.body.preheader ] + %i.02 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ] + %0 = load i32* %arrayidx.phi, align 4 + %add = add nsw i32 %0, %sum.03 + %inc = add nsw i32 %i.02, 1 + %exitcond = icmp eq i32 %inc, %n + %arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1 + br i1 %exitcond, label %for.end.loopexit, label %for.body + +for.end.loopexit: + br label %for.end + +for.end: + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ] + ret i32 %sum.0.lcssa +} + +; This test checks that that initial loop count value is removed. +; CHECK-NOT: ={{.}}#40 +; CHECK: loop0 +; CHECK-NOT: r{{[0-9]+}}{{.}}={{.}}add(r{{[0-9]+}},{{.}}#-1) +; CHECK-NOT: cmp.eq +; CHECK: endloop0 + +define i32 @test2(i32* nocapture %b) nounwind readonly { +entry: + br label %for.body + +for.body: + %sum.02 = phi i32 [ 0, %entry ], [ %add, %for.body ] + %arrayidx.phi = phi i32* [ %b, %entry ], [ %arrayidx.inc, %for.body ] + %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %0 = load i32* %arrayidx.phi, align 4 + %add = add nsw i32 %0, %sum.02 + %inc = add nsw i32 %i.01, 1 + %exitcond = icmp eq i32 %inc, 40 + %arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1 + br i1 %exitcond, label %for.end, label %for.body + +for.end: + ret i32 %add +} + +; This test checks that we don't remove the induction variable since it's used. +; CHECK: loop0 +; CHECK: r{{[0-9]+}}{{.}}={{.}}add(r{{[0-9]+}},{{.}}#1) +; CHECK-NOT: cmp.eq +; CHECK: endloop0 +define i32 @test3(i32* nocapture %b) nounwind { +entry: + br label %for.body + +for.body: + %arrayidx.phi = phi i32* [ %b, %entry ], [ %arrayidx.inc, %for.body ] + %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + store i32 %i.01, i32* %arrayidx.phi, align 4 + %inc = add nsw i32 %i.01, 1 + %exitcond = icmp eq i32 %inc, 40 + %arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1 + br i1 %exitcond, label %for.end, label %for.body + +for.end: + ret i32 0 +} + + diff --git a/test/CodeGen/Hexagon/hwloop-const.ll b/test/CodeGen/Hexagon/hwloop-const.ll new file mode 100644 index 0000000000..a621c58c63 --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-const.ll @@ -0,0 +1,31 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 -O2 < %s | FileCheck %s +; ModuleID = 'hwloop-const.c' +target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32" +target triple = "hexagon-unknown-linux-gnu" + +@b = common global [25000 x i32] zeroinitializer, align 8 +@a = common global [25000 x i32] zeroinitializer, align 8 +@c = common global [25000 x i32] zeroinitializer, align 8 + +define i32 @hwloop_bug() nounwind { +entry: + br label %for.body + +; CHECK: endloop +for.body: ; preds = %for.body, %entry + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds [25000 x i32]* @b, i32 0, i32 %i.02 + store i32 %i.02, i32* %arrayidx, align 4, !tbaa !0 + %arrayidx1 = getelementptr inbounds [25000 x i32]* @a, i32 0, i32 %i.02 + store i32 %i.02, i32* %arrayidx1, align 4, !tbaa !0 + %inc = add nsw i32 %i.02, 1 + %exitcond = icmp eq i32 %inc, 25000 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret i32 0 +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/Hexagon/hwloop-dbg.ll b/test/CodeGen/Hexagon/hwloop-dbg.ll new file mode 100644 index 0000000000..eaffa0797a --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-dbg.ll @@ -0,0 +1,65 @@ +; RUN: llc < %s -march=hexagon -mcpu=hexagonv4 -O2 -disable-lsr | FileCheck %s +; ModuleID = 'hwloop-dbg.o' +target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32" +target triple = "hexagon" + +define void @foo(i32* nocapture %a, i32* nocapture %b) nounwind { +entry: + tail call void @llvm.dbg.value(metadata !{i32* %a}, i64 0, metadata !13), !dbg !17 + tail call void @llvm.dbg.value(metadata !{i32* %b}, i64 0, metadata !14), !dbg !18 + tail call void @llvm.dbg.value(metadata !2, i64 0, metadata !15), !dbg !19 + br label %for.body, !dbg !19 + +for.body: ; preds = %for.body, %entry +; CHECK: loop0( +; CHECK-NOT: add({{r[0-9]*}}, # +; CHECK: endloop0 + %arrayidx.phi = phi i32* [ %a, %entry ], [ %arrayidx.inc, %for.body ] + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %b.addr.01 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.body ] + %incdec.ptr = getelementptr inbounds i32* %b.addr.01, i32 1, !dbg !21 + tail call void @llvm.dbg.value(metadata !{i32* %incdec.ptr}, i64 0, metadata !14), !dbg !21 + %0 = load i32* %b.addr.01, align 4, !dbg !21, !tbaa !23 + store i32 %0, i32* %arrayidx.phi, align 4, !dbg !21, !tbaa !23 + %inc = add nsw i32 %i.02, 1, !dbg !26 + tail call void @llvm.dbg.value(metadata !{i32 %inc}, i64 0, metadata !15), !dbg !26 + %exitcond = icmp eq i32 %inc, 10, !dbg !19 + %arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1 + br i1 %exitcond, label %for.end, label %for.body, !dbg !19 + +for.end: ; preds = %for.body + ret void, !dbg !27 +} + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"hwloop-dbg.c", metadata !"/usr2/kparzysz/s.hex/t", metadata !"QuIC LLVM Hexagon Clang version 6.1-pre-unknown, (git://git-hexagon-aus.quicinc.com/llvm/clang-mainline.git e9382867661454cdf44addb39430741578e9765c) (llvm/llvm-mainline.git 36412bb1fcf03ed426d4437b41198bae066675ac)", i1 true, i1 true, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] [/usr2/kparzysz/s.hex/t/hwloop-dbg.c] [DW_LANG_C99] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"foo", metadata !"foo", metadata !"", metadata !6, i32 1, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (i32*, i32*)* @foo, null, null, metadata !11, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo] +!6 = metadata !{i32 786473, metadata !"hwloop-dbg.c", metadata !"/usr2/kparzysz/s.hex/t", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!8 = metadata !{null, metadata !9, metadata !9} +!9 = metadata !{i32 786447, null, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 32, align 32, offset 0] [from int] +!10 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!11 = metadata !{metadata !12} +!12 = metadata !{metadata !13, metadata !14, metadata !15} +!13 = metadata !{i32 786689, metadata !5, metadata !"a", metadata !6, i32 16777217, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [a] [line 1] +!14 = metadata !{i32 786689, metadata !5, metadata !"b", metadata !6, i32 33554433, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [b] [line 1] +!15 = metadata !{i32 786688, metadata !16, metadata !"i", metadata !6, i32 2, metadata !10, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [i] [line 2] +!16 = metadata !{i32 786443, metadata !5, i32 1, i32 26, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] [/usr2/kparzysz/s.hex/t/hwloop-dbg.c] +!17 = metadata !{i32 1, i32 15, metadata !5, null} +!18 = metadata !{i32 1, i32 23, metadata !5, null} +!19 = metadata !{i32 3, i32 8, metadata !20, null} +!20 = metadata !{i32 786443, metadata !16, i32 3, i32 3, metadata !6, i32 1} ; [ DW_TAG_lexical_block ] [/usr2/kparzysz/s.hex/t/hwloop-dbg.c] +!21 = metadata !{i32 4, i32 5, metadata !22, null} +!22 = metadata !{i32 786443, metadata !20, i32 3, i32 28, metadata !6, i32 2} ; [ DW_TAG_lexical_block ] [/usr2/kparzysz/s.hex/t/hwloop-dbg.c] +!23 = metadata !{metadata !"int", metadata !24} +!24 = metadata !{metadata !"omnipotent char", metadata !25} +!25 = metadata !{metadata !"Simple C/C++ TBAA"} +!26 = metadata !{i32 3, i32 23, metadata !20, null} +!27 = metadata !{i32 6, i32 1, metadata !16, null} diff --git a/test/CodeGen/Hexagon/hwloop-le.ll b/test/CodeGen/Hexagon/hwloop-le.ll new file mode 100644 index 0000000000..9c8cec7c2a --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-le.ll @@ -0,0 +1,438 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 -O3 < %s | FileCheck %s + + +; CHECK: test_pos1_ir_sle +; CHECK: loop0 +; a < b +define void @test_pos1_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 28395, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 28395, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ir_sle +; CHECK: loop0 +; a < b +define void @test_pos2_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 9073, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 9073, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ir_sle +; CHECK: loop0 +; a < b +define void @test_pos4_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 21956, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 21956, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ir_sle +; CHECK: loop0 +; a < b +define void @test_pos8_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 16782, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 16782, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ir_sle +; CHECK: loop0 +; a < b +define void @test_pos16_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 19097, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 19097, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_ri_sle +; CHECK: loop0 +; a < b +define void @test_pos1_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, 14040 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp sle i32 %inc, 14040 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ri_sle +; CHECK: loop0 +; a < b +define void @test_pos2_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, 13710 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp sle i32 %inc, 13710 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ri_sle +; CHECK: loop0 +; a < b +define void @test_pos4_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, 9920 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp sle i32 %inc, 9920 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ri_sle +; CHECK: loop0 +; a < b +define void @test_pos8_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, 18924 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp sle i32 %inc, 18924 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ri_sle +; CHECK: loop0 +; a < b +define void @test_pos16_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, 11812 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp sle i32 %inc, 11812 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_rr_sle +; CHECK: loop0 +; a < b +define void @test_pos1_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_rr_sle +; CHECK: loop0 +; a < b +define void @test_pos2_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_rr_sle +; CHECK: loop0 +; a < b +define void @test_pos4_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_rr_sle +; CHECK: loop0 +; a < b +define void @test_pos8_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_rr_sle +; CHECK: loop0 +; a < b +define void @test_pos16_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp sle i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp sle i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + diff --git a/test/CodeGen/Hexagon/hwloop-lt.ll b/test/CodeGen/Hexagon/hwloop-lt.ll new file mode 100644 index 0000000000..7e43733da2 --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-lt.ll @@ -0,0 +1,438 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 -O3 < %s | FileCheck %s + + +; CHECK: test_pos1_ir_slt +; CHECK: loop0 +; a < b +define void @test_pos1_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 8531, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 8531, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ir_slt +; CHECK: loop0 +; a < b +define void @test_pos2_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 9152, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 9152, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ir_slt +; CHECK: loop0 +; a < b +define void @test_pos4_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 18851, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 18851, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ir_slt +; CHECK: loop0 +; a < b +define void @test_pos8_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 25466, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 25466, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ir_slt +; CHECK: loop0 +; a < b +define void @test_pos16_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 9295, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 9295, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_ri_slt +; CHECK: loop0 +; a < b +define void @test_pos1_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 31236 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp slt i32 %inc, 31236 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ri_slt +; CHECK: loop0 +; a < b +define void @test_pos2_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 22653 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp slt i32 %inc, 22653 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ri_slt +; CHECK: loop0 +; a < b +define void @test_pos4_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 1431 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp slt i32 %inc, 1431 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ri_slt +; CHECK: loop0 +; a < b +define void @test_pos8_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 22403 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp slt i32 %inc, 22403 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ri_slt +; CHECK: loop0 +; a < b +define void @test_pos16_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 21715 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp slt i32 %inc, 21715 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_rr_slt +; CHECK: loop0 +; a < b +define void @test_pos1_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_rr_slt +; CHECK: loop0 +; a < b +define void @test_pos2_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_rr_slt +; CHECK: loop0 +; a < b +define void @test_pos4_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_rr_slt +; CHECK: loop0 +; a < b +define void @test_pos8_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_rr_slt +; CHECK: loop0 +; a < b +define void @test_pos16_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp slt i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + diff --git a/test/CodeGen/Hexagon/hwloop-lt1.ll b/test/CodeGen/Hexagon/hwloop-lt1.ll new file mode 100644 index 0000000000..cf5874011e --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-lt1.ll @@ -0,0 +1,32 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate a hardware loop instruction. +; CHECK: endloop0 + +@A = common global [400 x i8] zeroinitializer, align 8 +@B = common global [400 x i8] zeroinitializer, align 8 +@C = common global [400 x i8] zeroinitializer, align 8 + +define void @run() nounwind { +entry: + br label %polly.loop_body + +polly.loop_after: ; preds = %polly.loop_body + ret void + +polly.loop_body: ; preds = %entry, %polly.loop_body + %polly.loopiv16 = phi i32 [ 0, %entry ], [ %polly.next_loopiv, %polly.loop_body ] + %polly.next_loopiv = add i32 %polly.loopiv16, 4 + %p_vector_iv14 = or i32 %polly.loopiv16, 1 + %p_vector_iv3 = add i32 %p_vector_iv14, 1 + %p_vector_iv415 = or i32 %polly.loopiv16, 3 + %p_arrayidx = getelementptr [400 x i8]* @A, i32 0, i32 %polly.loopiv16 + %p_arrayidx5 = getelementptr [400 x i8]* @A, i32 0, i32 %p_vector_iv14 + %p_arrayidx6 = getelementptr [400 x i8]* @A, i32 0, i32 %p_vector_iv3 + %p_arrayidx7 = getelementptr [400 x i8]* @A, i32 0, i32 %p_vector_iv415 + store i8 123, i8* %p_arrayidx, align 1 + store i8 123, i8* %p_arrayidx5, align 1 + store i8 123, i8* %p_arrayidx6, align 1 + store i8 123, i8* %p_arrayidx7, align 1 + %0 = icmp slt i32 %polly.next_loopiv, 400 + br i1 %0, label %polly.loop_body, label %polly.loop_after +} diff --git a/test/CodeGen/Hexagon/hwloop-ne.ll b/test/CodeGen/Hexagon/hwloop-ne.ll new file mode 100644 index 0000000000..bceef2a169 --- /dev/null +++ b/test/CodeGen/Hexagon/hwloop-ne.ll @@ -0,0 +1,438 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 -O3 < %s | FileCheck %s + + +; CHECK: test_pos1_ir_ne +; CHECK: loop0 +; a < b +define void @test_pos1_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 32623, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 32623, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ir_ne +; CHECK: loop0 +; a < b +define void @test_pos2_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 29554, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 29554, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ir_ne +; CHECK: loop0 +; a < b +define void @test_pos4_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 15692, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 15692, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ir_ne +; CHECK: loop0 +; a < b +define void @test_pos8_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 10449, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 10449, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ir_ne +; CHECK: loop0 +; a < b +define void @test_pos16_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 32087, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ 32087, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_ri_ne +; CHECK: loop0 +; a < b +define void @test_pos1_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 3472 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp ne i32 %inc, 3472 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_ri_ne +; CHECK: loop0 +; a < b +define void @test_pos2_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 8730 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp ne i32 %inc, 8730 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_ri_ne +; CHECK: loop0 +; a < b +define void @test_pos4_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 1493 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp ne i32 %inc, 1493 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_ri_ne +; CHECK: loop0 +; a < b +define void @test_pos8_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 1706 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp ne i32 %inc, 1706 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_ri_ne +; CHECK: loop0 +; a < b +define void @test_pos16_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, 1886 + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp ne i32 %inc, 1886 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos1_rr_ne +; CHECK: loop0 +; a < b +define void @test_pos1_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 1 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos2_rr_ne +; CHECK: loop0 +; a < b +define void @test_pos2_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 2 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos4_rr_ne +; CHECK: loop0 +; a < b +define void @test_pos4_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 4 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos8_rr_ne +; CHECK: loop0 +; a < b +define void @test_pos8_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 8 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + +; CHECK: test_pos16_rr_ne +; CHECK: loop0 +; a < b +define void @test_pos16_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind { +entry: + %cmp3 = icmp slt i32 %a, %b + br i1 %cmp3, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i8* %p, i32 %i.04 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 1 + %conv1 = trunc i32 %add to i8 + store i8 %conv1, i8* %arrayidx, align 1 + %inc = add nsw i32 %i.04, 16 + %cmp = icmp ne i32 %inc, %b + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body, %entry + ret void +} + + + diff --git a/test/CodeGen/Hexagon/i16_VarArg.ll b/test/CodeGen/Hexagon/i16_VarArg.ll new file mode 100644 index 0000000000..eb44c2905c --- /dev/null +++ b/test/CodeGen/Hexagon/i16_VarArg.ll @@ -0,0 +1,40 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; CHECK: call __hexagon_{{[A-Z_a-z0-9]+}} + +@a_str = internal constant [8 x i8] c"a = %f\0A\00" +@b_str = internal constant [8 x i8] c"b = %f\0A\00" +@add_str = internal constant [12 x i8] c"a + b = %f\0A\00" +@sub_str = internal constant [12 x i8] c"a - b = %f\0A\00" +@mul_str = internal constant [12 x i8] c"a * b = %f\0A\00" +@div_str = internal constant [12 x i8] c"b / a = %f\0A\00" +@rem_str = internal constant [13 x i8] c"b %% a = %f\0A\00" +@lt_str = internal constant [12 x i8] c"a < b = %d\0A\00" +@le_str = internal constant [13 x i8] c"a <= b = %d\0A\00" +@gt_str = internal constant [12 x i8] c"a > b = %d\0A\00" +@ge_str = internal constant [13 x i8] c"a >= b = %d\0A\00" +@eq_str = internal constant [13 x i8] c"a == b = %d\0A\00" +@ne_str = internal constant [13 x i8] c"a != b = %d\0A\00" +@A = global double 2.000000e+00 +@B = global double 5.000000e+00 + +declare i32 @printf(i8*, ...) + +define i32 @main() { + %a = load double* @A + %b = load double* @B + %lt_r = fcmp olt double %a, %b + %le_r = fcmp ole double %a, %b + %gt_r = fcmp ogt double %a, %b + %ge_r = fcmp oge double %a, %b + %eq_r = fcmp oeq double %a, %b + %ne_r = fcmp une double %a, %b + %val1 = zext i1 %lt_r to i16 + %lt_s = getelementptr [12 x i8]* @lt_str, i64 0, i64 0 + %le_s = getelementptr [13 x i8]* @le_str, i64 0, i64 0 + %gt_s = getelementptr [12 x i8]* @gt_str, i64 0, i64 0 + %ge_s = getelementptr [13 x i8]* @ge_str, i64 0, i64 0 + %eq_s = getelementptr [13 x i8]* @eq_str, i64 0, i64 0 + %ne_s = getelementptr [13 x i8]* @ne_str, i64 0, i64 0 + call i32 (i8*, ...)* @printf( i8* %lt_s, i16 %val1 ) + ret i32 0 +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/i1_VarArg.ll b/test/CodeGen/Hexagon/i1_VarArg.ll new file mode 100644 index 0000000000..7dbfb25cd2 --- /dev/null +++ b/test/CodeGen/Hexagon/i1_VarArg.ll @@ -0,0 +1,44 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; CHECK: call __hexagon_{{[_A-Za-z0-9]+}} + +@a_str = internal constant [8 x i8] c"a = %f\0A\00" +@b_str = internal constant [8 x i8] c"b = %f\0A\00" +@add_str = internal constant [12 x i8] c"a + b = %f\0A\00" +@sub_str = internal constant [12 x i8] c"a - b = %f\0A\00" +@mul_str = internal constant [12 x i8] c"a * b = %f\0A\00" +@div_str = internal constant [12 x i8] c"b / a = %f\0A\00" +@rem_str = internal constant [13 x i8] c"b %% a = %f\0A\00" +@lt_str = internal constant [12 x i8] c"a < b = %d\0A\00" +@le_str = internal constant [13 x i8] c"a <= b = %d\0A\00" +@gt_str = internal constant [12 x i8] c"a > b = %d\0A\00" +@ge_str = internal constant [13 x i8] c"a >= b = %d\0A\00" +@eq_str = internal constant [13 x i8] c"a == b = %d\0A\00" +@ne_str = internal constant [13 x i8] c"a != b = %d\0A\00" +@A = global double 2.000000e+00 +@B = global double 5.000000e+00 + +declare i32 @printf(i8*, ...) + +define i32 @main() { + %a = load double* @A + %b = load double* @B + %lt_r = fcmp olt double %a, %b + %le_r = fcmp ole double %a, %b + %gt_r = fcmp ogt double %a, %b + %ge_r = fcmp oge double %a, %b + %eq_r = fcmp oeq double %a, %b + %ne_r = fcmp une double %a, %b + %lt_s = getelementptr [12 x i8]* @lt_str, i64 0, i64 0 + %le_s = getelementptr [13 x i8]* @le_str, i64 0, i64 0 + %gt_s = getelementptr [12 x i8]* @gt_str, i64 0, i64 0 + %ge_s = getelementptr [13 x i8]* @ge_str, i64 0, i64 0 + %eq_s = getelementptr [13 x i8]* @eq_str, i64 0, i64 0 + %ne_s = getelementptr [13 x i8]* @ne_str, i64 0, i64 0 + call i32 (i8*, ...)* @printf( i8* %lt_s, i1 %lt_r ) + call i32 (i8*, ...)* @printf( i8* %le_s, i1 %le_r ) + call i32 (i8*, ...)* @printf( i8* %gt_s, i1 %gt_r ) + call i32 (i8*, ...)* @printf( i8* %ge_s, i1 %ge_r ) + call i32 (i8*, ...)* @printf( i8* %eq_s, i1 %eq_r ) + call i32 (i8*, ...)* @printf( i8* %ne_s, i1 %ne_r ) + ret i32 0 +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/i8_VarArg.ll b/test/CodeGen/Hexagon/i8_VarArg.ll new file mode 100644 index 0000000000..687b178824 --- /dev/null +++ b/test/CodeGen/Hexagon/i8_VarArg.ll @@ -0,0 +1,40 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; CHECK: call __hexagon_{{[A-Z_a-z0-9]+}} + +@a_str = internal constant [8 x i8] c"a = %f\0A\00" +@b_str = internal constant [8 x i8] c"b = %f\0A\00" +@add_str = internal constant [12 x i8] c"a + b = %f\0A\00" +@sub_str = internal constant [12 x i8] c"a - b = %f\0A\00" +@mul_str = internal constant [12 x i8] c"a * b = %f\0A\00" +@div_str = internal constant [12 x i8] c"b / a = %f\0A\00" +@rem_str = internal constant [13 x i8] c"b %% a = %f\0A\00" +@lt_str = internal constant [12 x i8] c"a < b = %d\0A\00" +@le_str = internal constant [13 x i8] c"a <= b = %d\0A\00" +@gt_str = internal constant [12 x i8] c"a > b = %d\0A\00" +@ge_str = internal constant [13 x i8] c"a >= b = %d\0A\00" +@eq_str = internal constant [13 x i8] c"a == b = %d\0A\00" +@ne_str = internal constant [13 x i8] c"a != b = %d\0A\00" +@A = global double 2.000000e+00 +@B = global double 5.000000e+00 + +declare i32 @printf(i8*, ...) + +define i32 @main() { + %a = load double* @A + %b = load double* @B + %lt_r = fcmp olt double %a, %b + %le_r = fcmp ole double %a, %b + %gt_r = fcmp ogt double %a, %b + %ge_r = fcmp oge double %a, %b + %eq_r = fcmp oeq double %a, %b + %ne_r = fcmp une double %a, %b + %val1 = zext i1 %lt_r to i8 + %lt_s = getelementptr [12 x i8]* @lt_str, i64 0, i64 0 + %le_s = getelementptr [13 x i8]* @le_str, i64 0, i64 0 + %gt_s = getelementptr [12 x i8]* @gt_str, i64 0, i64 0 + %ge_s = getelementptr [13 x i8]* @ge_str, i64 0, i64 0 + %eq_s = getelementptr [13 x i8]* @eq_str, i64 0, i64 0 + %ne_s = getelementptr [13 x i8]* @ne_str, i64 0, i64 0 + call i32 (i8*, ...)* @printf( i8* %lt_s, i8 %val1 ) + ret i32 0 +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/idxload-with-zero-offset.ll b/test/CodeGen/Hexagon/idxload-with-zero-offset.ll new file mode 100644 index 0000000000..ca6df88a55 --- /dev/null +++ b/test/CodeGen/Hexagon/idxload-with-zero-offset.ll @@ -0,0 +1,70 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate load instruction with (base + register offset << 0) + +; load word + +define i32 @load_w(i32* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i32* %a, i32 %tmp + %val = load i32* %scevgep9, align 4 + ret i32 %val +} + +; load unsigned half word + +define i16 @load_uh(i16* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memuh(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i16* %a, i32 %tmp + %val = load i16* %scevgep9, align 2 + ret i16 %val +} + +; load signed half word + +define i32 @load_h(i16* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memh(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i16* %a, i32 %tmp + %val = load i16* %scevgep9, align 2 + %conv = sext i16 %val to i32 + ret i32 %conv +} + +; load unsigned byte + +define i8 @load_ub(i8* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i8* %a, i32 %tmp + %val = load i8* %scevgep9, align 1 + ret i8 %val +} + +; load signed byte + +define i32 @foo_2(i8* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memb(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i8* %a, i32 %tmp + %val = load i8* %scevgep9, align 1 + %conv = sext i8 %val to i32 + ret i32 %conv +} + +; load doubleword + +define i64 @load_d(i64* nocapture %a, i32 %n) nounwind { +; CHECK: r{{[0-9]+}}:{{[0-9]+}}{{ *}}={{ *}}memd(r{{[0-9]+}}+r{{[0-9]+}}<<#0) +entry: + %tmp = shl i32 %n, 4 + %scevgep9 = getelementptr i64* %a, i32 %tmp + %val = load i64* %scevgep9, align 8 + ret i64 %val +} diff --git a/test/CodeGen/Hexagon/indirect-br.ll b/test/CodeGen/Hexagon/indirect-br.ll new file mode 100644 index 0000000000..919e501891 --- /dev/null +++ b/test/CodeGen/Hexagon/indirect-br.ll @@ -0,0 +1,14 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +;CHECK: jumpr r{{[0-9]+}} + +define i32 @check_indirect_br(i8* %target) nounwind { +entry: + indirectbr i8* %target, [label %test_label] + +test_label: + br label %ret + +ret: + ret i32 -1 +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/postinc-store.ll b/test/CodeGen/Hexagon/postinc-store.ll new file mode 100644 index 0000000000..99a3a58ad3 --- /dev/null +++ b/test/CodeGen/Hexagon/postinc-store.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s + +; Check that post-increment store instructions are being generated. +; CHECK: memw(r{{[0-9]+}}{{ *}}++{{ *}}#4{{ *}}){{ *}}={{ *}}r{{[0-9]+}} + +define i32 @sum(i32* nocapture %a, i16* nocapture %b, i32 %n) nounwind { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ 10, %entry ] + %arrayidx.phi = phi i32* [ %a, %entry ], [ %arrayidx.inc, %for.body ] + %arrayidx1.phi = phi i16* [ %b, %entry ], [ %arrayidx1.inc, %for.body ] + %0 = load i32* %arrayidx.phi, align 4 + %1 = load i16* %arrayidx1.phi, align 2 + %conv = sext i16 %1 to i32 + %factor = mul i32 %0, 2 + %add3 = add i32 %factor, %conv + store i32 %add3, i32* %arrayidx.phi, align 4 + + %arrayidx.inc = getelementptr i32* %arrayidx.phi, i32 1 + %arrayidx1.inc = getelementptr i16* %arrayidx1.phi, i32 1 + %lsr.iv.next = add i32 %lsr.iv, -1 + %exitcond = icmp eq i32 %lsr.iv.next, 0 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret i32 0 +} diff --git a/test/CodeGen/Hexagon/pred-absolute-store.ll b/test/CodeGen/Hexagon/pred-absolute-store.ll new file mode 100644 index 0000000000..b1b09f414a --- /dev/null +++ b/test/CodeGen/Hexagon/pred-absolute-store.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we are able to predicate instructions with abosolute +; addressing mode. + +; CHECK: if{{ *}}(p{{[0-3]+}}){{ *}}memw(##gvar){{ *}}={{ *}}r{{[0-9]+}} + +@gvar = external global i32 +define i32 @test2(i32 %a, i32 %b) nounwind { +entry: + %cmp = icmp eq i32 %a, %b + br i1 %cmp, label %if.then, label %if.end + +if.then: + store i32 %a, i32* @gvar, align 4 + br label %if.end + +if.end: + ret i32 %b +} diff --git a/test/CodeGen/Hexagon/predicate-copy.ll b/test/CodeGen/Hexagon/predicate-copy.ll new file mode 100644 index 0000000000..552b687941 --- /dev/null +++ b/test/CodeGen/Hexagon/predicate-copy.ll @@ -0,0 +1,8 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 -O3 < %s | FileCheck %s + +; CHECK: r{{[0-9]+}} = p{{[0-9]+}} +define i1 @foo() { +entry: + ret i1 false +} + diff --git a/test/CodeGen/Hexagon/struct_args.ll b/test/CodeGen/Hexagon/struct_args.ll index e488f33c3d..f91300b506 100644 --- a/test/CodeGen/Hexagon/struct_args.ll +++ b/test/CodeGen/Hexagon/struct_args.ll @@ -1,5 +1,5 @@ ; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s -; CHECK: r{{[0-9]}}:{{[0-9]}} = combine(r{{[0-9]}}, r{{[0-9]}}) +; CHECK: r{{[0-9]}}:{{[0-9]}} = combine({{r[0-9]|#0}}, r{{[0-9]}}) ; CHECK: r{{[0-9]}}:{{[0-9]}} |= asl(r{{[0-9]}}:{{[0-9]}}, #32) %struct.small = type { i32, i32 } diff --git a/test/CodeGen/Hexagon/sube.ll b/test/CodeGen/Hexagon/sube.ll new file mode 100644 index 0000000000..84172e957d --- /dev/null +++ b/test/CodeGen/Hexagon/sube.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK: r{{[0-9]+:[0-9]+}} = #0 +; CHECK: r{{[0-9]+:[0-9]+}} = #1 +; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}}) +; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}}) + +define void @check_sube_subc(i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) { +entry: + %tmp1 = zext i64 %AL to i128 + %tmp23 = zext i64 %AH to i128 + %tmp4 = shl i128 %tmp23, 64 + %tmp5 = or i128 %tmp4, %tmp1 + %tmp67 = zext i64 %BL to i128 + %tmp89 = zext i64 %BH to i128 + %tmp11 = shl i128 %tmp89, 64 + %tmp12 = or i128 %tmp11, %tmp67 + %tmp15 = sub i128 %tmp5, %tmp12 + %tmp1617 = trunc i128 %tmp15 to i64 + store i64 %tmp1617, i64* %RL + %tmp21 = lshr i128 %tmp15, 64 + %tmp2122 = trunc i128 %tmp21 to i64 + store i64 %tmp2122, i64* %RH + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/Hexagon/validate-offset.ll b/test/CodeGen/Hexagon/validate-offset.ll new file mode 100644 index 0000000000..9e7d0aa078 --- /dev/null +++ b/test/CodeGen/Hexagon/validate-offset.ll @@ -0,0 +1,36 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s -O0 + +; This is a regression test which makes sure that the offset check +; is available for STRiw_indexed instruction. This is required +; by 'Hexagon Expand Predicate Spill Code' pass. + +define i32 @f(i32 %a, i32 %b) nounwind { +entry: + %retval = alloca i32, align 4 + %a.addr = alloca i32, align 4 + %b.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + store i32 %b, i32* %b.addr, align 4 + %0 = load i32* %a.addr, align 4 + %1 = load i32* %b.addr, align 4 + %cmp = icmp sgt i32 %0, %1 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %2 = load i32* %a.addr, align 4 + %3 = load i32* %b.addr, align 4 + %add = add nsw i32 %2, %3 + store i32 %add, i32* %retval + br label %return + +if.else: + %4 = load i32* %a.addr, align 4 + %5 = load i32* %b.addr, align 4 + %sub = sub nsw i32 %4, %5 + store i32 %sub, i32* %retval + br label %return + +return: + %6 = load i32* %retval + ret i32 %6 +} diff --git a/test/CodeGen/Hexagon/zextloadi1.ll b/test/CodeGen/Hexagon/zextloadi1.ll new file mode 100644 index 0000000000..cb6e6fdf84 --- /dev/null +++ b/test/CodeGen/Hexagon/zextloadi1.ll @@ -0,0 +1,25 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s + +; CHECK: r{{[0-9]+}} = ##i129_l+16 +; CHECK: r{{[0-9]+}} = ##i129_s+16 +; CHECK: memd(##i129_s) = r{{[0-9]+:[0-9]+}} +; CHECK: r{{[0-9]+}} = ##i65_l+8 +; CHECK: r{{[0-9]+}} = ##i65_s+8 +; CHECK: memd(##i65_s) = r{{[0-9]+:[0-9]+}} + +@i65_l = external global i65 +@i65_s = external global i65 +@i129_l = external global i129 +@i129_s = external global i129 + +define void @i129_ls() nounwind { + %tmp = load i129* @i129_l + store i129 %tmp, i129* @i129_s + ret void +} + +define void @i65_ls() nounwind { + %tmp = load i65* @i65_l + store i65 %tmp, i65* @i65_s + ret void +}
\ No newline at end of file diff --git a/test/CodeGen/ARM/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/Inputs/DbgValueOtherTargets.ll index 6422689920..3f244f6891 100644 --- a/test/CodeGen/ARM/2010-04-07-DbgValueOtherTargets.ll +++ b/test/CodeGen/Inputs/DbgValueOtherTargets.ll @@ -1,4 +1,3 @@ -; RUN: llc -O0 -march=arm -asm-verbose < %s | FileCheck %s ; Check that DEBUG_VALUE comments come through on a variety of targets. define i32 @main() nounwind ssp { @@ -12,17 +11,17 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0} +!llvm.dbg.cu = !{!2} +!11 = metadata !{metadata !0} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !11, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!5 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] !6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 786688, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!8 = metadata !{i32 786443, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !9 = metadata !{i32 3, i32 11, metadata !8, null} !10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/MBlaze/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/MBlaze/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index d8970eac90..0000000000 --- a/test/CodeGen/MBlaze/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=mblaze -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/MBlaze/DbgValueOtherTargets.test b/test/CodeGen/MBlaze/DbgValueOtherTargets.test new file mode 100644 index 0000000000..4032d7b81c --- /dev/null +++ b/test/CodeGen/MBlaze/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=mblaze -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/MSP430/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/MSP430/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 9d549da8a9..0000000000 --- a/test/CodeGen/MSP430/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=msp430 -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/MSP430/DbgValueOtherTargets.test b/test/CodeGen/MSP430/DbgValueOtherTargets.test new file mode 100644 index 0000000000..f8c747ec92 --- /dev/null +++ b/test/CodeGen/MSP430/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=msp430 -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/Mips/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/Mips/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 994e19af4f..0000000000 --- a/test/CodeGen/Mips/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=mips -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/Mips/2010-07-20-Switch.ll b/test/CodeGen/Mips/2010-07-20-Switch.ll index 261fe9db17..38d7b7e255 100644 --- a/test/CodeGen/Mips/2010-07-20-Switch.ll +++ b/test/CodeGen/Mips/2010-07-20-Switch.ll @@ -1,6 +1,11 @@ -; RUN: llc < %s -march=mips -relocation-model=static | FileCheck %s -check-prefix=STATIC-O32 -; RUN: llc < %s -march=mips -relocation-model=pic | FileCheck %s -check-prefix=PIC-O32 -; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips64 -mattr=n64 | FileCheck %s -check-prefix=PIC-N64 +; RUN: llc < %s -march=mips -relocation-model=static | \ +; RUN: FileCheck %s -check-prefix=STATIC-O32 +; RUN: llc < %s -march=mips -relocation-model=pic | \ +; RUN: FileCheck %s -check-prefix=PIC-O32 +; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips64 | \ +; RUN: FileCheck %s -check-prefix=N64 +; RUN: llc < %s -march=mips64 -relocation-model=static -mcpu=mips64 | \ +; RUN: FileCheck %s -check-prefix=N64 define i32 @main() nounwind readnone { entry: @@ -17,12 +22,12 @@ entry: ; PIC-O32: lw $[[R4:[0-9]+]], %lo($JTI0_0)($[[R2]]) ; PIC-O32: addu $[[R5:[0-9]+]], $[[R4:[0-9]+]] ; PIC-O32: jr $[[R5]] -; PIC-N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 3 -; PIC-N64: ld $[[R1:[0-9]+]], %got_page($JTI0_0) -; PIC-N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]] -; PIC-N64: ld $[[R4:[0-9]+]], %got_ofst($JTI0_0)($[[R2]]) -; PIC-N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]] -; PIC-N64: jr $[[R5]] +; N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 3 +; N64: ld $[[R1:[0-9]+]], %got_page($JTI0_0) +; N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]] +; N64: ld $[[R4:[0-9]+]], %got_ofst($JTI0_0)($[[R2]]) +; N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]] +; N64: jr $[[R5]] switch i32 %0, label %bb4 [ i32 0, label %bb5 i32 1, label %bb1 @@ -58,10 +63,10 @@ bb5: ; preds = %entry ; PIC-O32: .gpword ; PIC-O32: .gpword ; PIC-O32: .gpword -; PIC-N64: .align 3 -; PIC-N64: $JTI0_0: -; PIC-N64: .gpdword -; PIC-N64: .gpdword -; PIC-N64: .gpdword -; PIC-N64: .gpdword +; N64: .align 3 +; N64: $JTI0_0: +; N64: .gpdword +; N64: .gpdword +; N64: .gpdword +; N64: .gpdword diff --git a/test/CodeGen/Mips/2012-12-12-ExpandMemcpy.ll b/test/CodeGen/Mips/2012-12-12-ExpandMemcpy.ll new file mode 100644 index 0000000000..9d4daee696 --- /dev/null +++ b/test/CodeGen/Mips/2012-12-12-ExpandMemcpy.ll @@ -0,0 +1,11 @@ +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s + +@.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 + +define void @t(i8* %ptr) { +entry: + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %ptr, i8* getelementptr inbounds ([7 x i8]* @.str, i64 0, i64 0), i64 7, i32 1, i1 false) + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind diff --git a/test/CodeGen/Mips/DbgValueOtherTargets.test b/test/CodeGen/Mips/DbgValueOtherTargets.test new file mode 100644 index 0000000000..9c351ace68 --- /dev/null +++ b/test/CodeGen/Mips/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=mips -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/Mips/addi.ll b/test/CodeGen/Mips/addi.ll new file mode 100644 index 0000000000..8f70a469c4 --- /dev/null +++ b/test/CodeGen/Mips/addi.ll @@ -0,0 +1,30 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -mips16-hard-float -soft-float -relocation-model=static < %s | FileCheck %s -check-prefix=16 + +@i = global i32 6, align 4 +@j = global i32 12, align 4 +@k = global i32 15, align 4 +@l = global i32 20, align 4 +@.str = private unnamed_addr constant [13 x i8] c"%i %i %i %i\0A\00", align 1 + +define void @foo() nounwind { +entry: + %0 = load i32* @i, align 4 + %add = add nsw i32 %0, 5 + store i32 %add, i32* @i, align 4 + %1 = load i32* @j, align 4 + %sub = sub nsw i32 %1, 5 + store i32 %sub, i32* @j, align 4 + %2 = load i32* @k, align 4 + %add1 = add nsw i32 %2, 10000 + store i32 %add1, i32* @k, align 4 + %3 = load i32* @l, align 4 + %sub2 = sub nsw i32 %3, 10000 + store i32 %sub2, i32* @l, align 4 +; 16: addiu ${{[0-9]+}}, 5 # 16 bit inst +; 16: addiu ${{[0-9]+}}, -5 # 16 bit inst +; 16: addiu ${{[0-9]+}}, 10000 +; 16: addiu ${{[0-9]+}}, -10000 + ret void +} + + diff --git a/test/CodeGen/Mips/align16.ll b/test/CodeGen/Mips/align16.ll new file mode 100644 index 0000000000..99139abbe8 --- /dev/null +++ b/test/CodeGen/Mips/align16.ll @@ -0,0 +1,31 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=16 + +@i = global i32 25, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @p(i32* %i) nounwind { +entry: + ret void +} + + +define void @foo() nounwind { +entry: + %y = alloca [512 x i32], align 4 + %x = alloca i32, align 8 + %zz = alloca i32, align 4 + %z = alloca i32, align 4 + %0 = load i32* @i, align 4 + %arrayidx = getelementptr inbounds [512 x i32]* %y, i32 0, i32 10 + store i32 %0, i32* %arrayidx, align 4 + %1 = load i32* @i, align 4 + store i32 %1, i32* %x, align 8 + call void @p(i32* %x) + %arrayidx1 = getelementptr inbounds [512 x i32]* %y, i32 0, i32 10 + call void @p(i32* %arrayidx1) + ret void +} +; 16: save $ra, $s0, $s1, 2040 +; 16: addiu $sp, -48 # 16 bit inst +; 16: addiu $sp, 48 # 16 bit inst +; 16: restore $ra, $s0, $s1, 2040
\ No newline at end of file diff --git a/test/CodeGen/Mips/alloca.ll b/test/CodeGen/Mips/alloca.ll index 29f43c8afa..d79ea9193d 100644 --- a/test/CodeGen/Mips/alloca.ll +++ b/test/CodeGen/Mips/alloca.ll @@ -3,11 +3,11 @@ define i32 @twoalloca(i32 %size) nounwind { entry: ; CHECK: subu $[[T0:[0-9]+]], $sp, $[[SZ:[0-9]+]] -; CHECK: addu $sp, $zero, $[[T0]] +; CHECK: move $sp, $[[T0]] ; CHECK: subu $[[T2:[0-9]+]], $sp, $[[SZ]] -; CHECK: addu $sp, $zero, $[[T2]] -; CHECK: addu $4, $zero, $[[T0]] -; CHECK: addu $4, $zero, $[[T2]] +; CHECK: move $sp, $[[T2]] +; CHECK: move $4, $[[T0]] +; CHECK: move $4, $[[T2]] %tmp1 = alloca i8, i32 %size, align 4 %add.ptr = getelementptr inbounds i8* %tmp1, i32 5 store i8 97, i8* %add.ptr, align 1 @@ -29,7 +29,7 @@ define i32 @alloca2(i32 %size) nounwind { entry: ; CHECK: alloca2 ; CHECK: subu $[[T0:[0-9]+]], $sp -; CHECK: addu $sp, $zero, $[[T0]] +; CHECK: move $sp, $[[T0]] %tmp1 = alloca i8, i32 %size, align 4 %0 = bitcast i8* %tmp1 to i32* diff --git a/test/CodeGen/Mips/alloca16.ll b/test/CodeGen/Mips/alloca16.ll index 731edae43c..5ae9a84791 100644 --- a/test/CodeGen/Mips/alloca16.ll +++ b/test/CodeGen/Mips/alloca16.ll @@ -68,8 +68,8 @@ entry: %21 = load i32** %ip, align 4 %arrayidx6 = getelementptr inbounds i32* %21, i32 %20 %22 = load i32* %arrayidx6, align 4 -; 16: save 16 +; 16: addiu $sp, -16 call void @temp(i32 %22) -; 16: restore 16 +; 16: addiu $sp, 16 ret void } diff --git a/test/CodeGen/Mips/br-jmp.ll b/test/CodeGen/Mips/br-jmp.ll index 1b5513ab39..9ca8d15961 100644 --- a/test/CodeGen/Mips/br-jmp.ll +++ b/test/CodeGen/Mips/br-jmp.ll @@ -1,5 +1,7 @@ ; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s -check-prefix=CHECK-PIC ; RUN: llc -march=mipsel -relocation-model=static < %s | FileCheck %s -check-prefix=CHECK-STATIC +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=CHECK-PIC16 +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=CHECK-STATIC16 define void @count(i32 %x, i32 %y, i32 %z) noreturn nounwind readnone { entry: @@ -11,3 +13,6 @@ bosco: ; preds = %bosco, %entry ; CHECK-PIC: b $BB0_1 ; CHECK-STATIC: j $BB0_1 +; CHECK-PIC16: b $BB0_1 +; CHECK-STATIC16: b $BB0_1 + diff --git a/test/CodeGen/Mips/brdelayslot.ll b/test/CodeGen/Mips/brdelayslot.ll index 897fc9768f..2deb037c9c 100644 --- a/test/CodeGen/Mips/brdelayslot.ll +++ b/test/CodeGen/Mips/brdelayslot.ll @@ -1,5 +1,12 @@ ; RUN: llc -march=mipsel -O0 < %s | FileCheck %s -check-prefix=None ; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=Default +; RUN: llc -march=mipsel -O1 -relocation-model=static < %s | \ +; RUN: FileCheck %s -check-prefix=STATICO1 +; RUN: llc -march=mipsel -disable-mips-df-forward-search=false \ +; RUN: -relocation-model=static < %s | FileCheck %s -check-prefix=FORWARD +; RUN: llc -march=mipsel -disable-mips-df-backward-search \ +; RUN: -disable-mips-df-succbb-search=false < %s | \ +; RUN: FileCheck %s -check-prefix=SUCCBB define void @foo1() nounwind { entry: @@ -67,3 +74,105 @@ if.end: ret void } +; Check that delay slot filler can place mov.s or mov.d in delay slot. +; +; Default: foo6: +; Default-NOT: nop +; Default: .end foo6 + +define void @foo6(float %a0, double %a1) nounwind { +entry: + tail call void @foo7(double %a1, float %a0) nounwind + ret void +} + +declare void @foo7(double, float) + +; Check that a store can move past other memory instructions. +; +; STATICO1: foo8: +; STATICO1: jalr ${{[0-9]+}} +; STATICO1-NEXT: sw ${{[0-9]+}}, %lo(g1) + +@foo9 = common global void ()* null, align 4 + +define i32 @foo8(i32 %a) nounwind { +entry: + store i32 %a, i32* @g1, align 4 + %0 = load void ()** @foo9, align 4 + tail call void %0() nounwind + %1 = load i32* @g1, align 4 + %add = add nsw i32 %1, %a + ret i32 %add +} + +; Test searchForward. Check that the second jal's slot is filled with another +; instruction in the same block. +; +; FORWARD: foo10: +; FORWARD: jal foo11 +; FORWARD: jal foo11 +; FORWARD-NOT: nop +; FORWARD: end foo10 + +define void @foo10() nounwind { +entry: + tail call void @foo11() nounwind + tail call void @foo11() nounwind + store i32 0, i32* @g1, align 4 + tail call void @foo11() nounwind + store i32 0, i32* @g1, align 4 + ret void +} + +declare void @foo11() + +; Check that delay slots of branches in both the entry block and loop body are +; filled. +; +; SUCCBB: succbbs_loop1: +; SUCCBB: bne ${{[0-9]+}}, $zero, $BB +; SUCCBB-NEXT: addiu +; SUCCBB: bne ${{[0-9]+}}, $zero, $BB +; SUCCBB-NEXT: addiu + +define i32 @succbbs_loop1(i32* nocapture %a, i32 %n) { +entry: + %cmp4 = icmp sgt i32 %n, 0 + br i1 %cmp4, label %for.body, label %for.end + +for.body: ; preds = %entry, %for.body + %s.06 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i32 %i.05 + %0 = load i32* %arrayidx, align 4 + %add = add nsw i32 %0, %s.06 + %inc = add nsw i32 %i.05, 1 + %exitcond = icmp eq i32 %inc, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %s.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.body ] + ret i32 %s.0.lcssa +} + +; Check that the first branch has its slot filled. +; +; SUCCBB: succbbs_br1: +; SUCCBB: beq ${{[0-9]+}}, $zero, $BB +; SUCCBB-NEXT: lw $25, %call16(foo100) + +define void @succbbs_br1(i32 %a) { +entry: + %tobool = icmp eq i32 %a, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + tail call void @foo100() #1 + br label %if.end + +if.end: ; preds = %entry, %if.then + ret void +} + +declare void @foo100() diff --git a/test/CodeGen/Mips/cmov.ll b/test/CodeGen/Mips/cmov.ll index 3af899a4e2..81925a4953 100755 --- a/test/CodeGen/Mips/cmov.ll +++ b/test/CodeGen/Mips/cmov.ll @@ -59,3 +59,140 @@ entry: ret i64 %cond } +; slti and conditional move. +; +; Check that, pattern +; (select (setgt a, N), t, f) +; turns into +; (movz t, (setlt a, N + 1), f) +; if N + 1 fits in 16-bit. + +; O32: slti0: +; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 +; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i32 @slti0(i32 %a) { +entry: + %cmp = icmp sgt i32 %a, 32766 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: slti1: +; O32: slt ${{[0-9]+}} + +define i32 @slti1(i32 %a) { +entry: + %cmp = icmp sgt i32 %a, 32767 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: slti2: +; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 +; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i32 @slti2(i32 %a) { +entry: + %cmp = icmp sgt i32 %a, -32769 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: slti3: +; O32: slt ${{[0-9]+}} + +define i32 @slti3(i32 %a) { +entry: + %cmp = icmp sgt i32 %a, -32770 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; 64-bit patterns. + +; N64: slti64_0: +; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 +; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i64 @slti64_0(i64 %a) { +entry: + %cmp = icmp sgt i64 %a, 32766 + %conv = select i1 %cmp, i64 3, i64 4 + ret i64 %conv +} + +; N64: slti64_1: +; N64: slt ${{[0-9]+}} + +define i64 @slti64_1(i64 %a) { +entry: + %cmp = icmp sgt i64 %a, 32767 + %conv = select i1 %cmp, i64 3, i64 4 + ret i64 %conv +} + +; N64: slti64_2: +; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 +; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i64 @slti64_2(i64 %a) { +entry: + %cmp = icmp sgt i64 %a, -32769 + %conv = select i1 %cmp, i64 3, i64 4 + ret i64 %conv +} + +; N64: slti64_3: +; N64: slt ${{[0-9]+}} + +define i64 @slti64_3(i64 %a) { +entry: + %cmp = icmp sgt i64 %a, -32770 + %conv = select i1 %cmp, i64 3, i64 4 + ret i64 %conv +} + +; sltiu instructions. + +; O32: sltiu0: +; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 +; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i32 @sltiu0(i32 %a) { +entry: + %cmp = icmp ugt i32 %a, 32766 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: sltiu1: +; O32: sltu ${{[0-9]+}} + +define i32 @sltiu1(i32 %a) { +entry: + %cmp = icmp ugt i32 %a, 32767 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: sltiu2: +; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 +; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] + +define i32 @sltiu2(i32 %a) { +entry: + %cmp = icmp ugt i32 %a, -32769 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} + +; O32: sltiu3: +; O32: sltu ${{[0-9]+}} + +define i32 @sltiu3(i32 %a) { +entry: + %cmp = icmp ugt i32 %a, -32770 + %cond = select i1 %cmp, i32 3, i32 4 + ret i32 %cond +} diff --git a/test/CodeGen/Mips/eh-return32.ll b/test/CodeGen/Mips/eh-return32.ll new file mode 100644 index 0000000000..fe8a40475c --- /dev/null +++ b/test/CodeGen/Mips/eh-return32.ll @@ -0,0 +1,81 @@ +; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s + +declare void @llvm.eh.return.i32(i32, i8*) +declare void @foo(...) + +define i8* @f1(i32 %offset, i8* %handler) { +entry: + call void (...)* @foo() + call void @llvm.eh.return.i32(i32 %offset, i8* %handler) + unreachable + +; CHECK: f1 +; CHECK: addiu $sp, $sp, -[[spoffset:[0-9]+]] + +; check that $a0-$a3 are saved on stack. +; CHECK: sw $4, [[offset0:[0-9]+]]($sp) +; CHECK: sw $5, [[offset1:[0-9]+]]($sp) +; CHECK: sw $6, [[offset2:[0-9]+]]($sp) +; CHECK: sw $7, [[offset3:[0-9]+]]($sp) + +; check that .cfi_offset directives are emitted for $a0-$a3. +; CHECK: .cfi_offset 4, +; CHECK: .cfi_offset 5, +; CHECK: .cfi_offset 6, +; CHECK: .cfi_offset 7, + +; check that stack adjustment and handler are put in $v1 and $v0. +; CHECK: move $[[R0:[a-z0-9]+]], $5 +; CHECK: move $[[R1:[a-z0-9]+]], $4 +; CHECK: move $3, $[[R1]] +; CHECK: move $2, $[[R0]] + +; check that $a0-$a3 are restored from stack. +; CHECK: lw $4, [[offset0]]($sp) +; CHECK: lw $5, [[offset1]]($sp) +; CHECK: lw $6, [[offset2]]($sp) +; CHECK: lw $7, [[offset3]]($sp) + +; check that stack is adjusted by $v1 and that code returns to address in $v0 +; CHECK: addiu $sp, $sp, [[spoffset]] +; CHECK: move $ra, $2 +; CHECK: jr $ra +; CHECK: addu $sp, $sp, $3 +} + +define i8* @f2(i32 %offset, i8* %handler) { +entry: + call void @llvm.eh.return.i32(i32 %offset, i8* %handler) + unreachable + +; CHECK: f2 +; CHECK: addiu $sp, $sp, -[[spoffset:[0-9]+]] + +; check that $a0-$a3 are saved on stack. +; CHECK: sw $4, [[offset0:[0-9]+]]($sp) +; CHECK: sw $5, [[offset1:[0-9]+]]($sp) +; CHECK: sw $6, [[offset2:[0-9]+]]($sp) +; CHECK: sw $7, [[offset3:[0-9]+]]($sp) + +; check that .cfi_offset directives are emitted for $a0-$a3. +; CHECK: .cfi_offset 4, +; CHECK: .cfi_offset 5, +; CHECK: .cfi_offset 6, +; CHECK: .cfi_offset 7, + +; check that stack adjustment and handler are put in $v1 and $v0. +; CHECK: move $3, $4 +; CHECK: move $2, $5 + +; check that $a0-$a3 are restored from stack. +; CHECK: lw $4, [[offset0]]($sp) +; CHECK: lw $5, [[offset1]]($sp) +; CHECK: lw $6, [[offset2]]($sp) +; CHECK: lw $7, [[offset3]]($sp) + +; check that stack is adjusted by $v1 and that code returns to address in $v0 +; CHECK: addiu $sp, $sp, [[spoffset]] +; CHECK: move $ra, $2 +; CHECK: jr $ra +; CHECK: addu $sp, $sp, $3 +} diff --git a/test/CodeGen/Mips/eh-return64.ll b/test/CodeGen/Mips/eh-return64.ll new file mode 100644 index 0000000000..0b76b95e24 --- /dev/null +++ b/test/CodeGen/Mips/eh-return64.ll @@ -0,0 +1,83 @@ +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s + +declare void @llvm.eh.return.i64(i64, i8*) +declare void @foo(...) + +define void @f1(i64 %offset, i8* %handler) { +entry: + call void (...)* @foo() + call void @llvm.eh.return.i64(i64 %offset, i8* %handler) + unreachable + +; CHECK: f1 +; CHECK: daddiu $sp, $sp, -[[spoffset:[0-9]+]] + +; check that $a0-$a3 are saved on stack. +; CHECK: sd $4, [[offset0:[0-9]+]]($sp) +; CHECK: sd $5, [[offset1:[0-9]+]]($sp) +; CHECK: sd $6, [[offset2:[0-9]+]]($sp) +; CHECK: sd $7, [[offset3:[0-9]+]]($sp) + +; check that .cfi_offset directives are emitted for $a0-$a3. +; CHECK: .cfi_offset 4, +; CHECK: .cfi_offset 5, +; CHECK: .cfi_offset 6, +; CHECK: .cfi_offset 7, + +; check that stack adjustment and handler are put in $v1 and $v0. +; CHECK: move $[[R0:[a-z0-9]+]], $5 +; CHECK: move $[[R1:[a-z0-9]+]], $4 +; CHECK: move $3, $[[R1]] +; CHECK: move $2, $[[R0]] + +; check that $a0-$a3 are restored from stack. +; CHECK: ld $4, [[offset0]]($sp) +; CHECK: ld $5, [[offset1]]($sp) +; CHECK: ld $6, [[offset2]]($sp) +; CHECK: ld $7, [[offset3]]($sp) + +; check that stack is adjusted by $v1 and that code returns to address in $v0 +; CHECK: daddiu $sp, $sp, [[spoffset]] +; CHECK: move $ra, $2 +; CHECK: jr $ra +; CHECK: daddu $sp, $sp, $3 + +} + +define void @f2(i64 %offset, i8* %handler) { +entry: + call void @llvm.eh.return.i64(i64 %offset, i8* %handler) + unreachable + +; CHECK: f2 +; CHECK: daddiu $sp, $sp, -[[spoffset:[0-9]+]] + +; check that $a0-$a3 are saved on stack. +; CHECK: sd $4, [[offset0:[0-9]+]]($sp) +; CHECK: sd $5, [[offset1:[0-9]+]]($sp) +; CHECK: sd $6, [[offset2:[0-9]+]]($sp) +; CHECK: sd $7, [[offset3:[0-9]+]]($sp) + +; check that .cfi_offset directives are emitted for $a0-$a3. +; CHECK: .cfi_offset 4, +; CHECK: .cfi_offset 5, +; CHECK: .cfi_offset 6, +; CHECK: .cfi_offset 7, + +; check that stack adjustment and handler are put in $v1 and $v0. +; CHECK: move $3, $4 +; CHECK: move $2, $5 + +; check that $a0-$a3 are restored from stack. +; CHECK: ld $4, [[offset0]]($sp) +; CHECK: ld $5, [[offset1]]($sp) +; CHECK: ld $6, [[offset2]]($sp) +; CHECK: ld $7, [[offset3]]($sp) + +; check that stack is adjusted by $v1 and that code returns to address in $v0 +; CHECK: daddiu $sp, $sp, [[spoffset]] +; CHECK: move $ra, $2 +; CHECK: jr $ra +; CHECK: daddu $sp, $sp, $3 + +} diff --git a/test/CodeGen/Mips/ex2.ll b/test/CodeGen/Mips/ex2.ll new file mode 100644 index 0000000000..67d19e4b84 --- /dev/null +++ b/test/CodeGen/Mips/ex2.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@_ZTIPKc = external constant i8* + +define i32 @main() { +; 16: main: +; 16: .cfi_startproc +; 16: save $ra, $s0, $s1, 32 +; 16: .cfi_offset 17, -8 +; 16: .cfi_offset 16, -12 +; 16: .cfi_offset 31, -4 +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %exception = call i8* @__cxa_allocate_exception(i32 4) nounwind + %0 = bitcast i8* %exception to i8** + store i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i8** %0 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIPKc to i8*), i8* null) noreturn + unreachable + +return: ; No predecessors! + %1 = load i32* %retval + ret i32 %1 +} + +declare i8* @__cxa_allocate_exception(i32) + +declare void @__cxa_throw(i8*, i8*, i8*) diff --git a/test/CodeGen/Mips/fp16static.ll b/test/CodeGen/Mips/fp16static.ll new file mode 100644 index 0000000000..240ec75a36 --- /dev/null +++ b/test/CodeGen/Mips/fp16static.ll @@ -0,0 +1,13 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -mips16-hard-float -soft-float -relocation-model=static < %s | FileCheck %s -check-prefix=CHECK-STATIC16 + +@x = common global float 0.000000e+00, align 4 + +define void @foo() nounwind { +entry: + %0 = load float* @x, align 4 + %1 = load float* @x, align 4 + %mul = fmul float %0, %1 + store float %mul, float* @x, align 4 +; CHECK-STATIC16: jal __mips16_mulsf3 + ret void +} diff --git a/test/CodeGen/Mips/frame-address.ll b/test/CodeGen/Mips/frame-address.ll index 9df1808fde..92946d9ffd 100644 --- a/test/CodeGen/Mips/frame-address.ll +++ b/test/CodeGen/Mips/frame-address.ll @@ -7,6 +7,6 @@ entry: %0 = call i8* @llvm.frameaddress(i32 0) ret i8* %0 -; CHECK: addu $fp, $sp, $zero -; CHECK: addu $2, $zero, $fp +; CHECK: move $fp, $sp +; CHECK: move $2, $fp } diff --git a/test/CodeGen/Mips/gpreg-lazy-binding.ll b/test/CodeGen/Mips/gpreg-lazy-binding.ll new file mode 100644 index 0000000000..88e596b3bb --- /dev/null +++ b/test/CodeGen/Mips/gpreg-lazy-binding.ll @@ -0,0 +1,27 @@ +; RUN: llc -march=mipsel -disable-mips-delay-filler < %s | FileCheck %s + +@g = external global i32 + +; CHECK: move $gp +; CHECK: jalr $25 +; CHECK: nop +; CHECK-NOT: move $gp +; CHECK: jalr $25 + +define void @f0() nounwind { +entry: + tail call void @externalFunc() nounwind + tail call fastcc void @internalFunc() + ret void +} + +declare void @externalFunc() + +define internal fastcc void @internalFunc() nounwind noinline { +entry: + %0 = load i32* @g, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @g, align 4 + ret void +} + diff --git a/test/CodeGen/Mips/helloworld.ll b/test/CodeGen/Mips/helloworld.ll index aee58b650e..56ee60785f 100644 --- a/test/CodeGen/Mips/helloworld.ll +++ b/test/CodeGen/Mips/helloworld.ll @@ -1,9 +1,11 @@ ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=C1 ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=C2 ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=PE +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s | FileCheck %s -check-prefix=ST1 +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s | FileCheck %s -check-prefix=ST2 ; -; re-enable this when mips16's jalr is fixed. -; DISABLED: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=SR +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=SR +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=SR32 @.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 @@ -15,7 +17,15 @@ entry: ; SR: .set mips16 # @main -; SR: save $ra, [[FS:[0-9]+]] +; SR32: .set nomips16 +; SR32: .ent main +; SR-NOT: .set noreorder +; SR-NOT: .set nomacro +; SR-NOT: .set noat +; SR32: .set noreorder +; SR32: .set nomacro +; SR32: .set noat +; SR: save $ra, $s0, $s1, [[FS:[0-9]+]] ; PE: li $[[T1:[0-9]+]], %hi(_gp_disp) ; PE: addiu $[[T2:[0-9]+]], $pc, %lo(_gp_disp) ; PE: sll $[[T3:[0-9]+]], $[[T1]], 16 @@ -25,10 +35,23 @@ entry: ; C2: move $25, ${{[0-9]+}} ; C1: move $gp, ${{[0-9]+}} ; C1: jalrc ${{[0-9]+}} -; SR: restore $ra, [[FS]] +; SR: restore $ra, $s0, $s1, [[FS]] ; PE: li $2, 0 ; PE: jrc $ra +; ST1: li ${{[0-9]+}}, %hi($.str) +; ST1: sll ${{[0-9]+}}, ${{[0-9]+}}, 16 +; ST1: addiu ${{[0-9]+}}, %lo($.str) +; ST2: li ${{[0-9]+}}, %hi($.str) +; ST2: jal printf } +; SR-NOT: .set at +; SR-NOT: .set macro +; SR-NOT: .set reorder +; SR32: .set at +; SR32: .set macro +; SR32: .set reorder +; SR: .end main +; SR32: .end main declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/hf16_1.ll b/test/CodeGen/Mips/hf16_1.ll new file mode 100644 index 0000000000..c7454ee0a8 --- /dev/null +++ b/test/CodeGen/Mips/hf16_1.ll @@ -0,0 +1,256 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -soft-float -mips16-hard-float -O3 < %s | FileCheck %s -check-prefix=1 +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -soft-float -mips16-hard-float -O3 < %s | FileCheck %s -check-prefix=2 + + +@x = common global float 0.000000e+00, align 4 +@xd = common global double 0.000000e+00, align 8 +@y = common global float 0.000000e+00, align 4 +@yd = common global double 0.000000e+00, align 8 +@xy = common global { float, float } zeroinitializer, align 4 +@xyd = common global { double, double } zeroinitializer, align 8 + +define void @foo() nounwind { +entry: + %0 = load float* @x, align 4 + call void @v_sf(float %0) + %1 = load double* @xd, align 8 + call void @v_df(double %1) + %2 = load float* @x, align 4 + %3 = load float* @y, align 4 + call void @v_sf_sf(float %2, float %3) + %4 = load double* @xd, align 8 + %5 = load float* @x, align 4 + call void @v_df_sf(double %4, float %5) + %6 = load double* @xd, align 8 + %7 = load double* @yd, align 8 + call void @v_df_df(double %6, double %7) + %call = call float @sf_v() + %8 = load float* @x, align 4 + %call1 = call float @sf_sf(float %8) + %9 = load double* @xd, align 8 + %call2 = call float @sf_df(double %9) + %10 = load float* @x, align 4 + %11 = load float* @y, align 4 + %call3 = call float @sf_sf_sf(float %10, float %11) + %12 = load double* @xd, align 8 + %13 = load float* @x, align 4 + %call4 = call float @sf_df_sf(double %12, float %13) + %14 = load double* @xd, align 8 + %15 = load double* @yd, align 8 + %call5 = call float @sf_df_df(double %14, double %15) + %call6 = call double @df_v() + %16 = load float* @x, align 4 + %call7 = call double @df_sf(float %16) + %17 = load double* @xd, align 8 + %call8 = call double @df_df(double %17) + %18 = load float* @x, align 4 + %19 = load float* @y, align 4 + %call9 = call double @df_sf_sf(float %18, float %19) + %20 = load double* @xd, align 8 + %21 = load float* @x, align 4 + %call10 = call double @df_df_sf(double %20, float %21) + %22 = load double* @xd, align 8 + %23 = load double* @yd, align 8 + %call11 = call double @df_df_df(double %22, double %23) + %call12 = call { float, float } @sc_v() + %24 = extractvalue { float, float } %call12, 0 + %25 = extractvalue { float, float } %call12, 1 + %26 = load float* @x, align 4 + %call13 = call { float, float } @sc_sf(float %26) + %27 = extractvalue { float, float } %call13, 0 + %28 = extractvalue { float, float } %call13, 1 + %29 = load double* @xd, align 8 + %call14 = call { float, float } @sc_df(double %29) + %30 = extractvalue { float, float } %call14, 0 + %31 = extractvalue { float, float } %call14, 1 + %32 = load float* @x, align 4 + %33 = load float* @y, align 4 + %call15 = call { float, float } @sc_sf_sf(float %32, float %33) + %34 = extractvalue { float, float } %call15, 0 + %35 = extractvalue { float, float } %call15, 1 + %36 = load double* @xd, align 8 + %37 = load float* @x, align 4 + %call16 = call { float, float } @sc_df_sf(double %36, float %37) + %38 = extractvalue { float, float } %call16, 0 + %39 = extractvalue { float, float } %call16, 1 + %40 = load double* @xd, align 8 + %41 = load double* @yd, align 8 + %call17 = call { float, float } @sc_df_df(double %40, double %41) + %42 = extractvalue { float, float } %call17, 0 + %43 = extractvalue { float, float } %call17, 1 + %call18 = call { double, double } @dc_v() + %44 = extractvalue { double, double } %call18, 0 + %45 = extractvalue { double, double } %call18, 1 + %46 = load float* @x, align 4 + %call19 = call { double, double } @dc_sf(float %46) + %47 = extractvalue { double, double } %call19, 0 + %48 = extractvalue { double, double } %call19, 1 + %49 = load double* @xd, align 8 + %call20 = call { double, double } @dc_df(double %49) + %50 = extractvalue { double, double } %call20, 0 + %51 = extractvalue { double, double } %call20, 1 + %52 = load float* @x, align 4 + %53 = load float* @y, align 4 + %call21 = call { double, double } @dc_sf_sf(float %52, float %53) + %54 = extractvalue { double, double } %call21, 0 + %55 = extractvalue { double, double } %call21, 1 + %56 = load double* @xd, align 8 + %57 = load float* @x, align 4 + %call22 = call { double, double } @dc_df_sf(double %56, float %57) + %58 = extractvalue { double, double } %call22, 0 + %59 = extractvalue { double, double } %call22, 1 + %60 = load double* @xd, align 8 + %61 = load double* @yd, align 8 + %call23 = call { double, double } @dc_df_df(double %60, double %61) + %62 = extractvalue { double, double } %call23, 0 + %63 = extractvalue { double, double } %call23, 1 + ret void +} + +declare void @v_sf(float) + +declare void @v_df(double) + +declare void @v_sf_sf(float, float) + +declare void @v_df_sf(double, float) + +declare void @v_df_df(double, double) + +declare float @sf_v() + +declare float @sf_sf(float) + +declare float @sf_df(double) + +declare float @sf_sf_sf(float, float) + +declare float @sf_df_sf(double, float) + +declare float @sf_df_df(double, double) + +declare double @df_v() + +declare double @df_sf(float) + +declare double @df_df(double) + +declare double @df_sf_sf(float, float) + +declare double @df_df_sf(double, float) + +declare double @df_df_df(double, double) + +declare { float, float } @sc_v() + +declare { float, float } @sc_sf(float) + +declare { float, float } @sc_df(double) + +declare { float, float } @sc_sf_sf(float, float) + +declare { float, float } @sc_df_sf(double, float) + +declare { float, float } @sc_df_df(double, double) + +declare { double, double } @dc_v() + +declare { double, double } @dc_sf(float) + +declare { double, double } @dc_df(double) + +declare { double, double } @dc_sf_sf(float, float) + +declare { double, double } @dc_df_sf(double, float) + +declare { double, double } @dc_df_df(double, double) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_1)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(v_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_2)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(v_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_5)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(v_sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_6)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(v_df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_10)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(v_df_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_0)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_v)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_2)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_5)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_6)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_10)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sf_df_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_0)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_v)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_1)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_5)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_6)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_10)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(df_df_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_0)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_v)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_1)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_2)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_5)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_6)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_sc_10)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(sc_df_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_0)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_v)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_1)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_2)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_df)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_5)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_sf_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_6)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_df_sf)(${{[0-9]+}}) + +; 1: lw ${{[0-9]+}}, %got(__mips16_call_stub_dc_10)(${{[0-9]+}}) +; 2: lw ${{[0-9]+}}, %call16(dc_df_df)(${{[0-9]+}}) + + + diff --git a/test/CodeGen/Mips/i64arg.ll b/test/CodeGen/Mips/i64arg.ll index 8b1f71b69f..704014cba0 100644 --- a/test/CodeGen/Mips/i64arg.ll +++ b/test/CodeGen/Mips/i64arg.ll @@ -2,8 +2,8 @@ define void @f1(i64 %ll1, float %f, i64 %ll, i32 %i, float %f2) nounwind { entry: -; CHECK: addu $[[R1:[0-9]+]], $zero, $5 -; CHECK: addu $[[R0:[0-9]+]], $zero, $4 +; CHECK: move $[[R1:[0-9]+]], $5 +; CHECK: move $[[R0:[0-9]+]], $4 ; CHECK: ori $6, ${{[0-9]+}}, 3855 ; CHECK: ori $7, ${{[0-9]+}}, 22136 ; CHECK: lw $25, %call16(ff1) @@ -12,16 +12,16 @@ entry: ; CHECK: lw $25, %call16(ff2) ; CHECK: lw $[[R2:[0-9]+]], 80($sp) ; CHECK: lw $[[R3:[0-9]+]], 84($sp) -; CHECK: addu $4, $zero, $[[R2]] -; CHECK: addu $5, $zero, $[[R3]] +; CHECK: move $4, $[[R2]] +; CHECK: move $5, $[[R3]] ; CHECK: jalr $25 tail call void @ff2(i64 %ll, double 3.000000e+00) nounwind %sub = add nsw i32 %i, -1 +; CHECK: lw $25, %call16(ff3) ; CHECK: sw $[[R1]], 28($sp) ; CHECK: sw $[[R0]], 24($sp) -; CHECK: lw $25, %call16(ff3) -; CHECK: addu $6, $zero, $[[R2]] -; CHECK: addu $7, $zero, $[[R3]] +; CHECK: move $6, $[[R2]] +; CHECK: move $7, $[[R3]] ; CHECK: jalr $25 tail call void @ff3(i32 %i, i64 %ll, i32 %sub, i64 %ll1) nounwind ret void diff --git a/test/CodeGen/Mips/inlineasm_constraint.ll b/test/CodeGen/Mips/inlineasm_constraint.ll index 5adec3bb29..8d30f45d84 100644 --- a/test/CodeGen/Mips/inlineasm_constraint.ll +++ b/test/CodeGen/Mips/inlineasm_constraint.ll @@ -51,5 +51,14 @@ entry: ; CHECK: #NO_APP tail call i32 asm sideeffect "addi $0,$1,$2", "=r,r,P"(i32 7, i32 65535) nounwind +; Now R Which takes the address of c + %c = alloca i32, align 4 + store i32 -4469539, i32* %c, align 4 + %8 = call i32 asm sideeffect "lwl $0, 1 + $1\0A\09lwr $0, 2 + $1\0A\09", "=r,*R"(i32* %c) #1 +; CHECK: #APP +; CHECK: lwl ${{[0-9]+}}, 1 + 0(${{[0-9]+}}) +; CHECK: lwr ${{[0-9]+}}, 2 + 0(${{[0-9]+}}) +; CHECK: #NO_APP + ret i32 0 } diff --git a/test/CodeGen/Mips/jtstat.ll b/test/CodeGen/Mips/jtstat.ll new file mode 100644 index 0000000000..01afc080c2 --- /dev/null +++ b/test/CodeGen/Mips/jtstat.ll @@ -0,0 +1,71 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=CHECK-STATIC16 + +@s = global i8 115, align 1 +@c = common global i8 0, align 1 +@.str = private unnamed_addr constant [5 x i8] c"%c \0A\00", align 1 + +define void @test(i32 %i) nounwind { +entry: + %i.addr = alloca i32, align 4 + store i32 %i, i32* %i.addr, align 4 + %0 = load i32* %i.addr, align 4 + switch i32 %0, label %sw.epilog [ + i32 115, label %sw.bb + i32 105, label %sw.bb1 + i32 100, label %sw.bb2 + i32 108, label %sw.bb3 + i32 99, label %sw.bb4 + i32 68, label %sw.bb5 + i32 81, label %sw.bb6 + i32 76, label %sw.bb7 + ] + +sw.bb: ; preds = %entry + store i8 115, i8* @c, align 1 + br label %sw.epilog + +sw.bb1: ; preds = %entry + store i8 105, i8* @c, align 1 + br label %sw.epilog + +sw.bb2: ; preds = %entry + store i8 100, i8* @c, align 1 + br label %sw.epilog + +sw.bb3: ; preds = %entry + store i8 108, i8* @c, align 1 + br label %sw.epilog + +sw.bb4: ; preds = %entry + store i8 99, i8* @c, align 1 + br label %sw.epilog + +sw.bb5: ; preds = %entry + store i8 68, i8* @c, align 1 + br label %sw.epilog + +sw.bb6: ; preds = %entry + store i8 81, i8* @c, align 1 + br label %sw.epilog + +sw.bb7: ; preds = %entry + store i8 76, i8* @c, align 1 + br label %sw.epilog + +sw.epilog: ; preds = %entry, %sw.bb7, %sw.bb6, %sw.bb5, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb + ret void +} + +; CHECK-STATIC16: li ${{[0-9]+}}, %hi($JTI{{[0-9]+}}_{{[0-9]+}}) +; CHECK-STATIC16: lw ${{[0-9]+}}, %lo($JTI{{[0-9]+}}_{{[0-9]+}})(${{[0-9]+}}) +; CHECK-STATIC16: $JTI{{[0-9]+}}_{{[0-9]+}}: +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) +; CHECK-STATIC16: .4byte ($BB0_{{[0-9]+}}) diff --git a/test/CodeGen/Mips/largefr1.ll b/test/CodeGen/Mips/largefr1.ll new file mode 100644 index 0000000000..0fe89f71d9 --- /dev/null +++ b/test/CodeGen/Mips/largefr1.ll @@ -0,0 +1,61 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -mips16-hard-float -soft-float -relocation-model=static < %s | FileCheck %s -check-prefix=1 + +@i = common global i32 0, align 4 +@j = common global i32 0, align 4 +@.str = private unnamed_addr constant [8 x i8] c"%i %i \0A\00", align 1 + +define void @foo(i32* %p, i32 %i, i32 %j) nounwind { +entry: + %p.addr = alloca i32*, align 4 + %i.addr = alloca i32, align 4 + %j.addr = alloca i32, align 4 + store i32* %p, i32** %p.addr, align 4 + store i32 %i, i32* %i.addr, align 4 + store i32 %j, i32* %j.addr, align 4 + %0 = load i32* %j.addr, align 4 + %1 = load i32** %p.addr, align 4 + %2 = load i32* %i.addr, align 4 + %add.ptr = getelementptr inbounds i32* %1, i32 %2 + store i32 %0, i32* %add.ptr, align 4 + ret void +} + +define i32 @main() nounwind { +entry: +; 1: main: +; 1: 1: .word -797992 +; 1: li ${{[0-9]+}}, 12 +; 1: sll ${{[0-9]+}}, ${{[0-9]+}}, 16 +; 1: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}} +; 2: move $sp, ${{[0-9]+}} +; 2: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}} +; 1: li ${{[0-9]+}}, 6 +; 1: sll ${{[0-9]+}}, ${{[0-9]+}}, 16 +; 1: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}} +; 2: move $sp, ${{[0-9]+}} +; 2: addu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}} +; 1: addiu ${{[0-9]+}}, ${{[0-9]+}}, 6800 +; 1: li ${{[0-9]+}}, 1 +; 1: sll ${{[0-9]+}}, ${{[0-9]+}}, 16 +; 2: li ${{[0-9]+}}, 34463 + %retval = alloca i32, align 4 + %one = alloca [100000 x i32], align 4 + %two = alloca [100000 x i32], align 4 + store i32 0, i32* %retval + %arrayidx = getelementptr inbounds [100000 x i32]* %one, i32 0, i32 0 + call void @foo(i32* %arrayidx, i32 50, i32 9999) + %arrayidx1 = getelementptr inbounds [100000 x i32]* %two, i32 0, i32 0 + call void @foo(i32* %arrayidx1, i32 99999, i32 5555) + %arrayidx2 = getelementptr inbounds [100000 x i32]* %one, i32 0, i32 50 + %0 = load i32* %arrayidx2, align 4 + store i32 %0, i32* @i, align 4 + %arrayidx3 = getelementptr inbounds [100000 x i32]* %two, i32 0, i32 99999 + %1 = load i32* %arrayidx3, align 4 + store i32 %1, i32* @j, align 4 + %2 = load i32* @i, align 4 + %3 = load i32* @j, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 %2, i32 %3) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/mips16ex.ll b/test/CodeGen/Mips/mips16ex.ll new file mode 100644 index 0000000000..ecb30b5c63 --- /dev/null +++ b/test/CodeGen/Mips/mips16ex.ll @@ -0,0 +1,87 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +;16: $eh_func_begin0=. +@.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 +@_ZTIi = external constant i8* +@.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1 + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %e = alloca i32, align 4 + store i32 0, i32* %retval + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0)) + %exception = call i8* @__cxa_allocate_exception(i32 4) nounwind + %0 = bitcast i8* %exception to i32* + store i32 20, i32* %0 + invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn + to label %unreachable unwind label %lpad + +lpad: ; preds = %entry + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + %2 = extractvalue { i8*, i32 } %1, 0 + store i8* %2, i8** %exn.slot + %3 = extractvalue { i8*, i32 } %1, 1 + store i32 %3, i32* %ehselector.slot + br label %catch.dispatch + +catch.dispatch: ; preds = %lpad + %sel = load i32* %ehselector.slot + %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind + %matches = icmp eq i32 %sel, %4 + br i1 %matches, label %catch, label %eh.resume + +catch: ; preds = %catch.dispatch + %exn = load i8** %exn.slot + %5 = call i8* @__cxa_begin_catch(i8* %exn) nounwind + %6 = bitcast i8* %5 to i32* + %exn.scalar = load i32* %6 + store i32 %exn.scalar, i32* %e, align 4 + %7 = load i32* %e, align 4 + %call2 = invoke i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str1, i32 0, i32 0), i32 %7) + to label %invoke.cont unwind label %lpad1 + +invoke.cont: ; preds = %catch + call void @__cxa_end_catch() nounwind + br label %try.cont + +try.cont: ; preds = %invoke.cont + ret i32 0 + +lpad1: ; preds = %catch + %8 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + %9 = extractvalue { i8*, i32 } %8, 0 + store i8* %9, i8** %exn.slot + %10 = extractvalue { i8*, i32 } %8, 1 + store i32 %10, i32* %ehselector.slot + call void @__cxa_end_catch() nounwind + br label %eh.resume + +eh.resume: ; preds = %lpad1, %catch.dispatch + %exn3 = load i8** %exn.slot + %sel4 = load i32* %ehselector.slot + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn3, 0 + %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %sel4, 1 + resume { i8*, i32 } %lpad.val5 + +unreachable: ; preds = %entry + unreachable +} + +declare i32 @printf(i8*, ...) + +declare i8* @__cxa_allocate_exception(i32) + +declare i32 @__gxx_personality_v0(...) + +declare void @__cxa_throw(i8*, i8*, i8*) + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() diff --git a/test/CodeGen/Mips/mips16fpe.ll b/test/CodeGen/Mips/mips16fpe.ll new file mode 100644 index 0000000000..4335436079 --- /dev/null +++ b/test/CodeGen/Mips/mips16fpe.ll @@ -0,0 +1,381 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 -soft-float -mips16-hard-float < %s | FileCheck %s -check-prefix=16hf + +@x = global float 5.000000e+00, align 4 +@y = global float 1.500000e+01, align 4 +@xd = global double 6.000000e+00, align 8 +@yd = global double 1.800000e+01, align 8 +@two = global i32 2, align 4 +@addsf3_result = common global float 0.000000e+00, align 4 +@adddf3_result = common global double 0.000000e+00, align 8 +@subsf3_result = common global float 0.000000e+00, align 4 +@subdf3_result = common global double 0.000000e+00, align 8 +@mulsf3_result = common global float 0.000000e+00, align 4 +@muldf3_result = common global double 0.000000e+00, align 8 +@divsf3_result = common global float 0.000000e+00, align 4 +@divdf3_result = common global double 0.000000e+00, align 8 +@extendsfdf2_result = common global double 0.000000e+00, align 8 +@xd2 = global double 0x40147E6B74B4CF6A, align 8 +@truncdfsf2_result = common global float 0.000000e+00, align 4 +@fix_truncsfsi_result = common global i32 0, align 4 +@fix_truncdfsi_result = common global i32 0, align 4 +@si = global i32 -9, align 4 +@ui = global i32 9, align 4 +@floatsisf_result = common global float 0.000000e+00, align 4 +@floatsidf_result = common global double 0.000000e+00, align 8 +@floatunsisf_result = common global float 0.000000e+00, align 4 +@floatunsidf_result = common global double 0.000000e+00, align 8 +@xx = global float 5.000000e+00, align 4 +@eqsf2_result = common global i32 0, align 4 +@xxd = global double 6.000000e+00, align 8 +@eqdf2_result = common global i32 0, align 4 +@nesf2_result = common global i32 0, align 4 +@nedf2_result = common global i32 0, align 4 +@gesf2_result = common global i32 0, align 4 +@gedf2_result = common global i32 0, align 4 +@ltsf2_result = common global i32 0, align 4 +@ltdf2_result = common global i32 0, align 4 +@lesf2_result = common global i32 0, align 4 +@ledf2_result = common global i32 0, align 4 +@gtsf2_result = common global i32 0, align 4 +@gtdf2_result = common global i32 0, align 4 + +define void @test_addsf3() nounwind { +entry: +;16hf: test_addsf3: + %0 = load float* @x, align 4 + %1 = load float* @y, align 4 + %add = fadd float %0, %1 + store float %add, float* @addsf3_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_addsf3)(${{[0-9]+}}) + ret void +} + +define void @test_adddf3() nounwind { +entry: +;16hf: test_adddf3: + %0 = load double* @xd, align 8 + %1 = load double* @yd, align 8 + %add = fadd double %0, %1 + store double %add, double* @adddf3_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_adddf3)(${{[0-9]+}}) + ret void +} + +define void @test_subsf3() nounwind { +entry: +;16hf: test_subsf3: + %0 = load float* @x, align 4 + %1 = load float* @y, align 4 + %sub = fsub float %0, %1 + store float %sub, float* @subsf3_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_subsf3)(${{[0-9]+}}) + ret void +} + +define void @test_subdf3() nounwind { +entry: +;16hf: test_subdf3: + %0 = load double* @xd, align 8 + %1 = load double* @yd, align 8 + %sub = fsub double %0, %1 + store double %sub, double* @subdf3_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_subdf3)(${{[0-9]+}}) + ret void +} + +define void @test_mulsf3() nounwind { +entry: +;16hf: test_mulsf3: + %0 = load float* @x, align 4 + %1 = load float* @y, align 4 + %mul = fmul float %0, %1 + store float %mul, float* @mulsf3_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_mulsf3)(${{[0-9]+}}) + ret void +} + +define void @test_muldf3() nounwind { +entry: +;16hf: test_muldf3: + %0 = load double* @xd, align 8 + %1 = load double* @yd, align 8 + %mul = fmul double %0, %1 + store double %mul, double* @muldf3_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_muldf3)(${{[0-9]+}}) + ret void +} + +define void @test_divsf3() nounwind { +entry: +;16hf: test_divsf3: + %0 = load float* @y, align 4 + %1 = load float* @x, align 4 + %div = fdiv float %0, %1 + store float %div, float* @divsf3_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_divsf3)(${{[0-9]+}}) + ret void +} + +define void @test_divdf3() nounwind { +entry: +;16hf: test_divdf3: + %0 = load double* @yd, align 8 + %mul = fmul double %0, 2.000000e+00 + %1 = load double* @xd, align 8 + %div = fdiv double %mul, %1 + store double %div, double* @divdf3_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_divdf3)(${{[0-9]+}}) + ret void +} + +define void @test_extendsfdf2() nounwind { +entry: +;16hf: test_extendsfdf2: + %0 = load float* @x, align 4 + %conv = fpext float %0 to double + store double %conv, double* @extendsfdf2_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_extendsfdf2)(${{[0-9]+}}) + ret void +} + +define void @test_truncdfsf2() nounwind { +entry: +;16hf: test_truncdfsf2: + %0 = load double* @xd2, align 8 + %conv = fptrunc double %0 to float + store float %conv, float* @truncdfsf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_truncdfsf2)(${{[0-9]+}}) + ret void +} + +define void @test_fix_truncsfsi() nounwind { +entry: +;16hf: test_fix_truncsfsi: + %0 = load float* @x, align 4 + %conv = fptosi float %0 to i32 + store i32 %conv, i32* @fix_truncsfsi_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_fix_truncsfsi)(${{[0-9]+}}) + ret void +} + +define void @test_fix_truncdfsi() nounwind { +entry: +;16hf: test_fix_truncdfsi: + %0 = load double* @xd, align 8 + %conv = fptosi double %0 to i32 + store i32 %conv, i32* @fix_truncdfsi_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_fix_truncdfsi)(${{[0-9]+}}) + ret void +} + +define void @test_floatsisf() nounwind { +entry: +;16hf: test_floatsisf: + %0 = load i32* @si, align 4 + %conv = sitofp i32 %0 to float + store float %conv, float* @floatsisf_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_floatsisf)(${{[0-9]+}}) + ret void +} + +define void @test_floatsidf() nounwind { +entry: +;16hf: test_floatsidf: + %0 = load i32* @si, align 4 + %conv = sitofp i32 %0 to double + store double %conv, double* @floatsidf_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_floatsidf)(${{[0-9]+}}) + ret void +} + +define void @test_floatunsisf() nounwind { +entry: +;16hf: test_floatunsisf: + %0 = load i32* @ui, align 4 + %conv = uitofp i32 %0 to float + store float %conv, float* @floatunsisf_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_floatunsisf)(${{[0-9]+}}) + ret void +} + +define void @test_floatunsidf() nounwind { +entry: +;16hf: test_floatunsidf: + %0 = load i32* @ui, align 4 + %conv = uitofp i32 %0 to double + store double %conv, double* @floatunsidf_result, align 8 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_floatunsidf)(${{[0-9]+}}) + ret void +} + +define void @test_eqsf2() nounwind { +entry: +;16hf: test_eqsf2: + %0 = load float* @x, align 4 + %1 = load float* @xx, align 4 + %cmp = fcmp oeq float %0, %1 + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @eqsf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_eqsf2)(${{[0-9]+}}) + ret void +} + +define void @test_eqdf2() nounwind { +entry: +;16hf: test_eqdf2: + %0 = load double* @xd, align 8 + %1 = load double* @xxd, align 8 + %cmp = fcmp oeq double %0, %1 + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @eqdf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_eqdf2)(${{[0-9]+}}) + ret void +} + +define void @test_nesf2() nounwind { +entry: +;16hf: test_nesf2: + %0 = load float* @x, align 4 + %1 = load float* @y, align 4 + %cmp = fcmp une float %0, %1 + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @nesf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_nesf2)(${{[0-9]+}}) + ret void +} + +define void @test_nedf2() nounwind { +entry: +;16hf: test_nedf2: + %0 = load double* @xd, align 8 + %1 = load double* @yd, align 8 + %cmp = fcmp une double %0, %1 + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @nedf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_nedf2)(${{[0-9]+}}) + ret void +} + +define void @test_gesf2() nounwind { +entry: +;16hf: test_gesf2: + %0 = load float* @x, align 4 + %1 = load float* @xx, align 4 + %cmp = fcmp oge float %0, %1 + %2 = load float* @y, align 4 + %cmp1 = fcmp oge float %2, %0 + %and3 = and i1 %cmp, %cmp1 + %and = zext i1 %and3 to i32 + store i32 %and, i32* @gesf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_gesf2)(${{[0-9]+}}) + ret void +} + +define void @test_gedf2() nounwind { +entry: +;16hf: test_gedf2: + %0 = load double* @xd, align 8 + %1 = load double* @xxd, align 8 + %cmp = fcmp oge double %0, %1 + %2 = load double* @yd, align 8 + %cmp1 = fcmp oge double %2, %0 + %and3 = and i1 %cmp, %cmp1 + %and = zext i1 %and3 to i32 + store i32 %and, i32* @gedf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_gedf2)(${{[0-9]+}}) + ret void +} + +define void @test_ltsf2() nounwind { +entry: +;16hf: test_ltsf2: + %0 = load float* @x, align 4 + %1 = load float* @xx, align 4 + %lnot = fcmp uge float %0, %1 + %2 = load float* @y, align 4 + %cmp1 = fcmp olt float %0, %2 + %and2 = and i1 %lnot, %cmp1 + %and = zext i1 %and2 to i32 + store i32 %and, i32* @ltsf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_unordsf2)(${{[0-9]+}}) +;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltsf2)(${{[0-9]+}}) + ret void +} + +define void @test_ltdf2() nounwind { +entry: +;16hf: test_ltdf2: + %0 = load double* @xd, align 8 + %1 = load double* @xxd, align 8 + %lnot = fcmp uge double %0, %1 + %2 = load double* @yd, align 8 + %cmp1 = fcmp olt double %0, %2 + %and2 = and i1 %lnot, %cmp1 + %and = zext i1 %and2 to i32 + store i32 %and, i32* @ltdf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_unorddf2)(${{[0-9]+}}) +;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltdf2)(${{[0-9]+}}) + ret void +} + +define void @test_lesf2() nounwind { +entry: +;16hf: test_lesf2: + %0 = load float* @x, align 4 + %1 = load float* @xx, align 4 + %cmp = fcmp ole float %0, %1 + %2 = load float* @y, align 4 + %cmp1 = fcmp ole float %0, %2 + %and3 = and i1 %cmp, %cmp1 + %and = zext i1 %and3 to i32 + store i32 %and, i32* @lesf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_lesf2)(${{[0-9]+}}) + ret void +} + +define void @test_ledf2() nounwind { +entry: +;16hf: test_ledf2: + %0 = load double* @xd, align 8 + %1 = load double* @xxd, align 8 + %cmp = fcmp ole double %0, %1 + %2 = load double* @yd, align 8 + %cmp1 = fcmp ole double %0, %2 + %and3 = and i1 %cmp, %cmp1 + %and = zext i1 %and3 to i32 + store i32 %and, i32* @ledf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_ledf2)(${{[0-9]+}}) + ret void +} + +define void @test_gtsf2() nounwind { +entry: +;16hf: test_gtsf2: + %0 = load float* @x, align 4 + %1 = load float* @xx, align 4 + %lnot = fcmp ule float %0, %1 + %2 = load float* @y, align 4 + %cmp1 = fcmp ogt float %2, %0 + %and2 = and i1 %lnot, %cmp1 + %and = zext i1 %and2 to i32 + store i32 %and, i32* @gtsf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_gtsf2)(${{[0-9]+}}) + ret void +} + +define void @test_gtdf2() nounwind { +entry: +;16hf: test_gtdf2: + %0 = load double* @xd, align 8 + %1 = load double* @xxd, align 8 + %lnot = fcmp ule double %0, %1 + %2 = load double* @yd, align 8 + %cmp1 = fcmp ogt double %2, %0 + %and2 = and i1 %lnot, %cmp1 + %and = zext i1 %and2 to i32 + store i32 %and, i32* @gtdf2_result, align 4 +;16hf: lw ${{[0-9]+}}, %call16(__mips16_gtdf2)(${{[0-9]+}}) + ret void +} + + diff --git a/test/CodeGen/Mips/mips64-f128-call.ll b/test/CodeGen/Mips/mips64-f128-call.ll new file mode 100644 index 0000000000..455e540e5d --- /dev/null +++ b/test/CodeGen/Mips/mips64-f128-call.ll @@ -0,0 +1,45 @@ +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck %s + +@gld0 = external global fp128 +@gld1 = external global fp128 + +; CHECK: foo0 +; CHECK: sdc1 $f13, 8(${{[0-9]+}}) +; CHECK: sdc1 $f12, 0(${{[0-9]+}}) + +define void @foo0(fp128 %a0) { +entry: + store fp128 %a0, fp128* @gld0, align 16 + ret void +} + +; CHECK: foo1 +; CHECK: ldc1 $f13, 8(${{[0-9]+}}) +; CHECK: ldc1 $f12, 0(${{[0-9]+}}) + +define void @foo1() { +entry: + %0 = load fp128* @gld0, align 16 + tail call void @foo2(fp128 %0) + ret void +} + +declare void @foo2(fp128) + +; CHECK: foo3 +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld0) +; CHECK: sdc1 $f2, 8($[[R0]]) +; CHECK: sdc1 $f0, 0($[[R0]]) +; CHECK: ld $[[R1:[0-9]+]], %got_disp(gld1) +; CHECK: ldc1 $f0, 0($[[R1]]) +; CHECK: ldc1 $f2, 8($[[R1]]) + +define fp128 @foo3() { +entry: + %call = tail call fp128 @foo4() + store fp128 %call, fp128* @gld0, align 16 + %0 = load fp128* @gld1, align 16 + ret fp128 %0 +} + +declare fp128 @foo4() diff --git a/test/CodeGen/Mips/mips64-f128.ll b/test/CodeGen/Mips/mips64-f128.ll new file mode 100644 index 0000000000..5892cab4f8 --- /dev/null +++ b/test/CodeGen/Mips/mips64-f128.ll @@ -0,0 +1,646 @@ +; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -soft-float -O1 \ +; RUN: -disable-mips-delay-filler < %s | FileCheck %s + +@gld0 = external global fp128 +@gld1 = external global fp128 +@gld2 = external global fp128 +@gf1 = external global float +@gd1 = external global double + +; CHECK: addLD: +; CHECK: ld $25, %call16(__addtf3) + +define fp128 @addLD() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %add = fadd fp128 %0, %1 + ret fp128 %add +} + +; CHECK: subLD: +; CHECK: ld $25, %call16(__subtf3) + +define fp128 @subLD() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %sub = fsub fp128 %0, %1 + ret fp128 %sub +} + +; CHECK: mulLD: +; CHECK: ld $25, %call16(__multf3) + +define fp128 @mulLD() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %mul = fmul fp128 %0, %1 + ret fp128 %mul +} + +; CHECK: divLD: +; CHECK: ld $25, %call16(__divtf3) + +define fp128 @divLD() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %div = fdiv fp128 %0, %1 + ret fp128 %div +} + +; CHECK: conv_LD_char: +; CHECK: ld $25, %call16(__floatsitf) + +define fp128 @conv_LD_char(i8 signext %a) { +entry: + %conv = sitofp i8 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_short: +; CHECK: ld $25, %call16(__floatsitf) + +define fp128 @conv_LD_short(i16 signext %a) { +entry: + %conv = sitofp i16 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_int: +; CHECK: ld $25, %call16(__floatsitf) + +define fp128 @conv_LD_int(i32 %a) { +entry: + %conv = sitofp i32 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_LL: +; CHECK: ld $25, %call16(__floatditf) + +define fp128 @conv_LD_LL(i64 %a) { +entry: + %conv = sitofp i64 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_UChar: +; CHECK: ld $25, %call16(__floatunsitf) + +define fp128 @conv_LD_UChar(i8 zeroext %a) { +entry: + %conv = uitofp i8 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_UShort: +; CHECK: ld $25, %call16(__floatunsitf) + +define fp128 @conv_LD_UShort(i16 zeroext %a) { +entry: + %conv = uitofp i16 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_UInt: +; CHECK: ld $25, %call16(__floatunsitf) + +define fp128 @conv_LD_UInt(i32 %a) { +entry: + %conv = uitofp i32 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_ULL: +; CHECK: ld $25, %call16(__floatunditf) + +define fp128 @conv_LD_ULL(i64 %a) { +entry: + %conv = uitofp i64 %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_char_LD: +; CHECK: ld $25, %call16(__fixtfsi) + +define signext i8 @conv_char_LD(fp128 %a) { +entry: + %conv = fptosi fp128 %a to i8 + ret i8 %conv +} + +; CHECK: conv_short_LD: +; CHECK: ld $25, %call16(__fixtfsi) + +define signext i16 @conv_short_LD(fp128 %a) { +entry: + %conv = fptosi fp128 %a to i16 + ret i16 %conv +} + +; CHECK: conv_int_LD: +; CHECK: ld $25, %call16(__fixtfsi) + +define i32 @conv_int_LD(fp128 %a) { +entry: + %conv = fptosi fp128 %a to i32 + ret i32 %conv +} + +; CHECK: conv_LL_LD: +; CHECK: ld $25, %call16(__fixtfdi) + +define i64 @conv_LL_LD(fp128 %a) { +entry: + %conv = fptosi fp128 %a to i64 + ret i64 %conv +} + +; CHECK: conv_UChar_LD: +; CHECK: ld $25, %call16(__fixtfsi) + +define zeroext i8 @conv_UChar_LD(fp128 %a) { +entry: + %conv = fptoui fp128 %a to i8 + ret i8 %conv +} + +; CHECK: conv_UShort_LD: +; CHECK: ld $25, %call16(__fixtfsi) + +define zeroext i16 @conv_UShort_LD(fp128 %a) { +entry: + %conv = fptoui fp128 %a to i16 + ret i16 %conv +} + +; CHECK: conv_UInt_LD: +; CHECK: ld $25, %call16(__fixunstfsi) + +define i32 @conv_UInt_LD(fp128 %a) { +entry: + %conv = fptoui fp128 %a to i32 + ret i32 %conv +} + +; CHECK: conv_ULL_LD: +; CHECK: ld $25, %call16(__fixunstfdi) + +define i64 @conv_ULL_LD(fp128 %a) { +entry: + %conv = fptoui fp128 %a to i64 + ret i64 %conv +} + +; CHECK: conv_LD_float: +; CHECK: ld $25, %call16(__extendsftf2) + +define fp128 @conv_LD_float(float %a) { +entry: + %conv = fpext float %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_LD_double: +; CHECK: ld $25, %call16(__extenddftf2) + +define fp128 @conv_LD_double(double %a) { +entry: + %conv = fpext double %a to fp128 + ret fp128 %conv +} + +; CHECK: conv_float_LD: +; CHECK: ld $25, %call16(__trunctfsf2) + +define float @conv_float_LD(fp128 %a) { +entry: + %conv = fptrunc fp128 %a to float + ret float %conv +} + +; CHECK: conv_double_LD: +; CHECK: ld $25, %call16(__trunctfdf2) + +define double @conv_double_LD(fp128 %a) { +entry: + %conv = fptrunc fp128 %a to double + ret double %conv +} + +; CHECK: libcall1_fabsl: +; CHECK: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) +; CHECK: daddiu $[[R1:[0-9]+]], $zero, 1 +; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 63 +; CHECK: daddiu $[[R3:[0-9]+]], $[[R2]], -1 +; CHECK: and $4, $[[R0]], $[[R3]] +; CHECK: ld $2, 0($[[R4]]) + +define fp128 @libcall1_fabsl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @fabsl(fp128 %0) nounwind readnone + ret fp128 %call +} + +declare fp128 @fabsl(fp128) #1 + +; CHECK: libcall1_ceill: +; CHECK: ld $25, %call16(ceill) + +define fp128 @libcall1_ceill() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @ceill(fp128 %0) nounwind readnone + ret fp128 %call +} + +declare fp128 @ceill(fp128) #1 + +; CHECK: libcall1_sinl: +; CHECK: ld $25, %call16(sinl) + +define fp128 @libcall1_sinl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @sinl(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @sinl(fp128) #2 + +; CHECK: libcall1_cosl: +; CHECK: ld $25, %call16(cosl) + +define fp128 @libcall1_cosl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @cosl(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @cosl(fp128) #2 + +; CHECK: libcall1_expl: +; CHECK: ld $25, %call16(expl) + +define fp128 @libcall1_expl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @expl(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @expl(fp128) #2 + +; CHECK: libcall1_exp2l: +; CHECK: ld $25, %call16(exp2l) + +define fp128 @libcall1_exp2l() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @exp2l(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @exp2l(fp128) #2 + +; CHECK: libcall1_logl: +; CHECK: ld $25, %call16(logl) + +define fp128 @libcall1_logl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @logl(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @logl(fp128) #2 + +; CHECK: libcall1_log2l: +; CHECK: ld $25, %call16(log2l) + +define fp128 @libcall1_log2l() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @log2l(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @log2l(fp128) #2 + +; CHECK: libcall1_log10l: +; CHECK: ld $25, %call16(log10l) + +define fp128 @libcall1_log10l() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @log10l(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @log10l(fp128) #2 + +; CHECK: libcall1_nearbyintl: +; CHECK: ld $25, %call16(nearbyintl) + +define fp128 @libcall1_nearbyintl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @nearbyintl(fp128 %0) nounwind readnone + ret fp128 %call +} + +declare fp128 @nearbyintl(fp128) #1 + +; CHECK: libcall1_floorl: +; CHECK: ld $25, %call16(floorl) + +define fp128 @libcall1_floorl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @floorl(fp128 %0) nounwind readnone + ret fp128 %call +} + +declare fp128 @floorl(fp128) #1 + +; CHECK: libcall1_sqrtl: +; CHECK: ld $25, %call16(sqrtl) + +define fp128 @libcall1_sqrtl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @sqrtl(fp128 %0) nounwind + ret fp128 %call +} + +declare fp128 @sqrtl(fp128) #2 + +; CHECK: libcall1_rintl: +; CHECK: ld $25, %call16(rintl) + +define fp128 @libcall1_rintl() { +entry: + %0 = load fp128* @gld0, align 16 + %call = tail call fp128 @rintl(fp128 %0) nounwind readnone + ret fp128 %call +} + +declare fp128 @rintl(fp128) #1 + +; CHECK: libcall_powil: +; CHECK: ld $25, %call16(__powitf2) + +define fp128 @libcall_powil(fp128 %a, i32 %b) { +entry: + %0 = tail call fp128 @llvm.powi.f128(fp128 %a, i32 %b) + ret fp128 %0 +} + +declare fp128 @llvm.powi.f128(fp128, i32) #3 + +; CHECK: libcall2_copysignl: +; CHECK: daddiu $[[R2:[0-9]+]], $zero, 1 +; CHECK: dsll $[[R3:[0-9]+]], $[[R2]], 63 +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) +; CHECK: ld $[[R1:[0-9]+]], 8($[[R0]]) +; CHECK: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] +; CHECK: ld $[[R5:[0-9]+]], %got_disp(gld0) +; CHECK: ld $[[R6:[0-9]+]], 8($[[R5]]) +; CHECK: daddiu $[[R7:[0-9]+]], $[[R3]], -1 +; CHECK: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] +; CHECK: or $4, $[[R8]], $[[R4]] +; CHECK: ld $2, 0($[[R5]]) + +define fp128 @libcall2_copysignl() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %call = tail call fp128 @copysignl(fp128 %0, fp128 %1) nounwind readnone + ret fp128 %call +} + +declare fp128 @copysignl(fp128, fp128) #1 + +; CHECK: libcall2_powl: +; CHECK: ld $25, %call16(powl) + +define fp128 @libcall2_powl() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %call = tail call fp128 @powl(fp128 %0, fp128 %1) nounwind + ret fp128 %call +} + +declare fp128 @powl(fp128, fp128) #2 + +; CHECK: libcall2_fmodl: +; CHECK: ld $25, %call16(fmodl) + +define fp128 @libcall2_fmodl() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld1, align 16 + %call = tail call fp128 @fmodl(fp128 %0, fp128 %1) nounwind + ret fp128 %call +} + +declare fp128 @fmodl(fp128, fp128) #2 + +; CHECK: libcall3_fmal: +; CHECK: ld $25, %call16(fmal) + +define fp128 @libcall3_fmal() { +entry: + %0 = load fp128* @gld0, align 16 + %1 = load fp128* @gld2, align 16 + %2 = load fp128* @gld1, align 16 + %3 = tail call fp128 @llvm.fma.f128(fp128 %0, fp128 %2, fp128 %1) + ret fp128 %3 +} + +declare fp128 @llvm.fma.f128(fp128, fp128, fp128) #4 + +; CHECK: cmp_lt: +; CHECK: ld $25, %call16(__lttf2) + +define i32 @cmp_lt(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp olt fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: cmp_le: +; CHECK: ld $25, %call16(__letf2) + +define i32 @cmp_le(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp ole fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: cmp_gt: +; CHECK: ld $25, %call16(__gttf2) + +define i32 @cmp_gt(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp ogt fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: cmp_ge: +; CHECK: ld $25, %call16(__getf2) + +define i32 @cmp_ge(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp oge fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: cmp_eq: +; CHECK: ld $25, %call16(__eqtf2) + +define i32 @cmp_eq(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp oeq fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: cmp_ne: +; CHECK: ld $25, %call16(__netf2) + +define i32 @cmp_ne(fp128 %a, fp128 %b) { +entry: + %cmp = fcmp une fp128 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; CHECK: load_LD_LD: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) +; CHECK: ld $2, 0($[[R0]]) +; CHECK: ld $4, 8($[[R0]]) + +define fp128 @load_LD_LD() { +entry: + %0 = load fp128* @gld1, align 16 + ret fp128 %0 +} + +; CHECK: load_LD_float: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gf1) +; CHECK: lw $4, 0($[[R0]]) +; CHECK: ld $25, %call16(__extendsftf2) +; CHECK: jalr $25 + +define fp128 @load_LD_float() { +entry: + %0 = load float* @gf1, align 4 + %conv = fpext float %0 to fp128 + ret fp128 %conv +} + +; CHECK: load_LD_double: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gd1) +; CHECK: ld $4, 0($[[R0]]) +; CHECK: ld $25, %call16(__extenddftf2) +; CHECK: jalr $25 + +define fp128 @load_LD_double() { +entry: + %0 = load double* @gd1, align 8 + %conv = fpext double %0 to fp128 + ret fp128 %conv +} + +; CHECK: store_LD_LD: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) +; CHECK: ld $[[R1:[0-9]+]], 0($[[R0]]) +; CHECK: ld $[[R2:[0-9]+]], 8($[[R0]]) +; CHECK: ld $[[R3:[0-9]+]], %got_disp(gld0) +; CHECK: sd $[[R2]], 8($[[R3]]) +; CHECK: sd $[[R1]], 0($[[R3]]) + +define void @store_LD_LD() { +entry: + %0 = load fp128* @gld1, align 16 + store fp128 %0, fp128* @gld0, align 16 + ret void +} + +; CHECK: store_LD_float: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) +; CHECK: ld $4, 0($[[R0]]) +; CHECK: ld $5, 8($[[R0]]) +; CHECK: ld $25, %call16(__trunctfsf2) +; CHECK: jalr $25 +; CHECK: ld $[[R1:[0-9]+]], %got_disp(gf1) +; CHECK: sw $2, 0($[[R1]]) + +define void @store_LD_float() { +entry: + %0 = load fp128* @gld1, align 16 + %conv = fptrunc fp128 %0 to float + store float %conv, float* @gf1, align 4 + ret void +} + +; CHECK: store_LD_double: +; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) +; CHECK: ld $4, 0($[[R0]]) +; CHECK: ld $5, 8($[[R0]]) +; CHECK: ld $25, %call16(__trunctfdf2) +; CHECK: jalr $25 +; CHECK: ld $[[R1:[0-9]+]], %got_disp(gd1) +; CHECK: sd $2, 0($[[R1]]) + +define void @store_LD_double() { +entry: + %0 = load fp128* @gld1, align 16 + %conv = fptrunc fp128 %0 to double + store double %conv, double* @gd1, align 8 + ret void +} + +; CHECK: select_LD: +; CHECK: movn $8, $6, $4 +; CHECK: movn $9, $7, $4 +; CHECK: move $2, $8 +; CHECK: move $4, $9 + +define fp128 @select_LD(i32 %a, i64, fp128 %b, fp128 %c) { +entry: + %tobool = icmp ne i32 %a, 0 + %cond = select i1 %tobool, fp128 %b, fp128 %c + ret fp128 %cond +} + +; CHECK: selectCC_LD: +; CHECK: move $[[R0:[0-9]+]], $11 +; CHECK: move $[[R1:[0-9]+]], $10 +; CHECK: move $[[R2:[0-9]+]], $9 +; CHECK: move $[[R3:[0-9]+]], $8 +; CHECK: ld $25, %call16(__gttf2)($gp) +; CHECK: jalr $25 +; CHECK: slti $1, $2, 1 +; CHECK: movz $[[R1]], $[[R3]], $1 +; CHECK: movz $[[R0]], $[[R2]], $1 +; CHECK: move $2, $[[R1]] +; CHECK: move $4, $[[R0]] + +define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) { +entry: + %cmp = fcmp ogt fp128 %a, %b + %cond = select i1 %cmp, fp128 %c, fp128 %d + ret fp128 %cond +} diff --git a/test/CodeGen/Mips/mips64-libcall.ll b/test/CodeGen/Mips/mips64-libcall.ll new file mode 100644 index 0000000000..d54598be70 --- /dev/null +++ b/test/CodeGen/Mips/mips64-libcall.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=mips64el -mcpu=mips64r2 -O3 < %s |\ +; RUN: FileCheck %s -check-prefix=HARD +; RUN: llc -march=mips64el -mcpu=mips64r2 -soft-float < %s |\ +; RUN: FileCheck %s -check-prefix=SOFT + +; Check that %add is not passed in an integer register. +; +; HARD: callfloor: +; HARD-NOT: dmfc1 $4 + +define double @callfloor(double %d) nounwind readnone { +entry: + %add = fadd double %d, 1.000000e+00 + %call = tail call double @floor(double %add) nounwind readnone + ret double %call +} + +declare double @floor(double) nounwind readnone + +; Check call16. +; +; SOFT: f64add: +; SOFT: ld $25, %call16(__adddf3) + +define double @f64add(double %a, double %b) { +entry: + %add = fadd double %a, %b + ret double %add +} diff --git a/test/CodeGen/Mips/mips64-sret.ll b/test/CodeGen/Mips/mips64-sret.ll index e26b0223b4..e01609f3b1 100644 --- a/test/CodeGen/Mips/mips64-sret.ll +++ b/test/CodeGen/Mips/mips64-sret.ll @@ -6,7 +6,7 @@ define void @f(%struct.S* noalias sret %agg.result) nounwind { entry: -; CHECK: daddu $2, $zero, $4 +; CHECK: move $2, $4 %0 = bitcast %struct.S* %agg.result to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.S* @g to i8*), i64 32, i32 4, i1 false) diff --git a/test/CodeGen/Mips/o32_cc_byval.ll b/test/CodeGen/Mips/o32_cc_byval.ll index 5558ba6e10..0a8f85f482 100644 --- a/test/CodeGen/Mips/o32_cc_byval.ll +++ b/test/CodeGen/Mips/o32_cc_byval.ll @@ -12,20 +12,20 @@ define void @f1() nounwind { entry: ; CHECK: lw $[[R1:[0-9]+]], %got(f1.s1) ; CHECK: addiu $[[R0:[0-9]+]], $[[R1]], %lo(f1.s1) +; CHECK: lw $[[R7:[0-9]+]], 12($[[R0]]) +; CHECK: lw $[[R3:[0-9]+]], 16($[[R0]]) +; CHECK: lw $[[R4:[0-9]+]], 20($[[R0]]) +; CHECK: lw $[[R5:[0-9]+]], 24($[[R0]]) ; CHECK: lw $[[R6:[0-9]+]], 28($[[R0]]) ; CHECK: sw $[[R6]], 36($sp) -; CHECK: lw $[[R5:[0-9]+]], 24($[[R0]]) ; CHECK: sw $[[R5]], 32($sp) -; CHECK: lw $[[R4:[0-9]+]], 20($[[R0]]) ; CHECK: sw $[[R4]], 28($sp) -; CHECK: lw $[[R3:[0-9]+]], 16($[[R0]]) ; CHECK: sw $[[R3]], 24($sp) -; CHECK: lw $[[R7:[0-9]+]], 12($[[R0]]) ; CHECK: sw $[[R7]], 20($sp) ; CHECK: lw $[[R2:[0-9]+]], 8($[[R0]]) ; CHECK: sw $[[R2]], 16($sp) -; CHECK: lw $7, 4($[[R0]]) ; CHECK: lw $6, %lo(f1.s1)($[[R1]]) +; CHECK: lw $7, 4($[[R0]]) %agg.tmp10 = alloca %struct.S3, align 4 call void @callee1(float 2.000000e+01, %struct.S1* byval bitcast (%0* @f1.s1 to %struct.S1*)) nounwind call void @callee2(%struct.S2* byval @f1.s2) nounwind diff --git a/test/CodeGen/Mips/return-vector-float4.ll b/test/CodeGen/Mips/return-vector-float4.ll deleted file mode 100644 index ae10f123e4..0000000000 --- a/test/CodeGen/Mips/return-vector-float4.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc -march=mipsel -mattr=+android < %s | FileCheck %s - -define <4 x float> @retvec4() nounwind readnone { -entry: -; CHECK: lwc1 $f0 -; CHECK: lwc1 $f2 -; CHECK: lwc1 $f1 -; CHECK: lwc1 $f3 - - ret <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> -} - diff --git a/test/CodeGen/Mips/return_address.ll b/test/CodeGen/Mips/return_address.ll index e1c9241984..34b72baa6d 100644 --- a/test/CodeGen/Mips/return_address.ll +++ b/test/CodeGen/Mips/return_address.ll @@ -5,7 +5,7 @@ entry: %0 = call i8* @llvm.returnaddress(i32 0) ret i8* %0 -; CHECK: addu $2, $zero, $ra +; CHECK: move $2, $ra } define i8* @f2() nounwind { @@ -14,9 +14,9 @@ entry: %0 = call i8* @llvm.returnaddress(i32 0) ret i8* %0 -; CHECK: addu $[[R0:[0-9]+]], $zero, $ra +; CHECK: move $[[R0:[0-9]+]], $ra ; CHECK: jal -; CHECK: addu $2, $zero, $[[R0]] +; CHECK: move $2, $[[R0]] } declare i8* @llvm.returnaddress(i32) nounwind readnone diff --git a/test/CodeGen/Mips/selTBteqzCmpi.ll b/test/CodeGen/Mips/selTBteqzCmpi.ll new file mode 100644 index 0000000000..9cb8227f9d --- /dev/null +++ b/test/CodeGen/Mips/selTBteqzCmpi.ll @@ -0,0 +1,26 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@i = global i32 1, align 4 +@j = global i32 2, align 4 +@a = global i32 5, align 4 +@.str = private unnamed_addr constant [8 x i8] c"%i = 2\0A\00", align 1 +@k = common global i32 0, align 4 + +define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp eq i32 %0, 10 + %1 = load i32* @i, align 4 + %2 = load i32* @j, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @i, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } + + +; 16: cmpi ${{[0-9]+}}, 10 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + + diff --git a/test/CodeGen/Mips/selTBtnezCmpi.ll b/test/CodeGen/Mips/selTBtnezCmpi.ll new file mode 100644 index 0000000000..bd334f59d3 --- /dev/null +++ b/test/CodeGen/Mips/selTBtnezCmpi.ll @@ -0,0 +1,26 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@i = global i32 1, align 4 +@j = global i32 2, align 4 +@a = global i32 5, align 4 +@.str = private unnamed_addr constant [8 x i8] c"%i = 1\0A\00", align 1 +@k = common global i32 0, align 4 + +define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp ne i32 %0, 10 + %1 = load i32* @i, align 4 + %2 = load i32* @j, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @i, align 4 + ret void +} + +; 16: cmpi ${{[0-9]+}}, 10 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } + + diff --git a/test/CodeGen/Mips/selTBtnezSlti.ll b/test/CodeGen/Mips/selTBtnezSlti.ll new file mode 100644 index 0000000000..593f6f274e --- /dev/null +++ b/test/CodeGen/Mips/selTBtnezSlti.ll @@ -0,0 +1,25 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@i = global i32 1, align 4 +@j = global i32 2, align 4 +@a = global i32 5, align 4 +@.str = private unnamed_addr constant [9 x i8] c"%i = 2 \0A\00", align 1 +@k = common global i32 0, align 4 + +define void @t() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, 10 + %1 = load i32* @j, align 4 + %2 = load i32* @i, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @i, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: slti ${{[0-9]+}}, 10 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + + diff --git a/test/CodeGen/Mips/seleq.ll b/test/CodeGen/Mips/seleq.ll new file mode 100644 index 0000000000..190baad0b1 --- /dev/null +++ b/test/CodeGen/Mips/seleq.ll @@ -0,0 +1,95 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 10, align 4 +@c = global i32 1, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 + +define void @calc_seleq() nounwind "target-cpu"="mips32" "target-features"="+o32,+mips32" { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp eq i32 %0, %1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %2 = load i32* @f, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %3 = load i32* @t, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %2, %cond.true ], [ %3, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %4 = load i32* @b, align 4 + %5 = load i32* @a, align 4 + %cmp1 = icmp eq i32 %4, %5 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %6 = load i32* @f, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %7 = load i32* @t, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %6, %cond.true2 ], [ %7, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %8 = load i32* @c, align 4 + %9 = load i32* @a, align 4 + %cmp6 = icmp eq i32 %8, %9 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %10 = load i32* @t, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %11 = load i32* @f, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %10, %cond.true7 ], [ %11, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %12 = load i32* @a, align 4 + %13 = load i32* @c, align 4 + %cmp11 = icmp eq i32 %12, %13 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %14 = load i32* @t, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %15 = load i32* @f, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %14, %cond.true12 ], [ %15, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips32" "target-features"="+o32,+mips32" } + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + diff --git a/test/CodeGen/Mips/seleqk.ll b/test/CodeGen/Mips/seleqk.ll new file mode 100644 index 0000000000..3ca622d5d8 --- /dev/null +++ b/test/CodeGen/Mips/seleqk.ll @@ -0,0 +1,91 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 1000, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_seleqk() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp eq i32 %0, 1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %1 = load i32* @t, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %2 = load i32* @f, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %1, %cond.true ], [ %2, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %3 = load i32* @a, align 4 + %cmp1 = icmp eq i32 %3, 1000 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %4 = load i32* @f, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %5 = load i32* @t, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %4, %cond.true2 ], [ %5, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %6 = load i32* @b, align 4 + %cmp6 = icmp eq i32 %6, 3 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %7 = load i32* @f, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %8 = load i32* @t, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %7, %cond.true7 ], [ %8, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %9 = load i32* @b, align 4 + %cmp11 = icmp eq i32 %9, 1000 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %10 = load i32* @t, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %11 = load i32* @f, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %10, %cond.true12 ], [ %11, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: cmpi ${{[0-9]+}}, 1 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 1000 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 3 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 1000 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} diff --git a/test/CodeGen/Mips/selgek.ll b/test/CodeGen/Mips/selgek.ll new file mode 100644 index 0000000000..8ab4046e92 --- /dev/null +++ b/test/CodeGen/Mips/selgek.ll @@ -0,0 +1,94 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 2, align 4 +@b = global i32 1000, align 4 +@c = global i32 2, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_z() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp sge i32 %0, 1000 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %1 = load i32* @f, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %2 = load i32* @t, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %1, %cond.true ], [ %2, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %3 = load i32* @b, align 4 + %cmp1 = icmp sge i32 %3, 1 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %4 = load i32* @t, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %5 = load i32* @f, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %4, %cond.true2 ], [ %5, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %6 = load i32* @c, align 4 + %cmp6 = icmp sge i32 %6, 2 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %7 = load i32* @t, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %8 = load i32* @f, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %7, %cond.true7 ], [ %8, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %9 = load i32* @a, align 4 + %cmp11 = icmp sge i32 %9, 2 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %10 = load i32* @t, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %11 = load i32* @f, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %10, %cond.true12 ], [ %11, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: slti ${{[0-9]+}}, 1000 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slti ${{[0-9]+}}, 1 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slti ${{[0-9]+}}, 2 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slti ${{[0-9]+}}, 2 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + + diff --git a/test/CodeGen/Mips/selgt.ll b/test/CodeGen/Mips/selgt.ll new file mode 100644 index 0000000000..67b9b49870 --- /dev/null +++ b/test/CodeGen/Mips/selgt.ll @@ -0,0 +1,98 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 10, align 4 +@c = global i32 1, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [9 x i8] c"%i = %i\0A\00", align 1 + +define i32 @calc_z() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %retval = alloca i32, align 4 + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp sgt i32 %0, %1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %2 = load i32* @f, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %3 = load i32* @t, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %2, %cond.true ], [ %3, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %4 = load i32* @b, align 4 + %5 = load i32* @a, align 4 + %cmp1 = icmp sgt i32 %4, %5 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %6 = load i32* @t, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %7 = load i32* @f, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %6, %cond.true2 ], [ %7, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %8 = load i32* @c, align 4 + %9 = load i32* @a, align 4 + %cmp6 = icmp sgt i32 %8, %9 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %10 = load i32* @f, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %11 = load i32* @t, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %10, %cond.true7 ], [ %11, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %12 = load i32* @a, align 4 + %13 = load i32* @c, align 4 + %cmp11 = icmp sgt i32 %12, %13 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %14 = load i32* @f, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %15 = load i32* @t, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %14, %cond.true12 ], [ %15, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + %16 = load i32* %retval + ret i32 %16 +} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } diff --git a/test/CodeGen/Mips/selle.ll b/test/CodeGen/Mips/selle.ll new file mode 100644 index 0000000000..b27df45e67 --- /dev/null +++ b/test/CodeGen/Mips/selle.ll @@ -0,0 +1,96 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 10, align 4 +@c = global i32 1, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_z() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp sle i32 %0, %1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %2 = load i32* @t, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %3 = load i32* @f, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %2, %cond.true ], [ %3, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %4 = load i32* @b, align 4 + %5 = load i32* @a, align 4 + %cmp1 = icmp sle i32 %4, %5 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %6 = load i32* @f, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %7 = load i32* @t, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %6, %cond.true2 ], [ %7, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %8 = load i32* @c, align 4 + %9 = load i32* @a, align 4 + %cmp6 = icmp sle i32 %8, %9 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %10 = load i32* @t, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %11 = load i32* @f, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %10, %cond.true7 ], [ %11, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %12 = load i32* @a, align 4 + %13 = load i32* @c, align 4 + %cmp11 = icmp sle i32 %12, %13 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %14 = load i32* @t, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %15 = load i32* @f, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %14, %cond.true12 ], [ %15, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } diff --git a/test/CodeGen/Mips/selltk.ll b/test/CodeGen/Mips/selltk.ll new file mode 100644 index 0000000000..1471b892c9 --- /dev/null +++ b/test/CodeGen/Mips/selltk.ll @@ -0,0 +1,93 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 2, align 4 +@b = global i32 1000, align 4 +@c = global i32 2, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_selltk() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, 1000 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %1 = load i32* @t, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %2 = load i32* @f, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %1, %cond.true ], [ %2, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %3 = load i32* @b, align 4 + %cmp1 = icmp slt i32 %3, 2 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %4 = load i32* @f, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %5 = load i32* @t, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %4, %cond.true2 ], [ %5, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %6 = load i32* @c, align 4 + %cmp6 = icmp sgt i32 %6, 2 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %7 = load i32* @f, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %8 = load i32* @t, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %7, %cond.true7 ], [ %8, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %9 = load i32* @a, align 4 + %cmp11 = icmp sgt i32 %9, 2 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %10 = load i32* @f, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %11 = load i32* @t, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %10, %cond.true12 ], [ %11, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slti ${{[0-9]+}}, 3 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + +; 16: slti ${{[0-9]+}}, 3 # 16 bit inst +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} + diff --git a/test/CodeGen/Mips/selne.ll b/test/CodeGen/Mips/selne.ll new file mode 100644 index 0000000000..e3d82b8cf5 --- /dev/null +++ b/test/CodeGen/Mips/selne.ll @@ -0,0 +1,97 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 10, align 4 +@c = global i32 1, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_seleq() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp ne i32 %0, %1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %2 = load i32* @f, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %3 = load i32* @t, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %2, %cond.true ], [ %3, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %4 = load i32* @b, align 4 + %5 = load i32* @a, align 4 + %cmp1 = icmp ne i32 %4, %5 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %6 = load i32* @f, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %7 = load i32* @t, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %6, %cond.true2 ], [ %7, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %8 = load i32* @c, align 4 + %9 = load i32* @a, align 4 + %cmp6 = icmp ne i32 %8, %9 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %10 = load i32* @t, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %11 = load i32* @f, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %10, %cond.true7 ], [ %11, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %12 = load i32* @a, align 4 + %13 = load i32* @c, align 4 + %cmp11 = icmp ne i32 %12, %13 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %14 = load i32* @t, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %15 = load i32* @f, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %14, %cond.true12 ], [ %15, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + diff --git a/test/CodeGen/Mips/selnek.ll b/test/CodeGen/Mips/selnek.ll new file mode 100644 index 0000000000..2601552310 --- /dev/null +++ b/test/CodeGen/Mips/selnek.ll @@ -0,0 +1,107 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 1000, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define void @calc_z() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp ne i32 %0, 1 + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: ; preds = %entry + %1 = load i32* @f, align 4 + br label %cond.end + +cond.false: ; preds = %entry + %2 = load i32* @t, align 4 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %1, %cond.true ], [ %2, %cond.false ] + store i32 %cond, i32* @z1, align 4 + %3 = load i32* @a, align 4 + %cmp1 = icmp ne i32 %3, 1000 + br i1 %cmp1, label %cond.true2, label %cond.false3 + +cond.true2: ; preds = %cond.end + %4 = load i32* @t, align 4 + br label %cond.end4 + +cond.false3: ; preds = %cond.end + %5 = load i32* @f, align 4 + br label %cond.end4 + +cond.end4: ; preds = %cond.false3, %cond.true2 + %cond5 = phi i32 [ %4, %cond.true2 ], [ %5, %cond.false3 ] + store i32 %cond5, i32* @z2, align 4 + %6 = load i32* @b, align 4 + %cmp6 = icmp ne i32 %6, 3 + br i1 %cmp6, label %cond.true7, label %cond.false8 + +cond.true7: ; preds = %cond.end4 + %7 = load i32* @t, align 4 + br label %cond.end9 + +cond.false8: ; preds = %cond.end4 + %8 = load i32* @f, align 4 + br label %cond.end9 + +cond.end9: ; preds = %cond.false8, %cond.true7 + %cond10 = phi i32 [ %7, %cond.true7 ], [ %8, %cond.false8 ] + store i32 %cond10, i32* @z3, align 4 + %9 = load i32* @b, align 4 + %cmp11 = icmp ne i32 %9, 1000 + br i1 %cmp11, label %cond.true12, label %cond.false13 + +cond.true12: ; preds = %cond.end9 + %10 = load i32* @f, align 4 + br label %cond.end14 + +cond.false13: ; preds = %cond.end9 + %11 = load i32* @t, align 4 + br label %cond.end14 + +cond.end14: ; preds = %cond.false13, %cond.true12 + %cond15 = phi i32 [ %10, %cond.true12 ], [ %11, %cond.false13 ] + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define i32 @main() nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" { +entry: + call void @calc_z() "target-cpu"="mips16" "target-features"="+mips16,+o32" + %0 = load i32* @z1, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %0) "target-cpu"="mips16" "target-features"="+mips16,+o32" + %1 = load i32* @z2, align 4 + %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) "target-cpu"="mips16" "target-features"="+mips16,+o32" + %2 = load i32* @z3, align 4 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %2) "target-cpu"="mips16" "target-features"="+mips16,+o32" + %3 = load i32* @z4, align 4 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %3) "target-cpu"="mips16" "target-features"="+mips16,+o32" + ret i32 0 +} + +declare i32 @printf(i8*, ...) "target-cpu"="mips16" "target-features"="+mips16,+o32" + +attributes #0 = { nounwind "target-cpu"="mips16" "target-features"="+mips16,+o32" } +attributes #1 = { "target-cpu"="mips16" "target-features"="+mips16,+o32" } + +; 16: cmpi ${{[0-9]+}}, 1 # 16 bit inst +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 1000 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 3 # 16 bit inst +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} + +; 16: cmpi ${{[0-9]+}}, 1000 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}}
\ No newline at end of file diff --git a/test/CodeGen/Mips/selpat.ll b/test/CodeGen/Mips/selpat.ll index cda0c96ef4..8eda8de45e 100644 --- a/test/CodeGen/Mips/selpat.ll +++ b/test/CodeGen/Mips/selpat.ll @@ -20,7 +20,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} store i32 %cond, i32* @z2, align 4 %4 = load i32* @c, align 4 @@ -41,7 +41,7 @@ entry: %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 ; 16: cmpi ${{[0-9]+}}, 1 -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp eq i32 %0, 10 %cond5 = select i1 %cmp1, i32 %2, i32 %1 @@ -51,7 +51,7 @@ entry: %cond10 = select i1 %cmp6, i32 %2, i32 %1 store i32 %cond10, i32* @z3, align 4 ; 16: cmpi ${{[0-9]+}}, 10 -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp11 = icmp eq i32 %3, 10 %cond15 = select i1 %cmp11, i32 %1, i32 %2 @@ -67,7 +67,7 @@ entry: %2 = load i32* @f, align 4 %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: beqz ${{[0-9]+}}, .+4 +; 16: beqz ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %cmp1 = icmp eq i32 %3, 0 @@ -91,7 +91,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp sge i32 %1, %0 %cond5 = select i1 %cmp1, i32 %3, i32 %2 @@ -112,7 +112,7 @@ entry: %1 = load i32* @b, align 4 %cmp = icmp sgt i32 %0, %1 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %2 = load i32* @f, align 4 %3 = load i32* @t, align 4 @@ -141,7 +141,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp sle i32 %1, %0 %cond5 = select i1 %cmp1, i32 %3, i32 %2 @@ -165,7 +165,7 @@ entry: %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 ; 16: slti ${{[0-9]+}}, {{[0-9]+}} -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %cmp1 = icmp slt i32 %3, 2 @@ -192,7 +192,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} store i32 %cond, i32* @z2, align 4 %4 = load i32* @c, align 4 @@ -212,7 +212,7 @@ entry: %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 ; 16: cmpi ${{[0-9]+}}, 1 -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp ne i32 %0, 10 %cond5 = select i1 %cmp1, i32 %2, i32 %1 @@ -222,7 +222,7 @@ entry: %cond10 = select i1 %cmp6, i32 %2, i32 %1 store i32 %cond10, i32* @z3, align 4 ; 16: cmpi ${{[0-9]+}}, 10 -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp11 = icmp ne i32 %3, 10 %cond15 = select i1 %cmp11, i32 %1, i32 %2 @@ -238,7 +238,7 @@ entry: %2 = load i32* @t, align 4 %cond = select i1 %cmp, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: bnez ${{[0-9]+}}, .+4 +; 16: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %cmp1 = icmp ne i32 %3, 0 @@ -260,7 +260,7 @@ entry: %2 = load i32* @t, align 4 %cond = select i1 %tobool, i32 %1, i32 %2 store i32 %cond, i32* @z1, align 4 -; 16: bnez ${{[0-9]+}}, .+4 +; 16: bnez ${{[0-9]+}}, $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %3 = load i32* @b, align 4 %tobool1 = icmp ne i32 %3, 0 @@ -284,7 +284,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp uge i32 %1, %0 %cond5 = select i1 %cmp1, i32 %3, i32 %2 @@ -309,7 +309,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: btnez .+4 +; 16: btnez $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp ugt i32 %1, %0 %cond5 = select i1 %cmp1, i32 %3, i32 %2 @@ -334,7 +334,7 @@ entry: %cond = select i1 %cmp, i32 %2, i32 %3 store i32 %cond, i32* @z1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: bteqz .+4 +; 16: bteqz $BB{{[0-9]+}}_{{[0-9]}} ; 16: move ${{[0-9]+}}, ${{[0-9]+}} %cmp1 = icmp ule i32 %1, %0 %cond5 = select i1 %cmp1, i32 %3, i32 %2 diff --git a/test/CodeGen/Mips/seteq.ll b/test/CodeGen/Mips/seteq.ll index da840c83a2..5fadf78d57 100644 --- a/test/CodeGen/Mips/seteq.ll +++ b/test/CodeGen/Mips/seteq.ll @@ -15,7 +15,7 @@ entry: store i32 %conv, i32* @r1, align 4 ; 16: xor $[[REGISTER:[0-9A-Ba-b_]+]], ${{[0-9]+}} ; 16: sltiu $[[REGISTER:[0-9A-Ba-b_]+]], 1 -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/seteqz.ll b/test/CodeGen/Mips/seteqz.ll index d445be6aed..80dc3120a6 100644 --- a/test/CodeGen/Mips/seteqz.ll +++ b/test/CodeGen/Mips/seteqz.ll @@ -12,13 +12,13 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: sltiu ${{[0-9]+}}, 1 -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 %1 = load i32* @j, align 4 %cmp1 = icmp eq i32 %1, 99 %conv2 = zext i1 %cmp1 to i32 store i32 %conv2, i32* @r2, align 4 ; 16: xor $[[REGISTER:[0-9A-Ba-b_]+]], ${{[0-9]+}} ; 16: sltiu $[[REGISTER:[0-9A-Ba-b_]+]], 1 -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/setge.ll b/test/CodeGen/Mips/setge.ll index 94b499bc31..8869eb8fc5 100644 --- a/test/CodeGen/Mips/setge.ll +++ b/test/CodeGen/Mips/setge.ll @@ -17,7 +17,7 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: move $[[REGISTER:[0-9]+]], $t8 +; 16: move $[[REGISTER:[0-9]+]], $24 ; 16: xor $[[REGISTER]], ${{[0-9]+}} %2 = load i32* @m, align 4 %cmp1 = icmp sge i32 %0, %2 diff --git a/test/CodeGen/Mips/setgek.ll b/test/CodeGen/Mips/setgek.ll index b6bae09bcb..18a0fcf621 100644 --- a/test/CodeGen/Mips/setgek.ll +++ b/test/CodeGen/Mips/setgek.ll @@ -12,7 +12,7 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: slti ${{[0-9]+}}, -32768 -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ; 16: xor ${{[0-9]+}}, ${{[0-9]+}} ret void } diff --git a/test/CodeGen/Mips/setle.ll b/test/CodeGen/Mips/setle.ll index f36fb4392d..2df6774c1f 100644 --- a/test/CodeGen/Mips/setle.ll +++ b/test/CodeGen/Mips/setle.ll @@ -16,7 +16,7 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: move $[[REGISTER:[0-9]+]], $t8 +; 16: move $[[REGISTER:[0-9]+]], $24 ; 16: xor $[[REGISTER]], ${{[0-9]+}} %2 = load i32* @m, align 4 %cmp1 = icmp sle i32 %2, %1 diff --git a/test/CodeGen/Mips/setlt.ll b/test/CodeGen/Mips/setlt.ll index 435be8e233..3dac74bf2e 100644 --- a/test/CodeGen/Mips/setlt.ll +++ b/test/CodeGen/Mips/setlt.ll @@ -16,6 +16,6 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: slt ${{[0-9]+}}, ${{[0-9]+}} -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/setltk.ll b/test/CodeGen/Mips/setltk.ll index c0b610e377..ecebc7e578 100644 --- a/test/CodeGen/Mips/setltk.ll +++ b/test/CodeGen/Mips/setltk.ll @@ -15,6 +15,6 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: slti $[[REGISTER:[0-9]+]], 10 -; 16: move $[[REGISTER]], $t8 +; 16: move $[[REGISTER]], $24 ret void } diff --git a/test/CodeGen/Mips/setne.ll b/test/CodeGen/Mips/setne.ll index 6460c83c7b..9e66901e32 100644 --- a/test/CodeGen/Mips/setne.ll +++ b/test/CodeGen/Mips/setne.ll @@ -15,6 +15,6 @@ entry: store i32 %conv, i32* @r1, align 4 ; 16: xor $[[REGISTER:[0-9]+]], ${{[0-9]+}} ; 16: sltu ${{[0-9]+}}, $[[REGISTER]] -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/setuge.ll b/test/CodeGen/Mips/setuge.ll index ac72b66e9f..1c9b5bbe81 100644 --- a/test/CodeGen/Mips/setuge.ll +++ b/test/CodeGen/Mips/setuge.ll @@ -16,7 +16,7 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: move $[[REGISTER:[0-9]+]], $t8 +; 16: move $[[REGISTER:[0-9]+]], $24 ; 16: xor $[[REGISTER]], ${{[0-9]+}} %2 = load i32* @m, align 4 %cmp1 = icmp uge i32 %0, %2 diff --git a/test/CodeGen/Mips/setugt.ll b/test/CodeGen/Mips/setugt.ll index 328f0e3be3..f10b47ae71 100644 --- a/test/CodeGen/Mips/setugt.ll +++ b/test/CodeGen/Mips/setugt.ll @@ -16,6 +16,6 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/setule.ll b/test/CodeGen/Mips/setule.ll index 792f2ae0fa..a6d6bf0640 100644 --- a/test/CodeGen/Mips/setule.ll +++ b/test/CodeGen/Mips/setule.ll @@ -16,7 +16,7 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: move $[[REGISTER:[0-9]+]], $t8 +; 16: move $[[REGISTER:[0-9]+]], $24 ; 16: xor $[[REGISTER]], ${{[0-9]+}} %2 = load i32* @m, align 4 %cmp1 = icmp ule i32 %2, %1 diff --git a/test/CodeGen/Mips/setult.ll b/test/CodeGen/Mips/setult.ll index 56d2e8daa3..00ee437a2f 100644 --- a/test/CodeGen/Mips/setult.ll +++ b/test/CodeGen/Mips/setult.ll @@ -16,6 +16,6 @@ entry: %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 ; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} -; 16: move ${{[0-9]+}}, $t8 +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/setultk.ll b/test/CodeGen/Mips/setultk.ll index 75b270ed84..eb9edbaad7 100644 --- a/test/CodeGen/Mips/setultk.ll +++ b/test/CodeGen/Mips/setultk.ll @@ -14,7 +14,7 @@ entry: %cmp = icmp ult i32 %0, 10 %conv = zext i1 %cmp to i32 store i32 %conv, i32* @r1, align 4 -; 16: sltiu $[[REGISTER:[0-9]+]], 10 -; 16: move $[[REGISTER]], $t8 +; 16: sltiu ${{[0-9]+}}, 10 # 16 bit inst +; 16: move ${{[0-9]+}}, $24 ret void } diff --git a/test/CodeGen/Mips/tls.ll b/test/CodeGen/Mips/tls.ll index 72d30dc369..b86d25e5e5 100644 --- a/test/CodeGen/Mips/tls.ll +++ b/test/CodeGen/Mips/tls.ll @@ -21,9 +21,9 @@ entry: ; PIC: jalr $25 ; PIC: lw $2, 0($2) -; STATIC: rdhwr $3, $29 ; STATIC: lui $[[R0:[0-9]+]], %tprel_hi(t1) ; STATIC: addiu $[[R1:[0-9]+]], $[[R0]], %tprel_lo(t1) +; STATIC: rdhwr $3, $29 ; STATIC: addu $[[R2:[0-9]+]], $3, $[[R1]] ; STATIC: lw $2, 0($[[R2]]) } diff --git a/test/CodeGen/Mips/vector-setcc.ll b/test/CodeGen/Mips/vector-setcc.ll new file mode 100644 index 0000000000..aeff4918c8 --- /dev/null +++ b/test/CodeGen/Mips/vector-setcc.ll @@ -0,0 +1,16 @@ +; RUN: llc -march=mipsel < %s + +@a = common global <4 x i32> zeroinitializer, align 16 +@b = common global <4 x i32> zeroinitializer, align 16 +@g0 = common global <4 x i32> zeroinitializer, align 16 + +define void @foo0() nounwind { +entry: + %0 = load <4 x i32>* @a, align 16 + %1 = load <4 x i32>* @b, align 16 + %cmp = icmp slt <4 x i32> %0, %1 + %sext = sext <4 x i1> %cmp to <4 x i32> + store <4 x i32> %sext, <4 x i32>* @g0, align 16 + ret void +} + diff --git a/test/CodeGen/NVPTX/intrin-nocapture.ll b/test/CodeGen/NVPTX/intrin-nocapture.ll new file mode 100644 index 0000000000..55781bb15a --- /dev/null +++ b/test/CodeGen/NVPTX/intrin-nocapture.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -O3 -S | FileCheck %s + +; Address space intrinsics were erroneously marked NoCapture, leading to bad +; optimizations (such as the store below being eliminated as dead code). This +; test makes sure we don't regress. + +declare void @foo(i32 addrspace(1)*) + +declare i32 addrspace(1)* @llvm.nvvm.ptr.gen.to.global.p1i32.p0i32(i32*) + +; CHECK: @bar +define void @bar() { + %t1 = alloca i32 +; CHECK: call i32 addrspace(1)* @llvm.nvvm.ptr.gen.to.global.p1i32.p0i32(i32* %t1) +; CHECK-NEXT: store i32 10, i32* %t1 + %t2 = call i32 addrspace(1)* @llvm.nvvm.ptr.gen.to.global.p1i32.p0i32(i32* %t1) + store i32 10, i32* %t1 + call void @foo(i32 addrspace(1)* %t2) + ret void +} + diff --git a/test/CodeGen/NVPTX/vector-loads.ll b/test/CodeGen/NVPTX/vector-loads.ll new file mode 100644 index 0000000000..f5a1795e3c --- /dev/null +++ b/test/CodeGen/NVPTX/vector-loads.ll @@ -0,0 +1,66 @@ +; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s + +; Even though general vector types are not supported in PTX, we can still +; optimize loads/stores with pseudo-vector instructions of the form: +; +; ld.v2.f32 {%f0, %f1}, [%r0] +; +; which will load two floats at once into scalar registers. + +define void @foo(<2 x float>* %a) { +; CHECK: .func foo +; CHECK: ld.v2.f32 {%f{{[0-9]+}}, %f{{[0-9]+}}}, [%r{{[0-9]+}}]; + %t1 = load <2 x float>* %a + %t2 = fmul <2 x float> %t1, %t1 + store <2 x float> %t2, <2 x float>* %a + ret void +} + +define void @foo2(<4 x float>* %a) { +; CHECK: .func foo2 +; CHECK: ld.v4.f32 {%f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}, [%r{{[0-9]+}}]; + %t1 = load <4 x float>* %a + %t2 = fmul <4 x float> %t1, %t1 + store <4 x float> %t2, <4 x float>* %a + ret void +} + +define void @foo3(<8 x float>* %a) { +; CHECK: .func foo3 +; CHECK: ld.v4.f32 {%f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}, [%r{{[0-9]+}}]; +; CHECK-NEXT: ld.v4.f32 {%f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}, %f{{[0-9]+}}}, [%r{{[0-9]+}}+16]; + %t1 = load <8 x float>* %a + %t2 = fmul <8 x float> %t1, %t1 + store <8 x float> %t2, <8 x float>* %a + ret void +} + + + +define void @foo4(<2 x i32>* %a) { +; CHECK: .func foo4 +; CHECK: ld.v2.u32 {%r{{[0-9]+}}, %r{{[0-9]+}}}, [%r{{[0-9]+}}]; + %t1 = load <2 x i32>* %a + %t2 = mul <2 x i32> %t1, %t1 + store <2 x i32> %t2, <2 x i32>* %a + ret void +} + +define void @foo5(<4 x i32>* %a) { +; CHECK: .func foo5 +; CHECK: ld.v4.u32 {%r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}}, [%r{{[0-9]+}}]; + %t1 = load <4 x i32>* %a + %t2 = mul <4 x i32> %t1, %t1 + store <4 x i32> %t2, <4 x i32>* %a + ret void +} + +define void @foo6(<8 x i32>* %a) { +; CHECK: .func foo6 +; CHECK: ld.v4.u32 {%r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}}, [%r{{[0-9]+}}]; +; CHECK-NEXT: ld.v4.u32 {%r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}, %r{{[0-9]+}}}, [%r{{[0-9]+}}+16]; + %t1 = load <8 x i32>* %a + %t2 = mul <8 x i32> %t1, %t1 + store <8 x i32> %t2, <8 x i32>* %a + ret void +} diff --git a/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll b/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll index 8802b97d2a..00a402e0e4 100644 --- a/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll +++ b/test/CodeGen/PowerPC/2008-07-10-SplatMiscompile.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -march=ppc32 -mcpu=g5 | grep vadduhm ; RUN: llc < %s -march=ppc32 -mcpu=g5 | grep vsubuhm +; XFAIL: * define <4 x i32> @test() nounwind { ret <4 x i32> < i32 4293066722, i32 4293066722, i32 4293066722, i32 4293066722> diff --git a/test/CodeGen/PowerPC/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/PowerPC/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 4a850984a9..0000000000 --- a/test/CodeGen/PowerPC/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=ppc32 -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/PowerPC/DbgValueOtherTargets.test b/test/CodeGen/PowerPC/DbgValueOtherTargets.test new file mode 100644 index 0000000000..b1b338776b --- /dev/null +++ b/test/CodeGen/PowerPC/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=ppc32 -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/PowerPC/iabs.ll b/test/CodeGen/PowerPC/Stats/iabs.ll index 7d089bbd65..7d089bbd65 100644 --- a/test/CodeGen/PowerPC/iabs.ll +++ b/test/CodeGen/PowerPC/Stats/iabs.ll diff --git a/test/CodeGen/PowerPC/Stats/lit.local.cfg b/test/CodeGen/PowerPC/Stats/lit.local.cfg new file mode 100644 index 0000000000..2608e139e9 --- /dev/null +++ b/test/CodeGen/PowerPC/Stats/lit.local.cfg @@ -0,0 +1,8 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'PowerPC' in targets: + config.unsupported = True + +if not config.root.enable_assertions: + config.unsupported = True diff --git a/test/CodeGen/PowerPC/rlwimi3.ll b/test/CodeGen/PowerPC/Stats/rlwimi3.ll index 7efdbe9634..7efdbe9634 100644 --- a/test/CodeGen/PowerPC/rlwimi3.ll +++ b/test/CodeGen/PowerPC/Stats/rlwimi3.ll diff --git a/test/CodeGen/PowerPC/a2q-stackalign.ll b/test/CodeGen/PowerPC/a2q-stackalign.ll new file mode 100644 index 0000000000..00c3291193 --- /dev/null +++ b/test/CodeGen/PowerPC/a2q-stackalign.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -march=ppc64 -mcpu=a2 | FileCheck -check-prefix=CHECK-A2 %s +; RUN: llc < %s -march=ppc64 -mcpu=a2q | FileCheck -check-prefix=CHECK-A2Q %s +; RUN: llc < %s -march=ppc64 -mtriple=powerpc64-bgq-linux -mcpu=a2 | FileCheck -check-prefix=CHECK-BGQ %s +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +declare i32 @bar(i8* %a) nounwind; +define i32 @foo() nounwind { + %p = alloca i8, i8 115 + store i8 0, i8* %p + %r = call i32 @bar(i8* %p) + ret i32 %r +} + +; Without QPX, the allocated stack frame is 240 bytes, but with QPX +; (because we require 32-byte alignment), it is 256 bytes. +; CHECK-A2: @foo +; CHECK-A2: stdu 1, -240(1) +; CHECK-A2Q: @foo +; CHECK-A2Q: stdu 1, -256(1) +; CHECK-BGQ: @foo +; CHECK-BGQ: stdu 1, -256(1) + diff --git a/test/CodeGen/PowerPC/a2q.ll b/test/CodeGen/PowerPC/a2q.ll new file mode 100644 index 0000000000..b26480f08b --- /dev/null +++ b/test/CodeGen/PowerPC/a2q.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -march=ppc64 -mcpu=a2q | FileCheck %s +; RUN: llc < %s -march=ppc64 -mcpu=a2 -mattr=+qpx | FileCheck %s + +define void @foo() { +entry: + ret void +} + +; CHECK: @foo + diff --git a/test/CodeGen/PowerPC/anon_aggr.ll b/test/CodeGen/PowerPC/anon_aggr.ll new file mode 100644 index 0000000000..52587e2c0b --- /dev/null +++ b/test/CodeGen/PowerPC/anon_aggr.ll @@ -0,0 +1,99 @@ +; RUN: llc -O0 -mcpu=pwr7 -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s + +; Test case for PR 14779: anonymous aggregates are not handled correctly. +; The bug is triggered by passing a byval structure after an anonymous +; aggregate. + +%tarray = type { i64, i8* } + +define i8* @func1({ i64, i8* } %array, i8* %ptr) { +entry: + %array_ptr = extractvalue {i64, i8* } %array, 1 + %cond = icmp eq i8* %array_ptr, %ptr + br i1 %cond, label %equal, label %unequal +equal: + ret i8* %array_ptr +unequal: + ret i8* %ptr +} + +; CHECK: func1: +; CHECK: cmpld {{[0-9]+}}, 4, 5 +; CHECK: std 4, -[[OFFSET1:[0-9]+]] +; CHECK: std 5, -[[OFFSET2:[0-9]+]] +; CHECK: ld 3, -[[OFFSET1]](1) +; CHECK: ld 3, -[[OFFSET2]](1) + + +define i8* @func2({ i64, i8* } %array1, %tarray* byval %array2) { +entry: + %array1_ptr = extractvalue {i64, i8* } %array1, 1 + %tmp = getelementptr inbounds %tarray* %array2, i32 0, i32 1 + %array2_ptr = load i8** %tmp + %cond = icmp eq i8* %array1_ptr, %array2_ptr + br i1 %cond, label %equal, label %unequal +equal: + ret i8* %array1_ptr +unequal: + ret i8* %array2_ptr +} + +; CHECK: func2: +; CHECK: addi [[REG1:[0-9]+]], 1, 64 +; CHECK: ld [[REG2:[0-9]+]], 8([[REG1]]) +; CHECK: cmpld {{[0-9]+}}, 4, [[REG2]] +; CHECK: std [[REG2]], -[[OFFSET1:[0-9]+]] +; CHECK: std 4, -[[OFFSET2:[0-9]+]] +; CHECK: ld 3, -[[OFFSET2]](1) +; CHECK: ld 3, -[[OFFSET1]](1) + +define i8* @func3({ i64, i8* }* byval %array1, %tarray* byval %array2) { +entry: + %tmp1 = getelementptr inbounds { i64, i8* }* %array1, i32 0, i32 1 + %array1_ptr = load i8** %tmp1 + %tmp2 = getelementptr inbounds %tarray* %array2, i32 0, i32 1 + %array2_ptr = load i8** %tmp2 + %cond = icmp eq i8* %array1_ptr, %array2_ptr + br i1 %cond, label %equal, label %unequal +equal: + ret i8* %array1_ptr +unequal: + ret i8* %array2_ptr +} + +; CHECK: func3: +; CHECK: addi [[REG1:[0-9]+]], 1, 64 +; CHECK: addi [[REG2:[0-9]+]], 1, 48 +; CHECK: ld [[REG3:[0-9]+]], 8([[REG1]]) +; CHECK: ld [[REG4:[0-9]+]], 8([[REG2]]) +; CHECK: cmpld {{[0-9]+}}, [[REG4]], [[REG3]] +; CHECK: std [[REG3]], -[[OFFSET1:[0-9]+]](1) +; CHECK: std [[REG4]], -[[OFFSET2:[0-9]+]](1) +; CHECK: ld 3, -[[OFFSET2]](1) +; CHECK: ld 3, -[[OFFSET1]](1) + +define i8* @func4(i64 %p1, i64 %p2, i64 %p3, i64 %p4, + i64 %p5, i64 %p6, i64 %p7, i64 %p8, + { i64, i8* } %array1, %tarray* byval %array2) { +entry: + %array1_ptr = extractvalue {i64, i8* } %array1, 1 + %tmp = getelementptr inbounds %tarray* %array2, i32 0, i32 1 + %array2_ptr = load i8** %tmp + %cond = icmp eq i8* %array1_ptr, %array2_ptr + br i1 %cond, label %equal, label %unequal +equal: + ret i8* %array1_ptr +unequal: + ret i8* %array2_ptr +} + +; CHECK: func4: +; CHECK: addi [[REG1:[0-9]+]], 1, 128 +; CHECK: ld [[REG2:[0-9]+]], 120(1) +; CHECK: ld [[REG3:[0-9]+]], 8([[REG1]]) +; CHECK: cmpld {{[0-9]+}}, [[REG2]], [[REG3]] +; CHECK: std [[REG2]], -[[OFFSET1:[0-9]+]](1) +; CHECK: std [[REG3]], -[[OFFSET2:[0-9]+]](1) +; CHECK: ld 3, -[[OFFSET1]](1) +; CHECK: ld 3, -[[OFFSET2]](1) + diff --git a/test/CodeGen/PowerPC/atomic-2.ll b/test/CodeGen/PowerPC/atomic-2.ll index a427379a8b..40b4a2eea9 100644 --- a/test/CodeGen/PowerPC/atomic-2.ll +++ b/test/CodeGen/PowerPC/atomic-2.ll @@ -24,3 +24,23 @@ define i64 @exchange(i64* %mem, i64 %val) nounwind { ; CHECK: stdcx. ret i64 %tmp } + +define void @atomic_store(i64* %mem, i64 %val) nounwind { +entry: +; CHECK: @atomic_store + store atomic i64 %val, i64* %mem release, align 64 +; CHECK: ldarx +; CHECK: stdcx. + ret void +} + +define i64 @atomic_load(i64* %mem) nounwind { +entry: +; CHECK: @atomic_load + %tmp = load atomic i64* %mem acquire, align 64 +; CHECK: ldarx +; CHECK: stdcx. +; CHECK: stdcx. + ret i64 %tmp +} + diff --git a/test/CodeGen/PowerPC/complex-return.ll b/test/CodeGen/PowerPC/complex-return.ll new file mode 100644 index 0000000000..f12152ff0f --- /dev/null +++ b/test/CodeGen/PowerPC/complex-return.ll @@ -0,0 +1,55 @@ +; RUN: llc -mcpu=pwr7 -O0 < %s | FileCheck %s + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define { ppc_fp128, ppc_fp128 } @foo() nounwind { +entry: + %retval = alloca { ppc_fp128, ppc_fp128 }, align 16 + %x = alloca { ppc_fp128, ppc_fp128 }, align 16 + %real = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %x, i32 0, i32 0 + %imag = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %x, i32 0, i32 1 + store ppc_fp128 0xM400C0000000000000000000000000000, ppc_fp128* %real + store ppc_fp128 0xMC00547AE147AE1483CA47AE147AE147A, ppc_fp128* %imag + %x.realp = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %x, i32 0, i32 0 + %x.real = load ppc_fp128* %x.realp + %x.imagp = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %x, i32 0, i32 1 + %x.imag = load ppc_fp128* %x.imagp + %real1 = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %retval, i32 0, i32 0 + %imag2 = getelementptr inbounds { ppc_fp128, ppc_fp128 }* %retval, i32 0, i32 1 + store ppc_fp128 %x.real, ppc_fp128* %real1 + store ppc_fp128 %x.imag, ppc_fp128* %imag2 + %0 = load { ppc_fp128, ppc_fp128 }* %retval + ret { ppc_fp128, ppc_fp128 } %0 +} + +; CHECK: foo: +; CHECK: lfd 3 +; CHECK: lfd 4 +; CHECK: lfd 2 +; CHECK: lfd 1 + +define { float, float } @oof() nounwind { +entry: + %retval = alloca { float, float }, align 4 + %x = alloca { float, float }, align 4 + %real = getelementptr inbounds { float, float }* %x, i32 0, i32 0 + %imag = getelementptr inbounds { float, float }* %x, i32 0, i32 1 + store float 3.500000e+00, float* %real + store float 0xC00547AE20000000, float* %imag + %x.realp = getelementptr inbounds { float, float }* %x, i32 0, i32 0 + %x.real = load float* %x.realp + %x.imagp = getelementptr inbounds { float, float }* %x, i32 0, i32 1 + %x.imag = load float* %x.imagp + %real1 = getelementptr inbounds { float, float }* %retval, i32 0, i32 0 + %imag2 = getelementptr inbounds { float, float }* %retval, i32 0, i32 1 + store float %x.real, float* %real1 + store float %x.imag, float* %imag2 + %0 = load { float, float }* %retval + ret { float, float } %0 +} + +; CHECK: oof: +; CHECK: lfs 2 +; CHECK: lfs 1 + diff --git a/test/CodeGen/PowerPC/dbg.ll b/test/CodeGen/PowerPC/dbg.ll index e161cb0568..8d87cf793d 100644 --- a/test/CodeGen/PowerPC/dbg.ll +++ b/test/CodeGen/PowerPC/dbg.ll @@ -17,10 +17,8 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} !0 = metadata !{i32 720913, i32 0, i32 12, metadata !"dbg.c", metadata !"/src", metadata !"clang version 3.1", i1 true, i1 true, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] -!1 = metadata !{metadata !2} -!2 = metadata !{i32 0} -!3 = metadata !{metadata !4} -!4 = metadata !{metadata !5} +!1 = metadata !{i32 0} +!3 = metadata !{metadata !5} !5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"main", metadata !"main", metadata !"", metadata !6, i32 1, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (i32, i8**)* @main, null, null, metadata !13} ; [ DW_TAG_subprogram ] !6 = metadata !{i32 720937, metadata !"dbg.c", metadata !"/src", null} ; [ DW_TAG_file_type ] !7 = metadata !{i32 720917, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] diff --git a/test/CodeGen/PowerPC/dcbt-sched.ll b/test/CodeGen/PowerPC/dcbt-sched.ll new file mode 100644 index 0000000000..dfa1b75bd7 --- /dev/null +++ b/test/CodeGen/PowerPC/dcbt-sched.ll @@ -0,0 +1,22 @@ +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" +; RUN: llc -mcpu=a2 -enable-misched -enable-aa-sched-mi < %s | FileCheck %s + +define i8 @test1(i8* noalias %a, i8* noalias %b, i8* noalias %c) nounwind { +entry: + %q = load i8* %b + call void @llvm.prefetch(i8* %a, i32 0, i32 3, i32 1) + %r = load i8* %c + %s = add i8 %q, %r + ret i8 %s +} + +declare void @llvm.prefetch(i8*, i32, i32, i32) + +; Test that we've moved the second load to before the dcbt to better +; hide its latency. +; CHECK: @test1 +; CHECK: lbz +; CHECK: lbz +; CHECK: dcbt + diff --git a/test/CodeGen/PowerPC/float-asmprint.ll b/test/CodeGen/PowerPC/float-asmprint.ll new file mode 100644 index 0000000000..c9dc02862a --- /dev/null +++ b/test/CodeGen/PowerPC/float-asmprint.ll @@ -0,0 +1,34 @@ +; RUN: llc -mtriple=powerpc64-none-linux < %s | FileCheck %s + +; Check that all current floating-point types are correctly emitted to assembly +; on a big-endian target. x86_fp80 can't actually print for unrelated reasons, +; but that's not really a problem. + +@var128 = global fp128 0xL00000000000000008000000000000000, align 16 +@varppc128 = global ppc_fp128 0xM80000000000000000000000000000000, align 16 +@var64 = global double -0.0, align 8 +@var32 = global float -0.0, align 4 +@var16 = global half -0.0, align 2 + +; CHECK: var128: +; CHECK-NEXT: .quad -9223372036854775808 # fp128 -0 +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .size + +; CHECK: varppc128: +; CHECK-NEXT: .quad -9223372036854775808 # ppc_fp128 -0 +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .size + +; CHECK: var64: +; CHECK-NEXT: .quad -9223372036854775808 # double -0 +; CHECK-NEXT: .size + +; CHECK: var32: +; CHECK-NEXT: .long 2147483648 # float -0 +; CHECK-NEXT: .size + +; CHECK: var16: +; CHECK-NEXT: .short 32768 # half -0 +; CHECK-NEXT: .size + diff --git a/test/CodeGen/PowerPC/in-asm-f64-reg.ll b/test/CodeGen/PowerPC/in-asm-f64-reg.ll new file mode 100644 index 0000000000..1321dfce20 --- /dev/null +++ b/test/CodeGen/PowerPC/in-asm-f64-reg.ll @@ -0,0 +1,11 @@ +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s + +define void @f() { +; CHECK: @f + +entry: + %0 = tail call double* asm sideeffect "qvstfdux $2,$0,$1", "=b,{r7},{f11},0,~{memory}"(i32 64, double undef, double* undef) + ret void + +; CHECK: qvstfdux 11,{{[0-9]+}},7 +} diff --git a/test/CodeGen/PowerPC/load-shift-combine.ll b/test/CodeGen/PowerPC/load-shift-combine.ll new file mode 100644 index 0000000000..a5d1224864 --- /dev/null +++ b/test/CodeGen/PowerPC/load-shift-combine.ll @@ -0,0 +1,34 @@ +; RUN: llc < %s + +; This used to cause a crash. A standard load is converted to a pre-increment +; load. Later the pre-increment load is combined with a subsequent SRL to +; produce a smaller load. This transform invalidly created a standard load +; and propagated the produced value into uses of both produced values of the +; pre-increment load. The result was a crash when attempting to process an +; add with a token-chain operand. + +%struct.Info = type { i32, i32, i8*, i8*, i8*, [32 x i8*], i64, [32 x i64], i64, i64, i64, [32 x i64] } +%struct.S1847 = type { [12 x i8], [4 x i8], [8 x i8], [4 x i8], [8 x i8], [2 x i8], i8, [4 x i64], i8, [3 x i8], [4 x i8], i8, i16, [4 x %struct.anon.76], i16, i8, i8* } +%struct.anon.76 = type { i32 } +@info = common global %struct.Info zeroinitializer, align 8 +@fails = common global i32 0, align 4 +@a1847 = external global [5 x %struct.S1847] +define void @test1847() nounwind { +entry: + %j = alloca i32, align 4 + %0 = load i64* getelementptr inbounds (%struct.Info* @info, i32 0, i32 8), align 8 + %1 = load i32* @fails, align 4 + %bf.load1 = load i96* bitcast (%struct.S1847* getelementptr inbounds ([5 x %struct.S1847]* @a1847, i32 0, i64 2) to i96*), align 8 + %bf.clear2 = and i96 %bf.load1, 302231454903657293676543 + %bf.set3 = or i96 %bf.clear2, -38383394772764476296921088 + store i96 %bf.set3, i96* bitcast (%struct.S1847* getelementptr inbounds ([5 x %struct.S1847]* @a1847, i32 0, i64 2) to i96*), align 8 + %2 = load i32* %j, align 4 + %3 = load i32* %j, align 4 + %inc11 = add nsw i32 %3, 1 + store i32 %inc11, i32* %j, align 4 + %bf.load15 = load i96* bitcast (%struct.S1847* getelementptr inbounds ([5 x %struct.S1847]* @a1847, i32 0, i64 2) to i96*), align 8 + %bf.clear16 = and i96 %bf.load15, -18446744069414584321 + %bf.set17 = or i96 %bf.clear16, 18446743532543672320 + store i96 %bf.set17, i96* bitcast (%struct.S1847* getelementptr inbounds ([5 x %struct.S1847]* @a1847, i32 0, i64 2) to i96*), align 8 + ret void +} diff --git a/test/CodeGen/PowerPC/mcm-1.ll b/test/CodeGen/PowerPC/mcm-1.ll index 62fe88c2b8..a57fb9dd98 100644 --- a/test/CodeGen/PowerPC/mcm-1.ll +++ b/test/CodeGen/PowerPC/mcm-1.ll @@ -1,6 +1,7 @@ ; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading and storing an external variable. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" diff --git a/test/CodeGen/PowerPC/mcm-10.ll b/test/CodeGen/PowerPC/mcm-10.ll new file mode 100644 index 0000000000..4bec3e16fa --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-10.ll @@ -0,0 +1,25 @@ +; RUN: llc -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck %s + +; Test peephole optimization for medium code model (32-bit TOC offsets) +; for loading and storing a static variable scoped to a function. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@test_fn_static.si = internal global i32 0, align 4 + +define signext i32 @test_fn_static() nounwind { +entry: + %0 = load i32* @test_fn_static.si, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @test_fn_static.si, align 4 + ret i32 %0 +} + +; CHECK: test_fn_static: +; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; CHECK: lwz {{[0-9]+}}, [[VAR]]@toc@l([[REG1]]) +; CHECK: stw {{[0-9]+}}, [[VAR]]@toc@l([[REG1]]) +; CHECK: .type [[VAR]],@object +; CHECK: .local [[VAR]] +; CHECK: .comm [[VAR]],4,4 diff --git a/test/CodeGen/PowerPC/mcm-11.ll b/test/CodeGen/PowerPC/mcm-11.ll new file mode 100644 index 0000000000..f2bc4c9cb7 --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-11.ll @@ -0,0 +1,27 @@ +; RUN: llc -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck %s + +; Test peephole optimization for medium code model (32-bit TOC offsets) +; for loading and storing a file-scope static variable. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@gi = global i32 5, align 4 + +define signext i32 @test_file_static() nounwind { +entry: + %0 = load i32* @gi, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @gi, align 4 + ret i32 %0 +} + +; CHECK: test_file_static: +; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; CHECK: lwz {{[0-9]+}}, [[VAR]]@toc@l([[REG1]]) +; CHECK: stw {{[0-9]+}}, [[VAR]]@toc@l([[REG1]]) +; CHECK: .type [[VAR]],@object +; CHECK: .data +; CHECK: .globl [[VAR]] +; CHECK: [[VAR]]: +; CHECK: .long 5 diff --git a/test/CodeGen/PowerPC/mcm-12.ll b/test/CodeGen/PowerPC/mcm-12.ll new file mode 100644 index 0000000000..911305d435 --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-12.ll @@ -0,0 +1,18 @@ +; RUN: llc -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck %s + +; Test peephole optimization for medium code model (32-bit TOC offsets) +; for loading a value from the constant pool (TOC-relative). + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define double @test_double_const() nounwind { +entry: + ret double 0x3F4FD4920B498CF0 +} + +; CHECK: [[VAR:[a-z0-9A-Z_.]+]]: +; CHECK: .quad 4562098671269285104 +; CHECK: test_double_const: +; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR]]@toc@ha +; CHECK: lfd {{[0-9]+}}, [[VAR]]@toc@l([[REG1]]) diff --git a/test/CodeGen/PowerPC/mcm-2.ll b/test/CodeGen/PowerPC/mcm-2.ll index 45df0ab14f..f0dff4c5a3 100644 --- a/test/CodeGen/PowerPC/mcm-2.ll +++ b/test/CodeGen/PowerPC/mcm-2.ll @@ -1,6 +1,7 @@ -; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck -check-prefix=MEDIUM %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck -check-prefix=LARGE %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading and storing a static variable scoped to a function. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" @@ -16,11 +17,21 @@ entry: ret i32 %0 } -; CHECK: test_fn_static: -; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha -; CHECK: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l -; CHECK: lwz {{[0-9]+}}, 0([[REG2]]) -; CHECK: stw {{[0-9]+}}, 0([[REG2]]) -; CHECK: .type [[VAR]],@object -; CHECK: .local [[VAR]] -; CHECK: .comm [[VAR]],4,4 +; MEDIUM: test_fn_static: +; MEDIUM: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; MEDIUM: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l +; MEDIUM: lwz {{[0-9]+}}, 0([[REG2]]) +; MEDIUM: stw {{[0-9]+}}, 0([[REG2]]) +; MEDIUM: .type [[VAR]],@object +; MEDIUM: .local [[VAR]] +; MEDIUM: .comm [[VAR]],4,4 + +; LARGE: test_fn_static: +; LARGE: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; LARGE: ld [[REG2:[0-9]+]], [[VAR]]@toc@l([[REG1]]) +; LARGE: lwz {{[0-9]+}}, 0([[REG2]]) +; LARGE: stw {{[0-9]+}}, 0([[REG2]]) +; LARGE: .type [[VAR]],@object +; LARGE: .local [[VAR]] +; LARGE: .comm [[VAR]],4,4 + diff --git a/test/CodeGen/PowerPC/mcm-3.ll b/test/CodeGen/PowerPC/mcm-3.ll index 0e7bbe798b..b7905503f4 100644 --- a/test/CodeGen/PowerPC/mcm-3.ll +++ b/test/CodeGen/PowerPC/mcm-3.ll @@ -1,6 +1,7 @@ -; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck -check-prefix=MEDIUM %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck -check-prefix=LARGE %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading and storing a file-scope static variable. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" @@ -16,13 +17,25 @@ entry: ret i32 %0 } -; CHECK: test_file_static: -; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha -; CHECK: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l -; CHECK: lwz {{[0-9]+}}, 0([[REG2]]) -; CHECK: stw {{[0-9]+}}, 0([[REG2]]) -; CHECK: .type [[VAR]],@object -; CHECK: .data -; CHECK: .globl [[VAR]] -; CHECK: [[VAR]]: -; CHECK: .long 5 +; MEDIUM: test_file_static: +; MEDIUM: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; MEDIUM: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l +; MEDIUM: lwz {{[0-9]+}}, 0([[REG2]]) +; MEDIUM: stw {{[0-9]+}}, 0([[REG2]]) +; MEDIUM: .type [[VAR]],@object +; MEDIUM: .data +; MEDIUM: .globl [[VAR]] +; MEDIUM: [[VAR]]: +; MEDIUM: .long 5 + +; LARGE: test_file_static: +; LARGE: addis [[REG1:[0-9]+]], 2, [[VAR:[a-z0-9A-Z_.]+]]@toc@ha +; LARGE: ld [[REG2:[0-9]+]], [[VAR]]@toc@l([[REG1]]) +; LARGE: lwz {{[0-9]+}}, 0([[REG2]]) +; LARGE: stw {{[0-9]+}}, 0([[REG2]]) +; LARGE: .type [[VAR]],@object +; LARGE: .data +; LARGE: .globl [[VAR]] +; LARGE: [[VAR]]: +; LARGE: .long 5 + diff --git a/test/CodeGen/PowerPC/mcm-4.ll b/test/CodeGen/PowerPC/mcm-4.ll index db36d0bcf7..47c60c9360 100644 --- a/test/CodeGen/PowerPC/mcm-4.ll +++ b/test/CodeGen/PowerPC/mcm-4.ll @@ -1,6 +1,7 @@ -; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck -check-prefix=MEDIUM %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck -check-prefix=LARGE %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading a value from the constant pool (TOC-relative). target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" @@ -11,9 +12,16 @@ entry: ret double 0x3F4FD4920B498CF0 } -; CHECK: [[VAR:[a-z0-9A-Z_.]+]]: -; CHECK: .quad 4562098671269285104 -; CHECK: test_double_const: -; CHECK: addis [[REG1:[0-9]+]], 2, [[VAR]]@toc@ha -; CHECK: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l -; CHECK: lfd {{[0-9]+}}, 0([[REG2]]) +; MEDIUM: [[VAR:[a-z0-9A-Z_.]+]]: +; MEDIUM: .quad 4562098671269285104 +; MEDIUM: test_double_const: +; MEDIUM: addis [[REG1:[0-9]+]], 2, [[VAR]]@toc@ha +; MEDIUM: addi [[REG2:[0-9]+]], [[REG1]], [[VAR]]@toc@l +; MEDIUM: lfd {{[0-9]+}}, 0([[REG2]]) + +; LARGE: [[VAR:[a-z0-9A-Z_.]+]]: +; LARGE: .quad 4562098671269285104 +; LARGE: test_double_const: +; LARGE: addis [[REG1:[0-9]+]], 2, [[VAR]]@toc@ha +; LARGE: ld [[REG2:[0-9]+]], [[VAR]]@toc@l([[REG1]]) +; LARGE: lfd {{[0-9]+}}, 0([[REG2]]) diff --git a/test/CodeGen/PowerPC/mcm-5.ll b/test/CodeGen/PowerPC/mcm-5.ll index 10d89f5215..1be27b7e8c 100644 --- a/test/CodeGen/PowerPC/mcm-5.ll +++ b/test/CodeGen/PowerPC/mcm-5.ll @@ -1,6 +1,7 @@ ; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading the address of a jump table from the TOC. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" diff --git a/test/CodeGen/PowerPC/mcm-6.ll b/test/CodeGen/PowerPC/mcm-6.ll index 0a7fa762d4..35efaaa562 100644 --- a/test/CodeGen/PowerPC/mcm-6.ll +++ b/test/CodeGen/PowerPC/mcm-6.ll @@ -1,6 +1,7 @@ ; RUN: llc -mcpu=pwr7 -O0 -code-model=medium < %s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large < %s | FileCheck %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading and storing a tentatively defined variable. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" diff --git a/test/CodeGen/PowerPC/mcm-7.ll b/test/CodeGen/PowerPC/mcm-7.ll index 0e9fa2b38b..0dd39ee410 100644 --- a/test/CodeGen/PowerPC/mcm-7.ll +++ b/test/CodeGen/PowerPC/mcm-7.ll @@ -1,6 +1,7 @@ ; RUN: llc -mcpu=pwr7 -O0 -code-model=medium < %s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large < %s | FileCheck %s -; Test correct code generation for medium code model (32-bit TOC offsets) +; Test correct code generation for medium and large code model ; for loading a function address. target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" diff --git a/test/CodeGen/PowerPC/mcm-8.ll b/test/CodeGen/PowerPC/mcm-8.ll new file mode 100644 index 0000000000..3ece786d64 --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-8.ll @@ -0,0 +1,25 @@ +; RUN: llc -mcpu=pwr7 -O0 -code-model=medium < %s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large < %s | FileCheck %s + +; Test correct code generation for medium and large code model +; for loading a variable with available-externally linkage. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@x = available_externally constant [13 x i8] c"St9bad_alloc\00" + +define signext i8 @test_avext() nounwind { +entry: + %0 = getelementptr inbounds [13 x i8]* @x, i32 0, i32 0 + %1 = load i8* %0, align 1 + ret i8 %1 +} + +; CHECK: test_avext: +; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha +; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) +; CHECK: lbz {{[0-9]+}}, 0([[REG2]]) +; CHECK: .section .toc +; CHECK: .LC[[TOCNUM]]: +; CHECK: .tc {{[a-z0-9A-Z_.]+}}[TC],{{[a-z0-9A-Z_.]+}} diff --git a/test/CodeGen/PowerPC/mcm-9.ll b/test/CodeGen/PowerPC/mcm-9.ll new file mode 100644 index 0000000000..f366f45cc8 --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-9.ll @@ -0,0 +1,28 @@ +; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s +; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck %s + +; Test correct code generation for medium and large code model +; for loading and storing an aliased external variable. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@ei = external global i32 +@a = alias i32* @ei + +define signext i32 @test_external() nounwind { +entry: + %0 = load i32* @a, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @a, align 4 + ret i32 %0 +} + +; CHECK: test_external: +; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha +; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) +; CHECK: lwz {{[0-9]+}}, 0([[REG2]]) +; CHECK: stw {{[0-9]+}}, 0([[REG2]]) +; CHECK: .section .toc +; CHECK: .LC[[TOCNUM]]: +; CHECK: .tc {{[a-z0-9A-Z_.]+}}[TC],{{[a-z0-9A-Z_.]+}} diff --git a/test/CodeGen/PowerPC/mcm-obj-2.ll b/test/CodeGen/PowerPC/mcm-obj-2.ll new file mode 100644 index 0000000000..2dd1718ba7 --- /dev/null +++ b/test/CodeGen/PowerPC/mcm-obj-2.ll @@ -0,0 +1,77 @@ +; RUN: llc -O1 -mcpu=pwr7 -code-model=medium -filetype=obj %s -o - | \ +; RUN: elf-dump --dump-section-data | FileCheck %s + +; FIXME: When asm-parse is available, could make this an assembly test. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@test_fn_static.si = internal global i32 0, align 4 + +define signext i32 @test_fn_static() nounwind { +entry: + %0 = load i32* @test_fn_static.si, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @test_fn_static.si, align 4 + ret i32 %0 +} + +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for +; accessing function-scoped variable si. +; +; CHECK: Relocation 0 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM2:[0-9]+]] +; CHECK-NEXT: 'r_type', 0x00000032 +; CHECK: Relocation 1 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM2]] +; CHECK-NEXT: 'r_type', 0x00000030 +; CHECK: Relocation 2 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM2]] +; CHECK-NEXT: 'r_type', 0x00000030 + +@gi = global i32 5, align 4 + +define signext i32 @test_file_static() nounwind { +entry: + %0 = load i32* @gi, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @gi, align 4 + ret i32 %0 +} + +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for +; accessing file-scope variable gi. +; +; CHECK: Relocation 3 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM3:[0-9]+]] +; CHECK-NEXT: 'r_type', 0x00000032 +; CHECK: Relocation 4 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM3]] +; CHECK-NEXT: 'r_type', 0x00000030 +; CHECK: Relocation 5 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM3]] +; CHECK-NEXT: 'r_type', 0x00000030 + +define double @test_double_const() nounwind { +entry: + ret double 0x3F4FD4920B498CF0 +} + +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for +; accessing a constant. +; +; CHECK: Relocation 6 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM4:[0-9]+]] +; CHECK-NEXT: 'r_type', 0x00000032 +; CHECK: Relocation 7 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM4]] +; CHECK-NEXT: 'r_type', 0x00000030 + diff --git a/test/CodeGen/PowerPC/mcm-obj.ll b/test/CodeGen/PowerPC/mcm-obj.ll index ec1b7b0084..117c3b3343 100644 --- a/test/CodeGen/PowerPC/mcm-obj.ll +++ b/test/CodeGen/PowerPC/mcm-obj.ll @@ -1,5 +1,7 @@ ; RUN: llc -O0 -mcpu=pwr7 -code-model=medium -filetype=obj %s -o - | \ -; RUN: elf-dump --dump-section-data | FileCheck %s +; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=MEDIUM %s +; RUN: llc -O0 -mcpu=pwr7 -code-model=large -filetype=obj %s -o - | \ +; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=LARGE %s ; FIXME: When asm-parse is available, could make this an assembly test. @@ -19,15 +21,25 @@ entry: ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for ; accessing external variable ei. ; -; CHECK: '.rela.text' -; CHECK: Relocation 0 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 1 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM1]] -; CHECK-NEXT: 'r_type', 0x00000040 +; MEDIUM: '.rela.text' +; MEDIUM: Relocation 0 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM1:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 1 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM1]] +; MEDIUM-NEXT: 'r_type', 0x00000040 +; +; LARGE: '.rela.text' +; LARGE: Relocation 0 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM1:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 1 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM1]] +; LARGE-NEXT: 'r_type', 0x00000040 @test_fn_static.si = internal global i32 0, align 4 @@ -42,14 +54,26 @@ entry: ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for ; accessing function-scoped variable si. ; -; CHECK: Relocation 2 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM2:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 3 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM2]] -; CHECK-NEXT: 'r_type', 0x00000030 +; MEDIUM: Relocation 2 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM2:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 3 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM2]] +; MEDIUM-NEXT: 'r_type', 0x00000030 +; +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for +; accessing function-scoped variable si. +; +; LARGE: Relocation 2 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM2:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 3 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM2]] +; LARGE-NEXT: 'r_type', 0x00000040 @gi = global i32 5, align 4 @@ -64,14 +88,26 @@ entry: ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for ; accessing file-scope variable gi. ; -; CHECK: Relocation 4 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM3:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 5 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM3]] -; CHECK-NEXT: 'r_type', 0x00000030 +; MEDIUM: Relocation 4 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM3:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 5 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM3]] +; MEDIUM-NEXT: 'r_type', 0x00000030 +; +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for +; accessing file-scope variable gi. +; +; LARGE: Relocation 4 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM3:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 5 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM3]] +; LARGE-NEXT: 'r_type', 0x00000040 define double @test_double_const() nounwind { entry: @@ -81,14 +117,26 @@ entry: ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO for ; accessing a constant. ; -; CHECK: Relocation 6 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM4:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 7 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM4]] -; CHECK-NEXT: 'r_type', 0x00000030 +; MEDIUM: Relocation 6 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM4:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 7 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM4]] +; MEDIUM-NEXT: 'r_type', 0x00000030 +; +; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for +; accessing a constant. +; +; LARGE: Relocation 6 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM4:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 7 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM4]] +; LARGE-NEXT: 'r_type', 0x00000040 define signext i32 @test_jump_table(i32 signext %i) nounwind { entry: @@ -137,14 +185,23 @@ sw.epilog: ; preds = %sw.bb3, %sw.default ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for ; accessing a jump table address. ; -; CHECK: Relocation 8 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM5:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 9 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM5]] -; CHECK-NEXT: 'r_type', 0x00000040 +; MEDIUM: Relocation 8 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM5:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 9 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM5]] +; MEDIUM-NEXT: 'r_type', 0x00000040 +; +; LARGE: Relocation 8 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM5:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 9 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM5]] +; LARGE-NEXT: 'r_type', 0x00000040 @ti = common global i32 0, align 4 @@ -159,14 +216,23 @@ entry: ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for ; accessing tentatively declared variable ti. ; -; CHECK: Relocation 10 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM6:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 11 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM6]] -; CHECK-NEXT: 'r_type', 0x00000040 +; MEDIUM: Relocation 10 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM6:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 11 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM6]] +; MEDIUM-NEXT: 'r_type', 0x00000040 +; +; LARGE: Relocation 10 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM6:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 11 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM6]] +; LARGE-NEXT: 'r_type', 0x00000040 define i8* @test_fnaddr() nounwind { entry: @@ -182,12 +248,21 @@ declare signext i32 @foo(i32 signext) ; Verify generation of R_PPC64_TOC16_HA and R_PPC64_TOC16_LO_DS for ; accessing function address foo. ; -; CHECK: Relocation 12 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM7:[0-9]+]] -; CHECK-NEXT: 'r_type', 0x00000032 -; CHECK: Relocation 13 -; CHECK-NEXT: 'r_offset' -; CHECK-NEXT: 'r_sym', 0x[[SYM7]] -; CHECK-NEXT: 'r_type', 0x00000040 +; MEDIUM: Relocation 12 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM7:[0-9]+]] +; MEDIUM-NEXT: 'r_type', 0x00000032 +; MEDIUM: Relocation 13 +; MEDIUM-NEXT: 'r_offset' +; MEDIUM-NEXT: 'r_sym', 0x[[SYM7]] +; MEDIUM-NEXT: 'r_type', 0x00000040 +; +; LARGE: Relocation 12 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM7:[0-9]+]] +; LARGE-NEXT: 'r_type', 0x00000032 +; LARGE: Relocation 13 +; LARGE-NEXT: 'r_offset' +; LARGE-NEXT: 'r_sym', 0x[[SYM7]] +; LARGE-NEXT: 'r_type', 0x00000040 diff --git a/test/CodeGen/PowerPC/misched-inorder-latency.ll b/test/CodeGen/PowerPC/misched-inorder-latency.ll new file mode 100644 index 0000000000..8fae7ad4d1 --- /dev/null +++ b/test/CodeGen/PowerPC/misched-inorder-latency.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -enable-misched -pre-RA-sched=source -scheditins=false \ +; RUN: -disable-ifcvt-triangle-false -disable-post-ra | FileCheck %s +; +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-bgq-linux" + +; %val1 is a load live out of %entry. It should be hoisted +; above the add. +; CHECK: testload: +; CHECK: %entry +; CHECK: lwz +; CHECK: addi +; CHECK: bne +; CHECK: %true +define i32 @testload(i32 *%ptr, i32 %sumin) { +entry: + %sum1 = add i32 %sumin, 1 + %val1 = load i32* %ptr + %p = icmp eq i32 %sumin, 0 + br i1 %p, label %true, label %end +true: + %sum2 = add i32 %sum1, 1 + %ptr2 = getelementptr i32* %ptr, i32 1 + %val = load i32* %ptr2 + %val2 = add i32 %val1, %val + br label %end +end: + %valmerge = phi i32 [ %val1, %entry], [ %val2, %true ] + %summerge = phi i32 [ %sum1, %entry], [ %sum2, %true ] + %sumout = add i32 %valmerge, %summerge + ret i32 %sumout +} + +; The prefetch gets a default latency of 3 cycles and should be hoisted +; above the add. +; +; CHECK: testprefetch: +; CHECK: %entry +; CHECK: dcbt +; CHECK: addi +; CHECK: blr +define i32 @testprefetch(i8 *%ptr, i32 %i) { +entry: + %val1 = add i32 %i, 1 + tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 3, i32 1 ) + %p = icmp eq i32 %i, 0 + br i1 %p, label %true, label %end +true: + %val2 = add i32 %val1, 1 + br label %end +end: + %valmerge = phi i32 [ %val1, %entry], [ %val2, %true ] + ret i32 %valmerge +} +declare void @llvm.prefetch(i8*, i32, i32, i32) nounwind diff --git a/test/CodeGen/PowerPC/pr15031.ll b/test/CodeGen/PowerPC/pr15031.ll new file mode 100644 index 0000000000..5ccf941a1f --- /dev/null +++ b/test/CodeGen/PowerPC/pr15031.ll @@ -0,0 +1,370 @@ +; RUN: llc -mcpu=pwr7 -O3 < %s | FileCheck %s + +; Test case derived from bug report 15031. The code in the post-RA +; scheduler to break critical anti-dependencies was failing to check +; whether an instruction had more than one definition, and ensuring +; that any additional definitions interfered with the choice of a new +; register. As a result, this test originally caused this to be +; generated: +; +; lbzu 3, 1(3) +; +; which is illegal, since it requires register 3 to both receive the +; loaded value and receive the updated address. With the fix to bug +; 15031, a different register is chosen to receive the loaded value. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +%"class.llvm::MachineMemOperand" = type { %"struct.llvm::MachinePointerInfo", i64, i32, %"class.llvm::MDNode"*, %"class.llvm::MDNode"* } +%"struct.llvm::MachinePointerInfo" = type { %"class.llvm::Value"*, i64 } +%"class.llvm::Value" = type { i32 (...)**, i8, i8, i16, %"class.llvm::Type"*, %"class.llvm::Use"*, %"class.llvm::StringMapEntry"* } +%"class.llvm::Type" = type { %"class.llvm::LLVMContext"*, i32, i32, %"class.llvm::Type"** } +%"class.llvm::LLVMContext" = type { %"class.llvm::LLVMContextImpl"* } +%"class.llvm::LLVMContextImpl" = type opaque +%"class.llvm::Use" = type { %"class.llvm::Value"*, %"class.llvm::Use"*, %"class.llvm::PointerIntPair" } +%"class.llvm::PointerIntPair" = type { i64 } +%"class.llvm::StringMapEntry" = type opaque +%"class.llvm::MDNode" = type { %"class.llvm::Value", %"class.llvm::FoldingSetImpl::Node", i32, i32 } +%"class.llvm::FoldingSetImpl::Node" = type { i8* } +%"class.llvm::MachineInstr" = type { %"class.llvm::ilist_node", %"class.llvm::MCInstrDesc"*, %"class.llvm::MachineBasicBlock"*, %"class.llvm::MachineOperand"*, i32, %"class.llvm::ArrayRecycler<llvm::MachineOperand, 8>::Capacity", i8, i8, i8, %"class.llvm::MachineMemOperand"**, %"class.llvm::DebugLoc" } +%"class.llvm::ilist_node" = type { %"class.llvm::ilist_half_node", %"class.llvm::MachineInstr"* } +%"class.llvm::ilist_half_node" = type { %"class.llvm::MachineInstr"* } +%"class.llvm::MCInstrDesc" = type { i16, i16, i16, i16, i16, i32, i64, i16*, i16*, %"class.llvm::MCOperandInfo"* } +%"class.llvm::MCOperandInfo" = type { i16, i8, i8, i32 } +%"class.llvm::MachineBasicBlock" = type { %"class.llvm::ilist_node.0", %"struct.llvm::ilist", %"class.llvm::BasicBlock"*, i32, %"class.llvm::MachineFunction"*, %"class.std::vector.163", %"class.std::vector.163", %"class.std::vector.123", %"class.std::vector.123", i32, i8, i8 } +%"class.llvm::ilist_node.0" = type { %"class.llvm::ilist_half_node.1", %"class.llvm::MachineBasicBlock"* } +%"class.llvm::ilist_half_node.1" = type { %"class.llvm::MachineBasicBlock"* } +%"struct.llvm::ilist" = type { %"class.llvm::iplist" } +%"class.llvm::iplist" = type { %"struct.llvm::ilist_traits", %"class.llvm::MachineInstr"* } +%"struct.llvm::ilist_traits" = type { %"class.llvm::ilist_half_node", %"class.llvm::MachineBasicBlock"* } +%"class.llvm::BasicBlock" = type { %"class.llvm::Value", %"class.llvm::ilist_node.2", %"class.llvm::iplist.4", %"class.llvm::Function"* } +%"class.llvm::ilist_node.2" = type { %"class.llvm::ilist_half_node.3", %"class.llvm::BasicBlock"* } +%"class.llvm::ilist_half_node.3" = type { %"class.llvm::BasicBlock"* } +%"class.llvm::iplist.4" = type { %"struct.llvm::ilist_traits.5", %"class.llvm::Instruction"* } +%"struct.llvm::ilist_traits.5" = type { %"class.llvm::ilist_half_node.10" } +%"class.llvm::ilist_half_node.10" = type { %"class.llvm::Instruction"* } +%"class.llvm::Instruction" = type { %"class.llvm::User", %"class.llvm::ilist_node.193", %"class.llvm::BasicBlock"*, %"class.llvm::DebugLoc" } +%"class.llvm::User" = type { %"class.llvm::Value", %"class.llvm::Use"*, i32 } +%"class.llvm::ilist_node.193" = type { %"class.llvm::ilist_half_node.10", %"class.llvm::Instruction"* } +%"class.llvm::DebugLoc" = type { i32, i32 } +%"class.llvm::Function" = type { %"class.llvm::GlobalValue", %"class.llvm::ilist_node.27", %"class.llvm::iplist.47", %"class.llvm::iplist.54", %"class.llvm::ValueSymbolTable"*, %"class.llvm::AttributeSet" } +%"class.llvm::GlobalValue" = type { [52 x i8], [4 x i8], %"class.llvm::Module"*, %"class.std::basic_string" } +%"class.llvm::Module" = type { %"class.llvm::LLVMContext"*, %"class.llvm::iplist.11", %"class.llvm::iplist.20", %"class.llvm::iplist.29", %"struct.llvm::ilist.38", %"class.std::basic_string", %"class.llvm::ValueSymbolTable"*, %"class.llvm::OwningPtr", %"class.std::basic_string", %"class.std::basic_string", %"class.std::basic_string", i8* } +%"class.llvm::iplist.11" = type { %"struct.llvm::ilist_traits.12", %"class.llvm::GlobalVariable"* } +%"struct.llvm::ilist_traits.12" = type { %"class.llvm::ilist_node.18" } +%"class.llvm::ilist_node.18" = type { %"class.llvm::ilist_half_node.19", %"class.llvm::GlobalVariable"* } +%"class.llvm::ilist_half_node.19" = type { %"class.llvm::GlobalVariable"* } +%"class.llvm::GlobalVariable" = type { %"class.llvm::GlobalValue", %"class.llvm::ilist_node.18", i8 } +%"class.llvm::iplist.20" = type { %"struct.llvm::ilist_traits.21", %"class.llvm::Function"* } +%"struct.llvm::ilist_traits.21" = type { %"class.llvm::ilist_node.27" } +%"class.llvm::ilist_node.27" = type { %"class.llvm::ilist_half_node.28", %"class.llvm::Function"* } +%"class.llvm::ilist_half_node.28" = type { %"class.llvm::Function"* } +%"class.llvm::iplist.29" = type { %"struct.llvm::ilist_traits.30", %"class.llvm::GlobalAlias"* } +%"struct.llvm::ilist_traits.30" = type { %"class.llvm::ilist_node.36" } +%"class.llvm::ilist_node.36" = type { %"class.llvm::ilist_half_node.37", %"class.llvm::GlobalAlias"* } +%"class.llvm::ilist_half_node.37" = type { %"class.llvm::GlobalAlias"* } +%"class.llvm::GlobalAlias" = type { %"class.llvm::GlobalValue", %"class.llvm::ilist_node.36" } +%"struct.llvm::ilist.38" = type { %"class.llvm::iplist.39" } +%"class.llvm::iplist.39" = type { %"struct.llvm::ilist_traits.40", %"class.llvm::NamedMDNode"* } +%"struct.llvm::ilist_traits.40" = type { %"class.llvm::ilist_node.45" } +%"class.llvm::ilist_node.45" = type { %"class.llvm::ilist_half_node.46", %"class.llvm::NamedMDNode"* } +%"class.llvm::ilist_half_node.46" = type { %"class.llvm::NamedMDNode"* } +%"class.llvm::NamedMDNode" = type { %"class.llvm::ilist_node.45", %"class.std::basic_string", %"class.llvm::Module"*, i8* } +%"class.std::basic_string" = type { %"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" } +%"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* } +%"class.llvm::ValueSymbolTable" = type opaque +%"class.llvm::OwningPtr" = type { %"class.llvm::GVMaterializer"* } +%"class.llvm::GVMaterializer" = type opaque +%"class.llvm::iplist.47" = type { %"struct.llvm::ilist_traits.48", %"class.llvm::BasicBlock"* } +%"struct.llvm::ilist_traits.48" = type { %"class.llvm::ilist_half_node.3" } +%"class.llvm::iplist.54" = type { %"struct.llvm::ilist_traits.55", %"class.llvm::Argument"* } +%"struct.llvm::ilist_traits.55" = type { %"class.llvm::ilist_half_node.61" } +%"class.llvm::ilist_half_node.61" = type { %"class.llvm::Argument"* } +%"class.llvm::Argument" = type { %"class.llvm::Value", %"class.llvm::ilist_node.192", %"class.llvm::Function"* } +%"class.llvm::ilist_node.192" = type { %"class.llvm::ilist_half_node.61", %"class.llvm::Argument"* } +%"class.llvm::AttributeSet" = type { %"class.llvm::AttributeSetImpl"* } +%"class.llvm::AttributeSetImpl" = type opaque +%"class.llvm::MachineFunction" = type { %"class.llvm::Function"*, %"class.llvm::TargetMachine"*, %"class.llvm::MCContext"*, %"class.llvm::MachineModuleInfo"*, %"class.llvm::GCModuleInfo"*, %"class.llvm::MachineRegisterInfo"*, %"struct.llvm::MachineFunctionInfo"*, %"class.llvm::MachineFrameInfo"*, %"class.llvm::MachineConstantPool"*, %"class.llvm::MachineJumpTableInfo"*, %"class.std::vector.163", %"class.llvm::BumpPtrAllocator", %"class.llvm::Recycler", %"class.llvm::ArrayRecycler", %"class.llvm::Recycler.180", %"struct.llvm::ilist.181", i32, i32, i8 } +%"class.llvm::TargetMachine" = type { i32 (...)**, %"class.llvm::Target"*, %"class.std::basic_string", %"class.std::basic_string", %"class.std::basic_string", %"class.llvm::MCCodeGenInfo"*, %"class.llvm::MCAsmInfo"*, i8, %"class.llvm::TargetOptions" } +%"class.llvm::Target" = type opaque +%"class.llvm::MCCodeGenInfo" = type opaque +%"class.llvm::MCAsmInfo" = type opaque +%"class.llvm::TargetOptions" = type { [2 x i8], i32, i8, i32, i8, %"class.std::basic_string", i32, i32 } +%"class.llvm::MCContext" = type { %"class.llvm::SourceMgr"*, %"class.llvm::MCAsmInfo"*, %"class.llvm::MCRegisterInfo"*, %"class.llvm::MCObjectFileInfo"*, %"class.llvm::BumpPtrAllocator", %"class.llvm::StringMap", %"class.llvm::StringMap.62", i32, %"class.llvm::DenseMap.63", i8*, %"class.llvm::raw_ostream"*, i8, %"class.std::basic_string", %"class.std::basic_string", %"class.std::vector", %"class.std::vector.70", %"class.llvm::MCDwarfLoc", i8, i8, i32, %"class.llvm::MCSection"*, %"class.llvm::MCSymbol"*, %"class.llvm::MCSymbol"*, %"class.std::vector.75", %"class.llvm::StringRef", %"class.llvm::StringRef", i8, %"class.llvm::DenseMap.80", %"class.std::vector.84", i8*, i8*, i8*, i8 } +%"class.llvm::SourceMgr" = type opaque +%"class.llvm::MCRegisterInfo" = type { %"struct.llvm::MCRegisterDesc"*, i32, i32, i32, %"class.llvm::MCRegisterClass"*, i32, i32, [2 x i16]*, i16*, i8*, i16*, i32, i16*, i32, i32, i32, i32, %"struct.llvm::MCRegisterInfo::DwarfLLVMRegPair"*, %"struct.llvm::MCRegisterInfo::DwarfLLVMRegPair"*, %"struct.llvm::MCRegisterInfo::DwarfLLVMRegPair"*, %"struct.llvm::MCRegisterInfo::DwarfLLVMRegPair"*, %"class.llvm::DenseMap" } +%"struct.llvm::MCRegisterDesc" = type { i32, i32, i32, i32, i32, i32 } +%"class.llvm::MCRegisterClass" = type { i8*, i16*, i8*, i16, i16, i16, i16, i16, i8, i8 } +%"struct.llvm::MCRegisterInfo::DwarfLLVMRegPair" = type { i32, i32 } +%"class.llvm::DenseMap" = type { %"struct.std::pair"*, i32, i32, i32 } +%"struct.std::pair" = type { i32, i32 } +%"class.llvm::MCObjectFileInfo" = type opaque +%"class.llvm::BumpPtrAllocator" = type { i64, i64, %"class.llvm::SlabAllocator"*, %"class.llvm::MemSlab"*, i8*, i8*, i64 } +%"class.llvm::SlabAllocator" = type { i32 (...)** } +%"class.llvm::MemSlab" = type { i64, %"class.llvm::MemSlab"* } +%"class.llvm::StringMap" = type { %"class.llvm::StringMapImpl", %"class.llvm::BumpPtrAllocator"* } +%"class.llvm::StringMapImpl" = type { %"class.llvm::StringMapEntryBase"**, i32, i32, i32, i32 } +%"class.llvm::StringMapEntryBase" = type { i32 } +%"class.llvm::StringMap.62" = type { %"class.llvm::StringMapImpl", %"class.llvm::BumpPtrAllocator"* } +%"class.llvm::DenseMap.63" = type { %"struct.std::pair.66"*, i32, i32, i32 } +%"struct.std::pair.66" = type opaque +%"class.llvm::raw_ostream" = type { i32 (...)**, i8*, i8*, i8*, i32 } +%"class.std::vector" = type { %"struct.std::_Vector_base" } +%"struct.std::_Vector_base" = type { %"struct.std::_Vector_base<llvm::MCDwarfFile *, std::allocator<llvm::MCDwarfFile *> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::MCDwarfFile *, std::allocator<llvm::MCDwarfFile *> >::_Vector_impl" = type { %"class.llvm::MCDwarfFile"**, %"class.llvm::MCDwarfFile"**, %"class.llvm::MCDwarfFile"** } +%"class.llvm::MCDwarfFile" = type { %"class.llvm::StringRef", i32 } +%"class.llvm::StringRef" = type { i8*, i64 } +%"class.std::vector.70" = type { %"struct.std::_Vector_base.71" } +%"struct.std::_Vector_base.71" = type { %"struct.std::_Vector_base<llvm::StringRef, std::allocator<llvm::StringRef> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::StringRef, std::allocator<llvm::StringRef> >::_Vector_impl" = type { %"class.llvm::StringRef"*, %"class.llvm::StringRef"*, %"class.llvm::StringRef"* } +%"class.llvm::MCDwarfLoc" = type { i32, i32, i32, i32, i32, i32 } +%"class.llvm::MCSection" = type opaque +%"class.llvm::MCSymbol" = type { %"class.llvm::StringRef", %"class.llvm::MCSection"*, %"class.llvm::MCExpr"*, i8 } +%"class.llvm::MCExpr" = type opaque +%"class.std::vector.75" = type { %"struct.std::_Vector_base.76" } +%"struct.std::_Vector_base.76" = type { %"struct.std::_Vector_base<const llvm::MCGenDwarfLabelEntry *, std::allocator<const llvm::MCGenDwarfLabelEntry *> >::_Vector_impl" } +%"struct.std::_Vector_base<const llvm::MCGenDwarfLabelEntry *, std::allocator<const llvm::MCGenDwarfLabelEntry *> >::_Vector_impl" = type { %"class.llvm::MCGenDwarfLabelEntry"**, %"class.llvm::MCGenDwarfLabelEntry"**, %"class.llvm::MCGenDwarfLabelEntry"** } +%"class.llvm::MCGenDwarfLabelEntry" = type { %"class.llvm::StringRef", i32, i32, %"class.llvm::MCSymbol"* } +%"class.llvm::DenseMap.80" = type { %"struct.std::pair.83"*, i32, i32, i32 } +%"struct.std::pair.83" = type { %"class.llvm::MCSection"*, %"class.llvm::MCLineSection"* } +%"class.llvm::MCLineSection" = type { %"class.std::vector.215" } +%"class.std::vector.215" = type { %"struct.std::_Vector_base.216" } +%"struct.std::_Vector_base.216" = type { %"struct.std::_Vector_base<llvm::MCLineEntry, std::allocator<llvm::MCLineEntry> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::MCLineEntry, std::allocator<llvm::MCLineEntry> >::_Vector_impl" = type { %"class.llvm::MCLineEntry"*, %"class.llvm::MCLineEntry"*, %"class.llvm::MCLineEntry"* } +%"class.llvm::MCLineEntry" = type { %"class.llvm::MCDwarfLoc", %"class.llvm::MCSymbol"* } +%"class.std::vector.84" = type { %"struct.std::_Vector_base.85" } +%"struct.std::_Vector_base.85" = type { %"struct.std::_Vector_base<const llvm::MCSection *, std::allocator<const llvm::MCSection *> >::_Vector_impl" } +%"struct.std::_Vector_base<const llvm::MCSection *, std::allocator<const llvm::MCSection *> >::_Vector_impl" = type { %"class.llvm::MCSection"**, %"class.llvm::MCSection"**, %"class.llvm::MCSection"** } +%"class.llvm::MachineModuleInfo" = type { %"class.llvm::ImmutablePass", %"class.llvm::MCContext", %"class.llvm::Module"*, %"class.llvm::MachineModuleInfoImpl"*, %"class.std::vector.95", i32, %"class.std::vector.100", %"class.llvm::DenseMap.110", %"class.llvm::DenseMap.114", i32, %"class.std::vector.118", %"class.std::vector.123", %"class.std::vector.123", %"class.std::vector.128", %"class.llvm::SmallPtrSet", %"class.llvm::MMIAddrLabelMap"*, i8, i8, i8, i8, %"class.llvm::SmallVector.133" } +%"class.llvm::ImmutablePass" = type { %"class.llvm::ModulePass" } +%"class.llvm::ModulePass" = type { %"class.llvm::Pass" } +%"class.llvm::Pass" = type { i32 (...)**, %"class.llvm::AnalysisResolver"*, i8*, i32 } +%"class.llvm::AnalysisResolver" = type { %"class.std::vector.89", %"class.llvm::PMDataManager"* } +%"class.std::vector.89" = type { %"struct.std::_Vector_base.90" } +%"struct.std::_Vector_base.90" = type { %"struct.std::_Vector_base<std::pair<const void *, llvm::Pass *>, std::allocator<std::pair<const void *, llvm::Pass *> > >::_Vector_impl" } +%"struct.std::_Vector_base<std::pair<const void *, llvm::Pass *>, std::allocator<std::pair<const void *, llvm::Pass *> > >::_Vector_impl" = type { %"struct.std::pair.94"*, %"struct.std::pair.94"*, %"struct.std::pair.94"* } +%"struct.std::pair.94" = type { i8*, %"class.llvm::Pass"* } +%"class.llvm::PMDataManager" = type opaque +%"class.llvm::MachineModuleInfoImpl" = type { i32 (...)** } +%"class.std::vector.95" = type { %"struct.std::_Vector_base.96" } +%"struct.std::_Vector_base.96" = type { %"struct.std::_Vector_base<llvm::MachineMove, std::allocator<llvm::MachineMove> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::MachineMove, std::allocator<llvm::MachineMove> >::_Vector_impl" = type { %"class.llvm::MachineMove"*, %"class.llvm::MachineMove"*, %"class.llvm::MachineMove"* } +%"class.llvm::MachineMove" = type { %"class.llvm::MCSymbol"*, %"class.llvm::MachineLocation", %"class.llvm::MachineLocation" } +%"class.llvm::MachineLocation" = type { i8, i32, i32 } +%"class.std::vector.100" = type { %"struct.std::_Vector_base.101" } +%"struct.std::_Vector_base.101" = type { %"struct.std::_Vector_base<llvm::LandingPadInfo, std::allocator<llvm::LandingPadInfo> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::LandingPadInfo, std::allocator<llvm::LandingPadInfo> >::_Vector_impl" = type { %"struct.llvm::LandingPadInfo"*, %"struct.llvm::LandingPadInfo"*, %"struct.llvm::LandingPadInfo"* } +%"struct.llvm::LandingPadInfo" = type { %"class.llvm::MachineBasicBlock"*, %"class.llvm::SmallVector", %"class.llvm::SmallVector", %"class.llvm::MCSymbol"*, %"class.llvm::Function"*, %"class.std::vector.105" } +%"class.llvm::SmallVector" = type { %"class.llvm::SmallVectorImpl", %"struct.llvm::SmallVectorStorage" } +%"class.llvm::SmallVectorImpl" = type { %"class.llvm::SmallVectorTemplateBase" } +%"class.llvm::SmallVectorTemplateBase" = type { %"class.llvm::SmallVectorTemplateCommon" } +%"class.llvm::SmallVectorTemplateCommon" = type { %"class.llvm::SmallVectorBase", %"struct.llvm::AlignedCharArrayUnion" } +%"class.llvm::SmallVectorBase" = type { i8*, i8*, i8* } +%"struct.llvm::AlignedCharArrayUnion" = type { %"struct.llvm::AlignedCharArray" } +%"struct.llvm::AlignedCharArray" = type { [8 x i8] } +%"struct.llvm::SmallVectorStorage" = type { i8 } +%"class.std::vector.105" = type { %"struct.std::_Vector_base.106" } +%"struct.std::_Vector_base.106" = type { %"struct.std::_Vector_base<int, std::allocator<int> >::_Vector_impl" } +%"struct.std::_Vector_base<int, std::allocator<int> >::_Vector_impl" = type { i32*, i32*, i32* } +%"class.llvm::DenseMap.110" = type { %"struct.std::pair.113"*, i32, i32, i32 } +%"struct.std::pair.113" = type { %"class.llvm::MCSymbol"*, %"class.llvm::SmallVector.206" } +%"class.llvm::SmallVector.206" = type { [28 x i8], %"struct.llvm::SmallVectorStorage.207" } +%"struct.llvm::SmallVectorStorage.207" = type { [3 x %"struct.llvm::AlignedCharArrayUnion.198"] } +%"struct.llvm::AlignedCharArrayUnion.198" = type { %"struct.llvm::AlignedCharArray.199" } +%"struct.llvm::AlignedCharArray.199" = type { [4 x i8] } +%"class.llvm::DenseMap.114" = type { %"struct.std::pair.117"*, i32, i32, i32 } +%"struct.std::pair.117" = type { %"class.llvm::MCSymbol"*, i32 } +%"class.std::vector.118" = type { %"struct.std::_Vector_base.119" } +%"struct.std::_Vector_base.119" = type { %"struct.std::_Vector_base<const llvm::GlobalVariable *, std::allocator<const llvm::GlobalVariable *> >::_Vector_impl" } +%"struct.std::_Vector_base<const llvm::GlobalVariable *, std::allocator<const llvm::GlobalVariable *> >::_Vector_impl" = type { %"class.llvm::GlobalVariable"**, %"class.llvm::GlobalVariable"**, %"class.llvm::GlobalVariable"** } +%"class.std::vector.123" = type { %"struct.std::_Vector_base.124" } +%"struct.std::_Vector_base.124" = type { %"struct.std::_Vector_base<unsigned int, std::allocator<unsigned int> >::_Vector_impl" } +%"struct.std::_Vector_base<unsigned int, std::allocator<unsigned int> >::_Vector_impl" = type { i32*, i32*, i32* } +%"class.std::vector.128" = type { %"struct.std::_Vector_base.129" } +%"struct.std::_Vector_base.129" = type { %"struct.std::_Vector_base<const llvm::Function *, std::allocator<const llvm::Function *> >::_Vector_impl" } +%"struct.std::_Vector_base<const llvm::Function *, std::allocator<const llvm::Function *> >::_Vector_impl" = type { %"class.llvm::Function"**, %"class.llvm::Function"**, %"class.llvm::Function"** } +%"class.llvm::SmallPtrSet" = type { %"class.llvm::SmallPtrSetImpl", [33 x i8*] } +%"class.llvm::SmallPtrSetImpl" = type { i8**, i8**, i32, i32, i32 } +%"class.llvm::MMIAddrLabelMap" = type opaque +%"class.llvm::SmallVector.133" = type { %"class.llvm::SmallVectorImpl.134", %"struct.llvm::SmallVectorStorage.139" } +%"class.llvm::SmallVectorImpl.134" = type { %"class.llvm::SmallVectorTemplateBase.135" } +%"class.llvm::SmallVectorTemplateBase.135" = type { %"class.llvm::SmallVectorTemplateCommon.136" } +%"class.llvm::SmallVectorTemplateCommon.136" = type { %"class.llvm::SmallVectorBase", %"struct.llvm::AlignedCharArrayUnion.137" } +%"struct.llvm::AlignedCharArrayUnion.137" = type { %"struct.llvm::AlignedCharArray.138" } +%"struct.llvm::AlignedCharArray.138" = type { [40 x i8] } +%"struct.llvm::SmallVectorStorage.139" = type { [3 x %"struct.llvm::AlignedCharArrayUnion.137"] } +%"class.llvm::GCModuleInfo" = type opaque +%"class.llvm::MachineRegisterInfo" = type { %"class.llvm::TargetRegisterInfo"*, i8, i8, %"class.llvm::IndexedMap", %"class.llvm::IndexedMap.146", %"class.llvm::MachineOperand"**, %"class.llvm::BitVector", %"class.llvm::BitVector", %"class.llvm::BitVector", %"class.std::vector.147", %"class.std::vector.123" } +%"class.llvm::TargetRegisterInfo" = type { i32 (...)**, %"class.llvm::MCRegisterInfo", %"struct.llvm::TargetRegisterInfoDesc"*, i8**, i32*, %"class.llvm::TargetRegisterClass"**, %"class.llvm::TargetRegisterClass"** } +%"struct.llvm::TargetRegisterInfoDesc" = type { i32, i8 } +%"class.llvm::TargetRegisterClass" = type { %"class.llvm::MCRegisterClass"*, i32*, i32*, i16*, %"class.llvm::TargetRegisterClass"**, void (%"class.llvm::ArrayRef"*, %"class.llvm::MachineFunction"*)* } +%"class.llvm::ArrayRef" = type { i16*, i64 } +%"class.llvm::IndexedMap" = type { %"class.std::vector.140", %"struct.std::pair.145", %"struct.llvm::VirtReg2IndexFunctor" } +%"class.std::vector.140" = type { %"struct.std::_Vector_base.141" } +%"struct.std::_Vector_base.141" = type { %"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass *, llvm::MachineOperand *>, std::allocator<std::pair<const llvm::TargetRegisterClass *, llvm::MachineOperand *> > >::_Vector_impl" } +%"struct.std::_Vector_base<std::pair<const llvm::TargetRegisterClass *, llvm::MachineOperand *>, std::allocator<std::pair<const llvm::TargetRegisterClass *, llvm::MachineOperand *> > >::_Vector_impl" = type { %"struct.std::pair.145"*, %"struct.std::pair.145"*, %"struct.std::pair.145"* } +%"struct.std::pair.145" = type { %"class.llvm::TargetRegisterClass"*, %"class.llvm::MachineOperand"* } +%"class.llvm::MachineOperand" = type { i8, [3 x i8], %union.anon, %"class.llvm::MachineInstr"*, %union.anon.188 } +%union.anon = type { i32 } +%union.anon.188 = type { %struct.anon } +%struct.anon = type { %"class.llvm::MachineOperand"*, %"class.llvm::MachineOperand"* } +%"struct.llvm::VirtReg2IndexFunctor" = type { i8 } +%"class.llvm::IndexedMap.146" = type { %"class.std::vector.147", %"struct.std::pair.152", %"struct.llvm::VirtReg2IndexFunctor" } +%"class.std::vector.147" = type { %"struct.std::_Vector_base.148" } +%"struct.std::_Vector_base.148" = type { %"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int> > >::_Vector_impl" } +%"struct.std::_Vector_base<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int> > >::_Vector_impl" = type { %"struct.std::pair.152"*, %"struct.std::pair.152"*, %"struct.std::pair.152"* } +%"struct.std::pair.152" = type { i32, i32 } +%"class.llvm::BitVector" = type { i64*, i32, i32 } +%"struct.llvm::MachineFunctionInfo" = type { i32 (...)** } +%"class.llvm::MachineFrameInfo" = type opaque +%"class.llvm::MachineConstantPool" = type { %"class.llvm::DataLayout"*, i32, %"class.std::vector.153", %"class.llvm::DenseSet" } +%"class.llvm::DataLayout" = type opaque +%"class.std::vector.153" = type { %"struct.std::_Vector_base.154" } +%"struct.std::_Vector_base.154" = type { %"struct.std::_Vector_base<llvm::MachineConstantPoolEntry, std::allocator<llvm::MachineConstantPoolEntry> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::MachineConstantPoolEntry, std::allocator<llvm::MachineConstantPoolEntry> >::_Vector_impl" = type { %"class.llvm::MachineConstantPoolEntry"*, %"class.llvm::MachineConstantPoolEntry"*, %"class.llvm::MachineConstantPoolEntry"* } +%"class.llvm::MachineConstantPoolEntry" = type { %union.anon.158, i32 } +%union.anon.158 = type { %"class.llvm::Constant"* } +%"class.llvm::Constant" = type { %"class.llvm::User" } +%"class.llvm::DenseSet" = type { %"class.llvm::DenseMap.159" } +%"class.llvm::DenseMap.159" = type { %"struct.std::pair.162"*, i32, i32, i32 } +%"struct.std::pair.162" = type { %"class.llvm::MachineConstantPoolValue"*, i8 } +%"class.llvm::MachineConstantPoolValue" = type { i32 (...)**, %"class.llvm::Type"* } +%"class.llvm::MachineJumpTableInfo" = type opaque +%"class.std::vector.163" = type { %"struct.std::_Vector_base.164" } +%"struct.std::_Vector_base.164" = type { %"struct.std::_Vector_base<llvm::MachineBasicBlock *, std::allocator<llvm::MachineBasicBlock *> >::_Vector_impl" } +%"struct.std::_Vector_base<llvm::MachineBasicBlock *, std::allocator<llvm::MachineBasicBlock *> >::_Vector_impl" = type { %"class.llvm::MachineBasicBlock"**, %"class.llvm::MachineBasicBlock"**, %"class.llvm::MachineBasicBlock"** } +%"class.llvm::Recycler" = type { %"class.llvm::iplist.168" } +%"class.llvm::iplist.168" = type { %"struct.llvm::ilist_traits.169", %"struct.llvm::RecyclerStruct"* } +%"struct.llvm::ilist_traits.169" = type { %"struct.llvm::RecyclerStruct" } +%"struct.llvm::RecyclerStruct" = type { %"struct.llvm::RecyclerStruct"*, %"struct.llvm::RecyclerStruct"* } +%"class.llvm::ArrayRecycler" = type { %"class.llvm::SmallVector.174" } +%"class.llvm::SmallVector.174" = type { %"class.llvm::SmallVectorImpl.175", %"struct.llvm::SmallVectorStorage.179" } +%"class.llvm::SmallVectorImpl.175" = type { %"class.llvm::SmallVectorTemplateBase.176" } +%"class.llvm::SmallVectorTemplateBase.176" = type { %"class.llvm::SmallVectorTemplateCommon.177" } +%"class.llvm::SmallVectorTemplateCommon.177" = type { %"class.llvm::SmallVectorBase", %"struct.llvm::AlignedCharArrayUnion.178" } +%"struct.llvm::AlignedCharArrayUnion.178" = type { %"struct.llvm::AlignedCharArray" } +%"struct.llvm::SmallVectorStorage.179" = type { [7 x %"struct.llvm::AlignedCharArrayUnion.178"] } +%"class.llvm::Recycler.180" = type { %"class.llvm::iplist.168" } +%"struct.llvm::ilist.181" = type { %"class.llvm::iplist.182" } +%"class.llvm::iplist.182" = type { %"struct.llvm::ilist_traits.183", %"class.llvm::MachineBasicBlock"* } +%"struct.llvm::ilist_traits.183" = type { %"class.llvm::ilist_half_node.1" } +%"class.llvm::ArrayRecycler<llvm::MachineOperand, 8>::Capacity" = type { i8 } +%"class.llvm::ConstantInt" = type { %"class.llvm::Constant", %"class.llvm::APInt" } +%"class.llvm::APInt" = type { i32, %union.anon.189 } +%union.anon.189 = type { i64 } +%"class.llvm::ConstantFP" = type { %"class.llvm::Constant", %"class.llvm::APFloat" } +%"class.llvm::APFloat" = type { %"struct.llvm::fltSemantics"*, %"union.llvm::APFloat::Significand", i16, i8 } +%"struct.llvm::fltSemantics" = type opaque +%"union.llvm::APFloat::Significand" = type { i64 } +%"class.llvm::BlockAddress" = type { %"class.llvm::Constant" } +%"class.llvm::hash_code" = type { i64 } +%"struct.llvm::hashing::detail::hash_combine_recursive_helper" = type { [64 x i8], %"struct.llvm::hashing::detail::hash_state", i64 } +%"struct.llvm::hashing::detail::hash_state" = type { i64, i64, i64, i64, i64, i64, i64, i64 } +%"class.llvm::PrintReg" = type { %"class.llvm::TargetRegisterInfo"*, i32, i32 } +%"class.llvm::PseudoSourceValue" = type { %"class.llvm::Value" } +%"class.llvm::FoldingSetNodeID" = type { %"class.llvm::SmallVector.194" } +%"class.llvm::SmallVector.194" = type { [28 x i8], %"struct.llvm::SmallVectorStorage.200" } +%"struct.llvm::SmallVectorStorage.200" = type { [31 x %"struct.llvm::AlignedCharArrayUnion.198"] } +%"struct.llvm::ArrayRecycler<llvm::MachineOperand, 8>::FreeList" = type { %"struct.llvm::ArrayRecycler<llvm::MachineOperand, 8>::FreeList"* } +%"class.llvm::ilist_iterator.202" = type { %"class.llvm::MachineInstr"* } +%"class.llvm::TargetInstrInfo" = type { i32 (...)**, [28 x i8], i32, i32 } +%"struct.std::pair.203" = type { i8, i8 } +%"class.llvm::SmallVectorImpl.195" = type { %"class.llvm::SmallVectorTemplateBase.196" } +%"class.llvm::SmallVectorTemplateBase.196" = type { %"class.llvm::SmallVectorTemplateCommon.197" } +%"class.llvm::SmallVectorTemplateCommon.197" = type { %"class.llvm::SmallVectorBase", %"struct.llvm::AlignedCharArrayUnion.198" } +%"class.llvm::AliasAnalysis" = type { i32 (...)**, %"class.llvm::DataLayout"*, %"class.llvm::TargetLibraryInfo"*, %"class.llvm::AliasAnalysis"* } +%"class.llvm::TargetLibraryInfo" = type opaque +%"struct.llvm::AliasAnalysis::Location" = type { %"class.llvm::Value"*, i64, %"class.llvm::MDNode"* } +%"class.llvm::DIVariable" = type { %"class.llvm::DIDescriptor" } +%"class.llvm::DIDescriptor" = type { %"class.llvm::MDNode"* } +%"class.llvm::DIScope" = type { %"class.llvm::DIDescriptor" } +%"class.llvm::ArrayRef.208" = type { i32*, i64 } +%"class.llvm::SmallVector.209" = type { %"class.llvm::SmallVectorImpl.210", %"struct.llvm::SmallVectorStorage.214" } +%"class.llvm::SmallVectorImpl.210" = type { %"class.llvm::SmallVectorTemplateBase.211" } +%"class.llvm::SmallVectorTemplateBase.211" = type { %"class.llvm::SmallVectorTemplateCommon.212" } +%"class.llvm::SmallVectorTemplateCommon.212" = type { %"class.llvm::SmallVectorBase", %"struct.llvm::AlignedCharArrayUnion.213" } +%"struct.llvm::AlignedCharArrayUnion.213" = type { %"struct.llvm::AlignedCharArray" } +%"struct.llvm::SmallVectorStorage.214" = type { [7 x %"struct.llvm::AlignedCharArrayUnion.213"] } +%"class.llvm::Twine" = type { %"union.llvm::Twine::Child", %"union.llvm::Twine::Child", i8, i8 } +%"union.llvm::Twine::Child" = type { %"class.llvm::Twine"* } +%"struct.std::random_access_iterator_tag" = type { i8 } + +declare void @_ZN4llvm19MachineRegisterInfo27removeRegOperandFromUseListEPNS_14MachineOperandE(%"class.llvm::MachineRegisterInfo"*, %"class.llvm::MachineOperand"*) + +declare void @_ZN4llvm19MachineRegisterInfo22addRegOperandToUseListEPNS_14MachineOperandE(%"class.llvm::MachineRegisterInfo"*, %"class.llvm::MachineOperand"*) + +declare zeroext i32 @_ZNK4llvm14MCRegisterInfo9getSubRegEjj(%"class.llvm::MCRegisterInfo"*, i32 zeroext, i32 zeroext) + +define void @_ZN4llvm14MachineOperand12substPhysRegEjRKNS_18TargetRegisterInfoE(%"class.llvm::MachineOperand"* %this, i32 zeroext %Reg, %"class.llvm::TargetRegisterInfo"* %TRI) align 2 { +entry: + %SubReg_TargetFlags.i = getelementptr inbounds %"class.llvm::MachineOperand"* %this, i64 0, i32 1 + %0 = bitcast [3 x i8]* %SubReg_TargetFlags.i to i24* + %bf.load.i = load i24* %0, align 1 + %bf.lshr.i = lshr i24 %bf.load.i, 12 + %tobool = icmp eq i24 %bf.lshr.i, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + %bf.cast.i = zext i24 %bf.lshr.i to i32 + %add.ptr = getelementptr inbounds %"class.llvm::TargetRegisterInfo"* %TRI, i64 0, i32 1 + %call3 = tail call zeroext i32 @_ZNK4llvm14MCRegisterInfo9getSubRegEjj(%"class.llvm::MCRegisterInfo"* %add.ptr, i32 zeroext %Reg, i32 zeroext %bf.cast.i) + %bf.load.i10 = load i24* %0, align 1 + %bf.clear.i = and i24 %bf.load.i10, 4095 + store i24 %bf.clear.i, i24* %0, align 1 + br label %if.end + +if.end: ; preds = %entry, %if.then + %Reg.addr.0 = phi i32 [ %call3, %if.then ], [ %Reg, %entry ] + %RegNo.i.i = getelementptr inbounds %"class.llvm::MachineOperand"* %this, i64 0, i32 2, i32 0 + %1 = load i32* %RegNo.i.i, align 4, !tbaa !0 + %cmp.i = icmp eq i32 %1, %Reg.addr.0 + br i1 %cmp.i, label %_ZN4llvm14MachineOperand6setRegEj.exit, label %if.end.i + +if.end.i: ; preds = %if.end + %ParentMI.i.i = getelementptr inbounds %"class.llvm::MachineOperand"* %this, i64 0, i32 3 + %2 = load %"class.llvm::MachineInstr"** %ParentMI.i.i, align 8, !tbaa !3 + %tobool.i = icmp eq %"class.llvm::MachineInstr"* %2, null + br i1 %tobool.i, label %if.end13.i, label %if.then3.i + +if.then3.i: ; preds = %if.end.i + %Parent.i.i = getelementptr inbounds %"class.llvm::MachineInstr"* %2, i64 0, i32 2 + %3 = load %"class.llvm::MachineBasicBlock"** %Parent.i.i, align 8, !tbaa !3 + %tobool5.i = icmp eq %"class.llvm::MachineBasicBlock"* %3, null + br i1 %tobool5.i, label %if.end13.i, label %if.then6.i + +if.then6.i: ; preds = %if.then3.i + %xParent.i.i = getelementptr inbounds %"class.llvm::MachineBasicBlock"* %3, i64 0, i32 4 + %4 = load %"class.llvm::MachineFunction"** %xParent.i.i, align 8, !tbaa !3 + %tobool8.i = icmp eq %"class.llvm::MachineFunction"* %4, null + br i1 %tobool8.i, label %if.end13.i, label %if.then9.i + +if.then9.i: ; preds = %if.then6.i + %RegInfo.i.i = getelementptr inbounds %"class.llvm::MachineFunction"* %4, i64 0, i32 5 + %5 = load %"class.llvm::MachineRegisterInfo"** %RegInfo.i.i, align 8, !tbaa !3 + tail call void @_ZN4llvm19MachineRegisterInfo27removeRegOperandFromUseListEPNS_14MachineOperandE(%"class.llvm::MachineRegisterInfo"* %5, %"class.llvm::MachineOperand"* %this) + store i32 %Reg.addr.0, i32* %RegNo.i.i, align 4, !tbaa !0 + tail call void @_ZN4llvm19MachineRegisterInfo22addRegOperandToUseListEPNS_14MachineOperandE(%"class.llvm::MachineRegisterInfo"* %5, %"class.llvm::MachineOperand"* %this) + br label %_ZN4llvm14MachineOperand6setRegEj.exit + +if.end13.i: ; preds = %if.then6.i, %if.then3.i, %if.end.i + store i32 %Reg.addr.0, i32* %RegNo.i.i, align 4, !tbaa !0 + br label %_ZN4llvm14MachineOperand6setRegEj.exit + +_ZN4llvm14MachineOperand6setRegEj.exit: ; preds = %if.end, %if.then9.i, %if.end13.i + ret void +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} +!3 = metadata !{metadata !"any pointer", metadata !1} +!4 = metadata !{metadata !"vtable pointer", metadata !2} +!5 = metadata !{metadata !"long", metadata !1} +!6 = metadata !{i64 0, i64 8, metadata !3, i64 8, i64 8, metadata !5} +!7 = metadata !{metadata !"short", metadata !1} +!8 = metadata !{i64 0, i64 1, metadata !1, i64 1, i64 4, metadata !0, i64 2, i64 1, metadata !1, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 3, i64 1, metadata !9, i64 4, i64 4, metadata !0, i64 4, i64 4, metadata !0, i64 8, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !5, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 24, i64 8, metadata !3, i64 16, i64 4, metadata !0, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 16, i64 8, metadata !3, i64 24, i64 4, metadata !0} +!9 = metadata !{metadata !"bool", metadata !1} +!10 = metadata !{i8 0, i8 2} + +; CHECK-NOT: lbzu 3, 1(3) diff --git a/test/CodeGen/PowerPC/pr15359.ll b/test/CodeGen/PowerPC/pr15359.ll new file mode 100644 index 0000000000..12fa3e5ffb --- /dev/null +++ b/test/CodeGen/PowerPC/pr15359.ll @@ -0,0 +1,20 @@ +; RUN: llc -O0 -mcpu=pwr7 -filetype=obj %s -o - | \ +; RUN: elf-dump --dump-section-data | FileCheck %s + +target datalayout = "E-p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@nextIdx = external thread_local global i32 + +define fastcc void @func() nounwind { +entry: + store i32 42, i32* @nextIdx + ret void +} + +; Verify that nextIdx has symbol type TLS. +; +; CHECK: '.symtab' +; CHECK: 'nextIdx' +; CHECK: 'st_type', 0x6 + diff --git a/test/CodeGen/PowerPC/pwr3-6x.ll b/test/CodeGen/PowerPC/pwr3-6x.ll new file mode 100644 index 0000000000..a9cfe412fd --- /dev/null +++ b/test/CodeGen/PowerPC/pwr3-6x.ll @@ -0,0 +1,14 @@ +; Test basic support for some older processors. + +;RUN: llc < %s -march=ppc64 -mcpu=pwr3 | FileCheck %s +;RUN: llc < %s -march=ppc64 -mcpu=pwr4 | FileCheck %s +;RUN: llc < %s -march=ppc64 -mcpu=pwr5 | FileCheck %s +;RUN: llc < %s -march=ppc64 -mcpu=pwr5x | FileCheck %s +;RUN: llc < %s -march=ppc64 -mcpu=pwr6x | FileCheck %s + +define void @foo() { +entry: + ret void +} + +; CHECK: @foo diff --git a/test/CodeGen/PowerPC/quadint-return.ll b/test/CodeGen/PowerPC/quadint-return.ll new file mode 100644 index 0000000000..03499915e7 --- /dev/null +++ b/test/CodeGen/PowerPC/quadint-return.ll @@ -0,0 +1,19 @@ +; REQUIRES: asserts +; RUN: llc -O0 -debug -o - < %s 2>&1 | FileCheck %s + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define i128 @foo() nounwind { +entry: + %x = alloca i128, align 16 + store i128 27, i128* %x, align 16 + %0 = load i128* %x, align 16 + ret i128 %0 +} + +; CHECK: ********** Function: foo +; CHECK: ********** FAST REGISTER ALLOCATION ********** +; CHECK: %X3<def> = COPY %vreg +; CHECK-NEXT: %X4<def> = COPY %vreg +; CHECK-NEXT: BLR diff --git a/test/CodeGen/PowerPC/sdag-ppcf128.ll b/test/CodeGen/PowerPC/sdag-ppcf128.ll new file mode 100644 index 0000000000..535ece6d3d --- /dev/null +++ b/test/CodeGen/PowerPC/sdag-ppcf128.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s +; +; PR14751: Unsupported type in SelectionDAG::getConstantFP() + +define fastcc void @_D3std4math4sqrtFNaNbNfcZc() { +entry: + br i1 undef, label %if, label %else +; CHECK: cmplwi 0, 3, 0 +if: ; preds = %entry + store { ppc_fp128, ppc_fp128 } zeroinitializer, { ppc_fp128, ppc_fp128 }* undef + ret void + +else: ; preds = %entry + unreachable +} diff --git a/test/CodeGen/PowerPC/stdux-constuse.ll b/test/CodeGen/PowerPC/stdux-constuse.ll new file mode 100644 index 0000000000..e62d438014 --- /dev/null +++ b/test/CodeGen/PowerPC/stdux-constuse.ll @@ -0,0 +1,47 @@ +; RUN: llc -mcpu=a2 -disable-lsr < %s | FileCheck %s +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define i32 @test1(i64 %add, i64* %ptr) nounwind { +entry: + %p1 = getelementptr i64* %ptr, i64 144115188075855 + br label %for.cond2.preheader + +for.cond2.preheader: + %nl.018 = phi i32 [ 0, %entry ], [ %inc9, %for.end ] + br label %for.body4 + +for.body4: + %lsr.iv = phi i32 [ %lsr.iv.next, %for.body4 ], [ 16000, %for.cond2.preheader ] + %i0 = phi i64* [ %p1, %for.cond2.preheader ], [ %i6, %for.body4 ] + %i6 = getelementptr i64* %i0, i64 400000 + %i7 = getelementptr i64* %i6, i64 300000 + %i8 = getelementptr i64* %i6, i64 200000 + %i9 = getelementptr i64* %i6, i64 100000 + store i64 %add, i64* %i6, align 32 + store i64 %add, i64* %i7, align 32 + store i64 %add, i64* %i8, align 32 + store i64 %add, i64* %i9, align 32 + %lsr.iv.next = add i32 %lsr.iv, -16 + %exitcond.15 = icmp eq i32 %lsr.iv.next, 0 + br i1 %exitcond.15, label %for.end, label %for.body4 + +; Make sure that we generate the most compact form of this loop with no +; unnecessary moves +; CHECK: @test1 +; CHECK: mtctr +; CHECK: stdux +; CHECK-NEXT: stdx +; CHECK-NEXT: stdx +; CHECK-NEXT: stdx +; CHECK-NEXT: bdnz + +for.end: + %inc9 = add nsw i32 %nl.018, 1 + %exitcond = icmp eq i32 %inc9, 400000 + br i1 %exitcond, label %for.end10, label %for.cond2.preheader + +for.end10: + ret i32 0 +} + diff --git a/test/CodeGen/PowerPC/svr4-redzone.ll b/test/CodeGen/PowerPC/svr4-redzone.ll new file mode 100644 index 0000000000..91ff579738 --- /dev/null +++ b/test/CodeGen/PowerPC/svr4-redzone.ll @@ -0,0 +1,39 @@ +; RUN: llc -mtriple="powerpc-unknown-linux-gnu" < %s | FileCheck %s --check-prefix=PPC32 +; RUN: llc -mtriple="powerpc64-unknown-linux-gnu" < %s | FileCheck %s --check-prefix=PPC64 +; PR15332 + +define void @regalloc() nounwind { +entry: + %0 = add i32 1, 2 + ret void +} +; PPC32: regalloc: +; PPC32-NOT: stwu 1, -{{[0-9]+}}(1) +; PPC32: blr + +; PPC64: regalloc: +; PPC64-NOT: stdu 1, -{{[0-9]+}}(1) +; PPC64: blr + +define void @smallstack() nounwind { +entry: + %0 = alloca i8, i32 4 + ret void +} +; PPC32: smallstack: +; PPC32: stwu 1, -16(1) + +; PPC64: smallstack: +; PPC64-NOT: stdu 1, -{{[0-9]+}}(1) +; PPC64: blr + +define void @bigstack() nounwind { +entry: + %0 = alloca i8, i32 230 + ret void +} +; PPC32: bigstack: +; PPC32: stwu 1, -240(1) + +; PPC64: bigstack: +; PPC64: stdu 1, -352(1) diff --git a/test/CodeGen/PowerPC/tls-2.ll b/test/CodeGen/PowerPC/tls-2.ll new file mode 100644 index 0000000000..20d8fe46ea --- /dev/null +++ b/test/CodeGen/PowerPC/tls-2.ll @@ -0,0 +1,15 @@ +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-freebsd10.0" +; RUN: llc -O1 < %s -march=ppc64 | FileCheck %s + +@a = thread_local global i32 0, align 4 + +;CHECK: localexec: +define i32 @localexec() nounwind { +entry: +;CHECK: addis [[REG1:[0-9]+]], 13, a@tprel@ha +;CHECK-NEXT: li [[REG2:[0-9]+]], 42 +;CHECK-NEXT: stw [[REG2]], a@tprel@l([[REG1]]) + store i32 42, i32* @a, align 4 + ret i32 0 +} diff --git a/test/CodeGen/PowerPC/tls-gd-obj.ll b/test/CodeGen/PowerPC/tls-gd-obj.ll new file mode 100644 index 0000000000..00b537d532 --- /dev/null +++ b/test/CodeGen/PowerPC/tls-gd-obj.ll @@ -0,0 +1,41 @@ +; RUN: llc -mcpu=pwr7 -O0 -filetype=obj -relocation-model=pic %s -o - | \ +; RUN: elf-dump --dump-section-data | FileCheck %s + +; Test correct relocation generation for thread-local storage using +; the general dynamic model and integrated assembly. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = thread_local global i32 0, align 4 + +define signext i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32* @a, align 4 + ret i32 %0 +} + +; Verify generation of R_PPC64_GOT_TLSGD16_HA, R_PPC64_GOT_TLSGD16_LO, +; and R_PPC64_TLSGD for accessing external variable a, and R_PPC64_REL24 +; for the call to __tls_get_addr. +; +; CHECK: '.rela.text' +; CHECK: Relocation 0 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]] +; CHECK-NEXT: 'r_type', 0x00000052 +; CHECK: Relocation 1 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x00000050 +; CHECK: Relocation 2 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x0000006b +; CHECK: Relocation 3 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x{{[0-9a-f]+}} +; CHECK-NEXT: 'r_type', 0x0000000a + diff --git a/test/CodeGen/PowerPC/tls-gd.ll b/test/CodeGen/PowerPC/tls-gd.ll new file mode 100644 index 0000000000..fb8dfaf04a --- /dev/null +++ b/test/CodeGen/PowerPC/tls-gd.ll @@ -0,0 +1,23 @@ +; RUN: llc -mcpu=pwr7 -O0 -relocation-model=pic < %s | FileCheck %s + +; Test correct assembly code generation for thread-local storage using +; the general dynamic model. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = thread_local global i32 0, align 4 + +define signext i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32* @a, align 4 + ret i32 %0 +} + +; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsgd@ha +; CHECK-NEXT: addi 3, [[REG]], a@got@tlsgd@l +; CHECK-NEXT: bl __tls_get_addr(a@tlsgd) +; CHECK-NEXT: nop + diff --git a/test/CodeGen/PowerPC/tls-ie-obj.ll b/test/CodeGen/PowerPC/tls-ie-obj.ll index 5cc0b187f6..3600cc52ba 100644 --- a/test/CodeGen/PowerPC/tls-ie-obj.ll +++ b/test/CodeGen/PowerPC/tls-ie-obj.ll @@ -24,9 +24,13 @@ entry: ; CHECK: Relocation 0 ; CHECK-NEXT: 'r_offset' ; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]] -; CHECK-NEXT: 'r_type', 0x00000057 +; CHECK-NEXT: 'r_type', 0x0000005a ; CHECK: Relocation 1 ; CHECK-NEXT: 'r_offset' ; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x00000058 +; CHECK: Relocation 2 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] ; CHECK-NEXT: 'r_type', 0x00000043 diff --git a/test/CodeGen/PowerPC/tls-ie.ll b/test/CodeGen/PowerPC/tls-ie.ll index cc6f084efb..c5cfba7b3f 100644 --- a/test/CodeGen/PowerPC/tls-ie.ll +++ b/test/CodeGen/PowerPC/tls-ie.ll @@ -16,6 +16,7 @@ entry: ret i32 %0 } -; CHECK: ld [[REG:[0-9]+]], a@got@tprel(2) -; CHECK: add {{[0-9]+}}, [[REG]], a@tls +; CHECK: addis [[REG1:[0-9]+]], 2, a@got@tprel@ha +; CHECK: ld [[REG2:[0-9]+]], a@got@tprel@l([[REG1]]) +; CHECK: add {{[0-9]+}}, [[REG2]], a@tls diff --git a/test/CodeGen/PowerPC/tls-ld-2.ll b/test/CodeGen/PowerPC/tls-ld-2.ll new file mode 100644 index 0000000000..4954afeb24 --- /dev/null +++ b/test/CodeGen/PowerPC/tls-ld-2.ll @@ -0,0 +1,24 @@ +; RUN: llc -mcpu=pwr7 -O1 -relocation-model=pic < %s | FileCheck %s + +; Test peephole optimization for thread-local storage using the +; local dynamic model. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = hidden thread_local global i32 0, align 4 + +define signext i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32* @a, align 4 + ret i32 %0 +} + +; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsld@ha +; CHECK-NEXT: addi 3, [[REG]], a@got@tlsld@l +; CHECK-NEXT: bl __tls_get_addr(a@tlsld) +; CHECK-NEXT: nop +; CHECK-NEXT: addis [[REG2:[0-9]+]], 3, a@dtprel@ha +; CHECK-NEXT: lwa {{[0-9]+}}, a@dtprel@l([[REG2]]) diff --git a/test/CodeGen/PowerPC/tls-ld-obj.ll b/test/CodeGen/PowerPC/tls-ld-obj.ll new file mode 100644 index 0000000000..c521ae405f --- /dev/null +++ b/test/CodeGen/PowerPC/tls-ld-obj.ll @@ -0,0 +1,50 @@ +; RUN: llc -mcpu=pwr7 -O0 -filetype=obj -relocation-model=pic %s -o - | \ +; RUN: elf-dump --dump-section-data | FileCheck %s + +; Test correct relocation generation for thread-local storage using +; the local dynamic model. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = hidden thread_local global i32 0, align 4 + +define signext i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32* @a, align 4 + ret i32 %0 +} + +; Verify generation of R_PPC64_GOT_TLSLD16_HA, R_PPC64_GOT_TLSLD16_LO, +; R_PPC64_TLSLD, R_PPC64_DTPREL16_HA, and R_PPC64_DTPREL16_LO for +; accessing external variable a, and R_PPC64_REL24 for the call to +; __tls_get_addr. +; +; CHECK: '.rela.text' +; CHECK: Relocation 0 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]] +; CHECK-NEXT: 'r_type', 0x00000056 +; CHECK: Relocation 1 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x00000054 +; CHECK: Relocation 2 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x0000006c +; CHECK: Relocation 3 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x{{[0-9a-f]+}} +; CHECK-NEXT: 'r_type', 0x0000000a +; CHECK: Relocation 4 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x0000004d +; CHECK: Relocation 5 +; CHECK-NEXT: 'r_offset' +; CHECK-NEXT: 'r_sym', 0x[[SYM1]] +; CHECK-NEXT: 'r_type', 0x0000004b + diff --git a/test/CodeGen/PowerPC/tls-ld.ll b/test/CodeGen/PowerPC/tls-ld.ll new file mode 100644 index 0000000000..1ebc6129e2 --- /dev/null +++ b/test/CodeGen/PowerPC/tls-ld.ll @@ -0,0 +1,24 @@ +; RUN: llc -mcpu=pwr7 -O0 -relocation-model=pic < %s | FileCheck %s + +; Test correct assembly code generation for thread-local storage using +; the local dynamic model. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = hidden thread_local global i32 0, align 4 + +define signext i32 @main() nounwind { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %0 = load i32* @a, align 4 + ret i32 %0 +} + +; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsld@ha +; CHECK-NEXT: addi 3, [[REG]], a@got@tlsld@l +; CHECK-NEXT: bl __tls_get_addr(a@tlsld) +; CHECK-NEXT: nop +; CHECK-NEXT: addis [[REG2:[0-9]+]], 3, a@dtprel@ha +; CHECK-NEXT: addi {{[0-9]+}}, [[REG2]], a@dtprel@l diff --git a/test/CodeGen/PowerPC/tls.ll b/test/CodeGen/PowerPC/tls.ll index 713893bf58..151b4b7dda 100644 --- a/test/CodeGen/PowerPC/tls.ll +++ b/test/CodeGen/PowerPC/tls.ll @@ -1,16 +1,21 @@ target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" target triple = "powerpc64-unknown-freebsd10.0" -; RUN: llc < %s -march=ppc64 | FileCheck %s +; RUN: llc -O0 < %s -march=ppc64 | FileCheck -check-prefix=OPT0 %s +; RUN: llc -O1 < %s -march=ppc64 | FileCheck -check-prefix=OPT1 %s @a = thread_local global i32 0, align 4 -;CHECK: localexec: +;OPT0: localexec: +;OPT1: localexec: define i32 @localexec() nounwind { entry: -;CHECK: addis [[REG1:[0-9]+]], 13, a@tprel@ha -;CHECK-NEXT: li [[REG2:[0-9]+]], 42 -;CHECK-NEXT: addi [[REG1]], [[REG1]], a@tprel@l -;CHECK-NEXT: stw [[REG2]], 0([[REG1]]) +;OPT0: addis [[REG1:[0-9]+]], 13, a@tprel@ha +;OPT0-NEXT: li [[REG2:[0-9]+]], 42 +;OPT0-NEXT: addi [[REG1]], [[REG1]], a@tprel@l +;OPT0-NEXT: stw [[REG2]], 0([[REG1]]) +;OPT1: addis [[REG1:[0-9]+]], 13, a@tprel@ha +;OPT1-NEXT: li [[REG2:[0-9]+]], 42 +;OPT1-NEXT: stw [[REG2]], a@tprel@l([[REG1]]) store i32 42, i32* @a, align 4 ret i32 0 } diff --git a/test/CodeGen/PowerPC/vaddsplat.ll b/test/CodeGen/PowerPC/vaddsplat.ll new file mode 100644 index 0000000000..e65148aff0 --- /dev/null +++ b/test/CodeGen/PowerPC/vaddsplat.ll @@ -0,0 +1,149 @@ +; RUN: llc -O0 -mcpu=pwr7 <%s | FileCheck %s + +; Test optimizations of build_vector for 6-bit immediates. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +%v4i32 = type <4 x i32> +%v8i16 = type <8 x i16> +%v16i8 = type <16 x i8> + +define void @test_v4i32_pos_even(%v4i32* %P, %v4i32* %S) { + %p = load %v4i32* %P + %r = add %v4i32 %p, < i32 18, i32 18, i32 18, i32 18 > + store %v4i32 %r, %v4i32* %S + ret void +} + +; CHECK: test_v4i32_pos_even: +; CHECK: vspltisw [[REG1:[0-9]+]], 9 +; CHECK: vadduwm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v4i32_neg_even(%v4i32* %P, %v4i32* %S) { + %p = load %v4i32* %P + %r = add %v4i32 %p, < i32 -28, i32 -28, i32 -28, i32 -28 > + store %v4i32 %r, %v4i32* %S + ret void +} + +; CHECK: test_v4i32_neg_even: +; CHECK: vspltisw [[REG1:[0-9]+]], -14 +; CHECK: vadduwm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v8i16_pos_even(%v8i16* %P, %v8i16* %S) { + %p = load %v8i16* %P + %r = add %v8i16 %p, < i16 30, i16 30, i16 30, i16 30, i16 30, i16 30, i16 30, i16 30 > + store %v8i16 %r, %v8i16* %S + ret void +} + +; CHECK: test_v8i16_pos_even: +; CHECK: vspltish [[REG1:[0-9]+]], 15 +; CHECK: vadduhm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v8i16_neg_even(%v8i16* %P, %v8i16* %S) { + %p = load %v8i16* %P + %r = add %v8i16 %p, < i16 -32, i16 -32, i16 -32, i16 -32, i16 -32, i16 -32, i16 -32, i16 -32 > + store %v8i16 %r, %v8i16* %S + ret void +} + +; CHECK: test_v8i16_neg_even: +; CHECK: vspltish [[REG1:[0-9]+]], -16 +; CHECK: vadduhm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v16i8_pos_even(%v16i8* %P, %v16i8* %S) { + %p = load %v16i8* %P + %r = add %v16i8 %p, < i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16 > + store %v16i8 %r, %v16i8* %S + ret void +} + +; CHECK: test_v16i8_pos_even: +; CHECK: vspltisb [[REG1:[0-9]+]], 8 +; CHECK: vaddubm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v16i8_neg_even(%v16i8* %P, %v16i8* %S) { + %p = load %v16i8* %P + %r = add %v16i8 %p, < i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18, i8 -18 > + store %v16i8 %r, %v16i8* %S + ret void +} + +; CHECK: test_v16i8_neg_even: +; CHECK: vspltisb [[REG1:[0-9]+]], -9 +; CHECK: vaddubm {{[0-9]+}}, [[REG1]], [[REG1]] + +define void @test_v4i32_pos_odd(%v4i32* %P, %v4i32* %S) { + %p = load %v4i32* %P + %r = add %v4i32 %p, < i32 27, i32 27, i32 27, i32 27 > + store %v4i32 %r, %v4i32* %S + ret void +} + +; CHECK: test_v4i32_pos_odd: +; CHECK: vspltisw [[REG2:[0-9]+]], -16 +; CHECK: vspltisw [[REG1:[0-9]+]], 11 +; CHECK: vsubuwm {{[0-9]+}}, [[REG1]], [[REG2]] + +define void @test_v4i32_neg_odd(%v4i32* %P, %v4i32* %S) { + %p = load %v4i32* %P + %r = add %v4i32 %p, < i32 -27, i32 -27, i32 -27, i32 -27 > + store %v4i32 %r, %v4i32* %S + ret void +} + +; CHECK: test_v4i32_neg_odd: +; CHECK: vspltisw [[REG2:[0-9]+]], -16 +; CHECK: vspltisw [[REG1:[0-9]+]], -11 +; CHECK: vadduwm {{[0-9]+}}, [[REG1]], [[REG2]] + +define void @test_v8i16_pos_odd(%v8i16* %P, %v8i16* %S) { + %p = load %v8i16* %P + %r = add %v8i16 %p, < i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31, i16 31 > + store %v8i16 %r, %v8i16* %S + ret void +} + +; CHECK: test_v8i16_pos_odd: +; CHECK: vspltish [[REG2:[0-9]+]], -16 +; CHECK: vspltish [[REG1:[0-9]+]], 15 +; CHECK: vsubuhm {{[0-9]+}}, [[REG1]], [[REG2]] + +define void @test_v8i16_neg_odd(%v8i16* %P, %v8i16* %S) { + %p = load %v8i16* %P + %r = add %v8i16 %p, < i16 -31, i16 -31, i16 -31, i16 -31, i16 -31, i16 -31, i16 -31, i16 -31 > + store %v8i16 %r, %v8i16* %S + ret void +} + +; CHECK: test_v8i16_neg_odd: +; CHECK: vspltish [[REG2:[0-9]+]], -16 +; CHECK: vspltish [[REG1:[0-9]+]], -15 +; CHECK: vadduhm {{[0-9]+}}, [[REG1]], [[REG2]] + +define void @test_v16i8_pos_odd(%v16i8* %P, %v16i8* %S) { + %p = load %v16i8* %P + %r = add %v16i8 %p, < i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17 > + store %v16i8 %r, %v16i8* %S + ret void +} + +; CHECK: test_v16i8_pos_odd: +; CHECK: vspltisb [[REG2:[0-9]+]], -16 +; CHECK: vspltisb [[REG1:[0-9]+]], 1 +; CHECK: vsububm {{[0-9]+}}, [[REG1]], [[REG2]] + +define void @test_v16i8_neg_odd(%v16i8* %P, %v16i8* %S) { + %p = load %v16i8* %P + %r = add %v16i8 %p, < i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17, i8 -17 > + store %v16i8 %r, %v16i8* %S + ret void +} + +; CHECK: test_v16i8_neg_odd: +; CHECK: vspltisb [[REG2:[0-9]+]], -16 +; CHECK: vspltisb [[REG1:[0-9]+]], -1 +; CHECK: vaddubm {{[0-9]+}}, [[REG1]], [[REG2]] + diff --git a/test/CodeGen/PowerPC/vec_cmp.ll b/test/CodeGen/PowerPC/vec_cmp.ll index 3180f464d1..eb41667610 100644 --- a/test/CodeGen/PowerPC/vec_cmp.ll +++ b/test/CodeGen/PowerPC/vec_cmp.ll @@ -54,7 +54,7 @@ entry: } ; CHECK: v16si8_cmp_ne: ; CHECK: vcmpequb [[RET:[0-9]+]], 2, 3 -; CHECK-NOR: vnor 2, [[RET]], [[RET]] +; CHECK-NEXT: vnor 2, [[RET]], [[RET]] define <16 x i8> @v16si8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone { entry: diff --git a/test/CodeGen/PowerPC/vec_constants.ll b/test/CodeGen/PowerPC/vec_constants.ll index 399f19f8d2..e4799e50e6 100644 --- a/test/CodeGen/PowerPC/vec_constants.ll +++ b/test/CodeGen/PowerPC/vec_constants.ll @@ -1,4 +1,7 @@ -; RUN: llc < %s -march=ppc32 -mcpu=g5 | not grep CPI +; RUN: llc -O0 -mcpu=pwr7 < %s | FileCheck %s + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" define void @test1(<4 x i32>* %P1, <4 x i32>* %P2, <4 x float>* %P3) nounwind { %tmp = load <4 x i32>* %P1 ; <<4 x i32>> [#uses=1] @@ -13,32 +16,71 @@ define void @test1(<4 x i32>* %P1, <4 x i32>* %P2, <4 x float>* %P3) nounwind { %tmp13 = bitcast <4 x i32> %tmp12 to <4 x float> ; <<4 x float>> [#uses=1] store <4 x float> %tmp13, <4 x float>* %P3 ret void + +; CHECK: test1: +; CHECK-NOT: CPI } define <4 x i32> @test_30() nounwind { ret <4 x i32> < i32 30, i32 30, i32 30, i32 30 > + +; CHECK: test_30: +; CHECK: vspltisw +; CHECK-NEXT: vadduwm +; CHECK-NEXT: blr } define <4 x i32> @test_29() nounwind { ret <4 x i32> < i32 29, i32 29, i32 29, i32 29 > + +; CHECK: test_29: +; CHECK: vspltisw +; CHECK-NEXT: vspltisw +; CHECK-NEXT: vsubuwm +; CHECK-NEXT: blr } define <8 x i16> @test_n30() nounwind { ret <8 x i16> < i16 -30, i16 -30, i16 -30, i16 -30, i16 -30, i16 -30, i16 -30, i16 -30 > + +; CHECK: test_n30: +; CHECK: vspltish +; CHECK-NEXT: vadduhm +; CHECK-NEXT: blr } define <16 x i8> @test_n104() nounwind { ret <16 x i8> < i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104, i8 -104 > + +; CHECK: test_n104: +; CHECK: vspltisb +; CHECK-NEXT: vslb +; CHECK-NEXT: blr } define <4 x i32> @test_vsldoi() nounwind { ret <4 x i32> < i32 512, i32 512, i32 512, i32 512 > + +; CHECK: test_vsldoi: +; CHECK: vspltisw +; CHECK-NEXT: vsldoi +; CHECK-NEXT: blr } define <8 x i16> @test_vsldoi_65023() nounwind { ret <8 x i16> < i16 65023, i16 65023,i16 65023,i16 65023,i16 65023,i16 65023,i16 65023,i16 65023 > + +; CHECK: test_vsldoi_65023: +; CHECK: vspltish +; CHECK-NEXT: vsldoi +; CHECK-NEXT: blr } define <4 x i32> @test_rol() nounwind { ret <4 x i32> < i32 -11534337, i32 -11534337, i32 -11534337, i32 -11534337 > + +; CHECK: test_rol: +; CHECK: vspltisw +; CHECK-NEXT: vrlw +; CHECK-NEXT: blr } diff --git a/test/CodeGen/PowerPC/vec_extload.ll b/test/CodeGen/PowerPC/vec_extload.ll index 15a3f9f295..998645d90d 100644 --- a/test/CodeGen/PowerPC/vec_extload.ll +++ b/test/CodeGen/PowerPC/vec_extload.ll @@ -15,55 +15,9 @@ define <16 x i8> @v16si8_sext_in_reg(<16 x i8> %a) { ret <16 x i8> %c } ; CHECK: v16si8_sext_in_reg: -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lbz -; CHECK: stb -; CHECK: lvx 2, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vslb +; CHECK: vsrab +; CHECK: blr ; The zero extend uses a more clever logic: a vector splat ; and a logic and to set higher bits to 0. @@ -83,31 +37,9 @@ define <8 x i16> @v8si16_sext_in_reg(<8 x i16> %a) { ret <8 x i16> %c } ; CHECK: v8si16_sext_in_reg: -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lhz -; CHECK: sth -; CHECK: lvx 2, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vslh +; CHECK: vsrah +; CHECK: blr ; Same as v8si16_sext_in_reg, but instead of creating the mask ; with a splat, loads it from memory. @@ -129,19 +61,9 @@ define <4 x i32> @v4si32_sext_in_reg(<4 x i32> %a) { ret <4 x i32> %c } ; CHECK: v4si32_sext_in_reg: -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lha -; CHECK: stw -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lha -; CHECK: stw -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lha -; CHECK: stw -; CHECK: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK: lha -; CHECK: stw -; CHECK: lvx 2, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vslw +; CHECK: vsraw +; CHECK: blr ; Same as v8si16_sext_in_reg. define <4 x i32> @v4si32_zext_in_reg(<4 x i32> %a) { diff --git a/test/CodeGen/PowerPC/vec_select.ll b/test/CodeGen/PowerPC/vec_select.ll new file mode 100644 index 0000000000..4ad0acca00 --- /dev/null +++ b/test/CodeGen/PowerPC/vec_select.ll @@ -0,0 +1,7 @@ +; RUN: llc < %s -mtriple=powerpc64-linux-gnu -mattr=+altivec | FileCheck %s + +; CHECK: vsel_float +define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) { + %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2 + ret <4 x float> %vsel +} diff --git a/test/CodeGen/R600/128bit-kernel-args.ll b/test/CodeGen/R600/128bit-kernel-args.ll new file mode 100644 index 0000000000..114f9e7447 --- /dev/null +++ b/test/CodeGen/R600/128bit-kernel-args.ll @@ -0,0 +1,18 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: @v4i32_kernel_arg +; CHECK: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 40 + +define void @v4i32_kernel_arg(<4 x i32> addrspace(1)* %out, <4 x i32> %in) { +entry: + store <4 x i32> %in, <4 x i32> addrspace(1)* %out + ret void +} + +; CHECK: @v4f32_kernel_arg +; CHECK: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 40 +define void @v4f32_kernel_args(<4 x float> addrspace(1)* %out, <4 x float> %in) { +entry: + store <4 x float> %in, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/add.v4i32.ll b/test/CodeGen/R600/add.v4i32.ll new file mode 100644 index 0000000000..ac4a87417b --- /dev/null +++ b/test/CodeGen/R600/add.v4i32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: ADD_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32> addrspace(1) * %in + %b = load <4 x i32> addrspace(1) * %b_ptr + %result = add <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/and.v4i32.ll b/test/CodeGen/R600/and.v4i32.ll new file mode 100644 index 0000000000..662085e2d6 --- /dev/null +++ b/test/CodeGen/R600/and.v4i32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: AND_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: AND_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: AND_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: AND_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32> addrspace(1) * %in + %b = load <4 x i32> addrspace(1) * %b_ptr + %result = and <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/dagcombiner-bug-illegal-vec4-int-to-fp.ll b/test/CodeGen/R600/dagcombiner-bug-illegal-vec4-int-to-fp.ll new file mode 100644 index 0000000000..fd958b3659 --- /dev/null +++ b/test/CodeGen/R600/dagcombiner-bug-illegal-vec4-int-to-fp.ll @@ -0,0 +1,36 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; This test is for a bug in +; DAGCombiner::reduceBuildVecConvertToConvertBuildVec() where +; the wrong type was being passed to +; TargetLowering::getOperationAction() when checking the legality of +; ISD::UINT_TO_FP and ISD::SINT_TO_FP opcodes. + + +; CHECK: @sint +; CHECK: INT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @sint(<4 x float> addrspace(1)* %out, i32 addrspace(1)* %in) { +entry: + %ptr = getelementptr i32 addrspace(1)* %in, i32 1 + %sint = load i32 addrspace(1) * %in + %conv = sitofp i32 %sint to float + %0 = insertelement <4 x float> undef, float %conv, i32 0 + %splat = shufflevector <4 x float> %0, <4 x float> undef, <4 x i32> zeroinitializer + store <4 x float> %splat, <4 x float> addrspace(1)* %out + ret void +} + +;CHECK: @uint +;CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @uint(<4 x float> addrspace(1)* %out, i32 addrspace(1)* %in) { +entry: + %ptr = getelementptr i32 addrspace(1)* %in, i32 1 + %uint = load i32 addrspace(1) * %in + %conv = uitofp i32 %uint to float + %0 = insertelement <4 x float> undef, float %conv, i32 0 + %splat = shufflevector <4 x float> %0, <4 x float> undef, <4 x i32> zeroinitializer + store <4 x float> %splat, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/disconnected-predset-break-bug.ll b/test/CodeGen/R600/disconnected-predset-break-bug.ll new file mode 100644 index 0000000000..a58674269a --- /dev/null +++ b/test/CodeGen/R600/disconnected-predset-break-bug.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; PRED_SET* instructions must be tied to any instruction that uses their +; result. This tests that there are no instructions between the PRED_SET* +; and the PREDICATE_BREAK in this loop. + +; CHECK: @loop_ge +; CHECK: WHILE +; CHECK: PRED_SET +; CHECK-NEXT: PREDICATED_BREAK +define void @loop_ge(i32 addrspace(1)* nocapture %out, i32 %iterations) nounwind { +entry: + %cmp5 = icmp sgt i32 %iterations, 0 + br i1 %cmp5, label %for.body, label %for.end + +for.body: ; preds = %for.body, %entry + %i.07.in = phi i32 [ %i.07, %for.body ], [ %iterations, %entry ] + %ai.06 = phi i32 [ %add, %for.body ], [ 0, %entry ] + %i.07 = add nsw i32 %i.07.in, -1 + %arrayidx = getelementptr inbounds i32 addrspace(1)* %out, i32 %ai.06 + store i32 %i.07, i32 addrspace(1)* %arrayidx, align 4 + %add = add nsw i32 %ai.06, 1 + %exitcond = icmp eq i32 %add, %iterations + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +} diff --git a/test/CodeGen/R600/fabs.ll b/test/CodeGen/R600/fabs.ll new file mode 100644 index 0000000000..0407533eaa --- /dev/null +++ b/test/CodeGen/R600/fabs.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MOV T{{[0-9]+\.[XYZW], \|T[0-9]+\.[XYZW]\|}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @fabs( float %r0) + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @fabs(float ) readnone diff --git a/test/CodeGen/R600/fadd.ll b/test/CodeGen/R600/fadd.ll new file mode 100644 index 0000000000..d7d1b6572c --- /dev/null +++ b/test/CodeGen/R600/fadd.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = fadd float %r0, %r1 + call void @llvm.AMDGPU.store.output(float %r2, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + diff --git a/test/CodeGen/R600/fadd.v4f32.ll b/test/CodeGen/R600/fadd.v4f32.ll new file mode 100644 index 0000000000..85dbfd52cb --- /dev/null +++ b/test/CodeGen/R600/fadd.v4f32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x float> addrspace(1)* %in, i32 1 + %a = load <4 x float> addrspace(1) * %in + %b = load <4 x float> addrspace(1) * %b_ptr + %result = fadd <4 x float> %a, %b + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/fcmp-cnd.ll b/test/CodeGen/R600/fcmp-cnd.ll new file mode 100644 index 0000000000..a94cfb5cf2 --- /dev/null +++ b/test/CodeGen/R600/fcmp-cnd.ll @@ -0,0 +1,14 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;Not checking arguments 2 and 3 to CNDE, because they may change between +;registers and literal.x depending on what the optimizer does. +;CHECK: CNDE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(i32 addrspace(1)* %out, float addrspace(1)* %in) { +entry: + %0 = load float addrspace(1)* %in + %cmp = fcmp oeq float %0, 0.000000e+00 + %value = select i1 %cmp, i32 2, i32 3 + store i32 %value, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/fcmp-cnde-int-args.ll b/test/CodeGen/R600/fcmp-cnde-int-args.ll new file mode 100644 index 0000000000..55aba0d72d --- /dev/null +++ b/test/CodeGen/R600/fcmp-cnde-int-args.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; This test checks a bug in R600TargetLowering::LowerSELECT_CC where the +; chance to optimize the fcmp + select instructions to SET* was missed +; due to the fact that the operands to fcmp and select had different types + +; CHECK: SET{{[A-Z]+}}_DX10 + +define void @test(i32 addrspace(1)* %out, float addrspace(1)* %in) { +entry: + %0 = load float addrspace(1)* %in + %cmp = fcmp oeq float %0, 0.000000e+00 + %value = select i1 %cmp, i32 -1, i32 0 + store i32 %value, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/fcmp.ll b/test/CodeGen/R600/fcmp.ll new file mode 100644 index 0000000000..37f621d239 --- /dev/null +++ b/test/CodeGen/R600/fcmp.ll @@ -0,0 +1,37 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: @fcmp_sext +; CHECK: SETE_DX10 T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @fcmp_sext(i32 addrspace(1)* %out, float addrspace(1)* %in) { +entry: + %0 = load float addrspace(1)* %in + %arrayidx1 = getelementptr inbounds float addrspace(1)* %in, i32 1 + %1 = load float addrspace(1)* %arrayidx1 + %cmp = fcmp oeq float %0, %1 + %sext = sext i1 %cmp to i32 + store i32 %sext, i32 addrspace(1)* %out + ret void +} + +; This test checks that a setcc node with f32 operands is lowered to a +; SET*_DX10 instruction. Previously we were lowering this to: +; SET* + FP_TO_SINT + +; CHECK: @fcmp_br +; CHECK: SET{{[N]*}}E_DX10 T{{[0-9]+\.[XYZW], [a-zA-Z0-9, .]+}}(5.0 + +define void @fcmp_br(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp oeq float %in, 5.0 + br i1 %0, label %IF, label %ENDIF + +IF: + %1 = getelementptr i32 addrspace(1)* %out, i32 1 + store i32 0, i32 addrspace(1)* %1 + br label %ENDIF + +ENDIF: + store i32 0, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/fdiv.v4f32.ll b/test/CodeGen/R600/fdiv.v4f32.ll new file mode 100644 index 0000000000..79e677f541 --- /dev/null +++ b/test/CodeGen/R600/fdiv.v4f32.ll @@ -0,0 +1,19 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: RECIP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: RECIP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: RECIP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: RECIP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x float> addrspace(1)* %in, i32 1 + %a = load <4 x float> addrspace(1) * %in + %b = load <4 x float> addrspace(1) * %b_ptr + %result = fdiv <4 x float> %a, %b + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/floor.ll b/test/CodeGen/R600/floor.ll new file mode 100644 index 0000000000..845330f284 --- /dev/null +++ b/test/CodeGen/R600/floor.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: FLOOR T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @floor(float %r0) + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @floor(float) readonly diff --git a/test/CodeGen/R600/fmad.ll b/test/CodeGen/R600/fmad.ll new file mode 100644 index 0000000000..a3d4d0ff0d --- /dev/null +++ b/test/CodeGen/R600/fmad.ll @@ -0,0 +1,19 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MULADD_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = call float @llvm.R600.load.input(i32 2) + %r3 = fmul float %r0, %r1 + %r4 = fadd float %r3, %r2 + call void @llvm.AMDGPU.store.output(float %r4, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @fabs(float ) readnone diff --git a/test/CodeGen/R600/fmax.ll b/test/CodeGen/R600/fmax.ll new file mode 100644 index 0000000000..3708f0b9ee --- /dev/null +++ b/test/CodeGen/R600/fmax.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MAX T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = fcmp uge float %r0, %r1 + %r3 = select i1 %r2, float %r0, float %r1 + call void @llvm.AMDGPU.store.output(float %r3, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) diff --git a/test/CodeGen/R600/fmin.ll b/test/CodeGen/R600/fmin.ll new file mode 100644 index 0000000000..19d59ab306 --- /dev/null +++ b/test/CodeGen/R600/fmin.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MIN T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = fcmp uge float %r0, %r1 + %r3 = select i1 %r2, float %r1, float %r0 + call void @llvm.AMDGPU.store.output(float %r3, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) diff --git a/test/CodeGen/R600/fmul.ll b/test/CodeGen/R600/fmul.ll new file mode 100644 index 0000000000..eb1d523c0b --- /dev/null +++ b/test/CodeGen/R600/fmul.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = fmul float %r0, %r1 + call void @llvm.AMDGPU.store.output(float %r2, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + diff --git a/test/CodeGen/R600/fmul.v4f32.ll b/test/CodeGen/R600/fmul.v4f32.ll new file mode 100644 index 0000000000..6d44a0c5c7 --- /dev/null +++ b/test/CodeGen/R600/fmul.v4f32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x float> addrspace(1)* %in, i32 1 + %a = load <4 x float> addrspace(1) * %in + %b = load <4 x float> addrspace(1) * %b_ptr + %result = fmul <4 x float> %a, %b + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/fsub.ll b/test/CodeGen/R600/fsub.ll new file mode 100644 index 0000000000..591aa52676 --- /dev/null +++ b/test/CodeGen/R600/fsub.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], -T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = fsub float %r0, %r1 + call void @llvm.AMDGPU.store.output(float %r2, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + diff --git a/test/CodeGen/R600/fsub.v4f32.ll b/test/CodeGen/R600/fsub.v4f32.ll new file mode 100644 index 0000000000..612a57e4b6 --- /dev/null +++ b/test/CodeGen/R600/fsub.v4f32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK: ADD T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x float> addrspace(1)* %in, i32 1 + %a = load <4 x float> addrspace(1) * %in + %b = load <4 x float> addrspace(1) * %b_ptr + %result = fsub <4 x float> %a, %b + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/i8_to_double_to_float.ll b/test/CodeGen/R600/i8_to_double_to_float.ll new file mode 100644 index 0000000000..39f33227fa --- /dev/null +++ b/test/CodeGen/R600/i8_to_double_to_float.ll @@ -0,0 +1,11 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(float addrspace(1)* %out, i8 addrspace(1)* %in) { + %1 = load i8 addrspace(1)* %in + %2 = uitofp i8 %1 to double + %3 = fptrunc double %2 to float + store float %3, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/icmp-select-sete-reverse-args.ll b/test/CodeGen/R600/icmp-select-sete-reverse-args.ll new file mode 100644 index 0000000000..71705a64f5 --- /dev/null +++ b/test/CodeGen/R600/icmp-select-sete-reverse-args.ll @@ -0,0 +1,18 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;Test that a select with reversed True/False values is correctly lowered +;to a SETNE_INT. There should only be one SETNE_INT instruction. + +;CHECK: SETNE_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK-NOT: SETNE_INT + +define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { +entry: + %0 = load i32 addrspace(1)* %in + %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %in, i32 1 + %1 = load i32 addrspace(1)* %arrayidx1 + %cmp = icmp eq i32 %0, %1 + %value = select i1 %cmp, i32 0, i32 -1 + store i32 %value, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/kcache-fold.ll b/test/CodeGen/R600/kcache-fold.ll new file mode 100644 index 0000000000..82fb925c0d --- /dev/null +++ b/test/CodeGen/R600/kcache-fold.ll @@ -0,0 +1,52 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: MOV T{{[0-9]+\.[XYZW], CBuf0\[[0-9]+\]\.[XYZW]}} + +define void @main() { +main_body: + %0 = load <4 x float> addrspace(8)* null + %1 = extractelement <4 x float> %0, i32 0 + %2 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %3 = extractelement <4 x float> %2, i32 0 + %4 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 2) + %5 = extractelement <4 x float> %4, i32 0 + %6 = fcmp ult float %1, 0.000000e+00 + %7 = select i1 %6, float %3, float %5 + %8 = load <4 x float> addrspace(8)* null + %9 = extractelement <4 x float> %8, i32 1 + %10 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %11 = extractelement <4 x float> %10, i32 1 + %12 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 2) + %13 = extractelement <4 x float> %12, i32 1 + %14 = fcmp ult float %9, 0.000000e+00 + %15 = select i1 %14, float %11, float %13 + %16 = load <4 x float> addrspace(8)* null + %17 = extractelement <4 x float> %16, i32 2 + %18 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %19 = extractelement <4 x float> %18, i32 2 + %20 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 2) + %21 = extractelement <4 x float> %20, i32 2 + %22 = fcmp ult float %17, 0.000000e+00 + %23 = select i1 %22, float %19, float %21 + %24 = load <4 x float> addrspace(8)* null + %25 = extractelement <4 x float> %24, i32 3 + %26 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %27 = extractelement <4 x float> %26, i32 3 + %28 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 2) + %29 = extractelement <4 x float> %28, i32 3 + %30 = fcmp ult float %25, 0.000000e+00 + %31 = select i1 %30, float %27, float %29 + %32 = call float @llvm.AMDIL.clamp.(float %7, float 0.000000e+00, float 1.000000e+00) + %33 = call float @llvm.AMDIL.clamp.(float %15, float 0.000000e+00, float 1.000000e+00) + %34 = call float @llvm.AMDIL.clamp.(float %23, float 0.000000e+00, float 1.000000e+00) + %35 = call float @llvm.AMDIL.clamp.(float %31, float 0.000000e+00, float 1.000000e+00) + %36 = insertelement <4 x float> undef, float %32, i32 0 + %37 = insertelement <4 x float> %36, float %33, i32 1 + %38 = insertelement <4 x float> %37, float %34, i32 2 + %39 = insertelement <4 x float> %38, float %35, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %39, i32 0, i32 0) + ret void +} + +declare float @llvm.AMDIL.clamp.(float, float, float) readnone +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) diff --git a/test/CodeGen/R600/legalizedag-bug-expand-setcc.ll b/test/CodeGen/R600/legalizedag-bug-expand-setcc.ll new file mode 100644 index 0000000000..1aae7f9f91 --- /dev/null +++ b/test/CodeGen/R600/legalizedag-bug-expand-setcc.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; This tests a bug where LegalizeDAG was not checking the target's +; BooleanContents value and always using one for true, when expanding +; setcc to select_cc. +; +; This bug caused the icmp IR instruction to be expanded to two machine +; instructions, when only one is needed. +; + +; CHECK: @setcc_expand +; CHECK: SET +; CHECK-NOT: CND +define void @setcc_expand(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp eq i32 %in, 5 + br i1 %0, label %IF, label %ENDIF +IF: + %1 = getelementptr i32 addrspace(1)* %out, i32 1 + store i32 0, i32 addrspace(1)* %1 + br label %ENDIF + +ENDIF: + store i32 0, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/lit.local.cfg b/test/CodeGen/R600/lit.local.cfg new file mode 100644 index 0000000000..36ee493e59 --- /dev/null +++ b/test/CodeGen/R600/lit.local.cfg @@ -0,0 +1,13 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +targets = set(root.targets_to_build.split()) +if not 'R600' in targets: + config.unsupported = True + diff --git a/test/CodeGen/R600/literals.ll b/test/CodeGen/R600/literals.ll new file mode 100644 index 0000000000..e69f64e0e1 --- /dev/null +++ b/test/CodeGen/R600/literals.ll @@ -0,0 +1,32 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; Test using an integer literal constant. +; Generated ASM should be: +; ADD_INT REG literal.x, 5 +; or +; ADD_INT literal.x REG, 5 + +; CHECK: @i32_literal +; CHECK: ADD_INT {{[A-Z0-9,. ]*}}literal.x,{{[A-Z0-9,. ]*}} 5 +define void @i32_literal(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = add i32 5, %in + store i32 %0, i32 addrspace(1)* %out + ret void +} + +; Test using a float literal constant. +; Generated ASM should be: +; ADD REG literal.x, 5.0 +; or +; ADD literal.x REG, 5.0 + +; CHECK: @float_literal +; CHECK: ADD {{[A-Z0-9,. ]*}}literal.x,{{[A-Z0-9,. ]*}} {{[0-9]+}}(5.0 +define void @float_literal(float addrspace(1)* %out, float %in) { +entry: + %0 = fadd float 5.0, %in + store float %0, float addrspace(1)* %out + ret void +} + diff --git a/test/CodeGen/R600/llvm.AMDGPU.mul.ll b/test/CodeGen/R600/llvm.AMDGPU.mul.ll new file mode 100644 index 0000000000..693eb27457 --- /dev/null +++ b/test/CodeGen/R600/llvm.AMDGPU.mul.ll @@ -0,0 +1,17 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: MUL NON-IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = call float @llvm.AMDGPU.mul( float %r0, float %r1) + call void @llvm.AMDGPU.store.output(float %r2, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @llvm.AMDGPU.mul(float ,float ) readnone diff --git a/test/CodeGen/R600/llvm.AMDGPU.tex.ll b/test/CodeGen/R600/llvm.AMDGPU.tex.ll new file mode 100644 index 0000000000..74331fa269 --- /dev/null +++ b/test/CodeGen/R600/llvm.AMDGPU.tex.ll @@ -0,0 +1,42 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 1 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 2 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 3 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 4 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 5 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 6 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 7 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 8 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 9 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 10 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 11 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 12 +;CHECK: TEX_SAMPLE_CT{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 13 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 14 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 15 +;CHECK: TEX_SAMPLET{{[0-9]+\.XYZW, T[0-9]+\.XYZW}}, 0, 0, 16 + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %addr = load <4 x float> addrspace(1)* %in + %res1 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %addr, i32 0, i32 0, i32 1) + %res2 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res1, i32 0, i32 0, i32 2) + %res3 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res2, i32 0, i32 0, i32 3) + %res4 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res3, i32 0, i32 0, i32 4) + %res5 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res4, i32 0, i32 0, i32 5) + %res6 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res5, i32 0, i32 0, i32 6) + %res7 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res6, i32 0, i32 0, i32 7) + %res8 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res7, i32 0, i32 0, i32 8) + %res9 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res8, i32 0, i32 0, i32 9) + %res10 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res9, i32 0, i32 0, i32 10) + %res11 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res10, i32 0, i32 0, i32 11) + %res12 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res11, i32 0, i32 0, i32 12) + %res13 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res12, i32 0, i32 0, i32 13) + %res14 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res13, i32 0, i32 0, i32 14) + %res15 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res14, i32 0, i32 0, i32 15) + %res16 = call <4 x float> @llvm.AMDGPU.tex(<4 x float> %res15, i32 0, i32 0, i32 16) + store <4 x float> %res16, <4 x float> addrspace(1)* %out + ret void +} + +declare <4 x float> @llvm.AMDGPU.tex(<4 x float>, i32, i32, i32) readnone diff --git a/test/CodeGen/R600/llvm.AMDGPU.trunc.ll b/test/CodeGen/R600/llvm.AMDGPU.trunc.ll new file mode 100644 index 0000000000..fac957f7ee --- /dev/null +++ b/test/CodeGen/R600/llvm.AMDGPU.trunc.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: TRUNC T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.AMDGPU.trunc( float %r0) + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @llvm.AMDGPU.trunc(float ) readnone diff --git a/test/CodeGen/R600/llvm.SI.fs.interp.constant.ll b/test/CodeGen/R600/llvm.SI.fs.interp.constant.ll new file mode 100644 index 0000000000..a8f604ac6d --- /dev/null +++ b/test/CodeGen/R600/llvm.SI.fs.interp.constant.ll @@ -0,0 +1,21 @@ +;RUN: llc < %s -march=r600 -mcpu=SI | FileCheck %s + +;CHECK: S_MOV_B32 +;CHECK-NEXT: V_INTERP_MOV_F32 + +define void @main(<16 x i8> addrspace(2)* inreg, <16 x i8> addrspace(2)* inreg, <32 x i8> addrspace(2)* inreg, i32 inreg) "ShaderType"="0" { +main_body: + %4 = call float @llvm.SI.fs.constant(i32 0, i32 0, i32 %3) + %5 = call i32 @llvm.SI.packf16(float %4, float %4) + %6 = bitcast i32 %5 to float + call void @llvm.SI.export(i32 15, i32 1, i32 1, i32 0, i32 1, float %6, float %6, float %6, float %6) + ret void +} + +declare void @llvm.AMDGPU.shader.type(i32) + +declare float @llvm.SI.fs.constant(i32, i32, i32) readonly + +declare i32 @llvm.SI.packf16(float, float) readnone + +declare void @llvm.SI.export(i32, i32, i32, i32, i32, float, float, float, float) diff --git a/test/CodeGen/R600/llvm.SI.sample.ll b/test/CodeGen/R600/llvm.SI.sample.ll new file mode 100644 index 0000000000..d397f3b678 --- /dev/null +++ b/test/CodeGen/R600/llvm.SI.sample.ll @@ -0,0 +1,71 @@ +;RUN: llc < %s -march=r600 -mcpu=SI | FileCheck %s + +;CHECK: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE_C +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE +;CHECK-NEXT: S_WAITCNT 1904 +;CHECK-NEXT: IMAGE_SAMPLE + +define void @test() { + %res1 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 1) + %res2 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 2) + %res3 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 3) + %res4 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 4) + %res5 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 5) + %res6 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 6) + %res7 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 7) + %res8 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 8) + %res9 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 9) + %res10 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 10) + %res11 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 11) + %res12 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 12) + %res13 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 13) + %res14 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 14) + %res15 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 15) + %res16 = call <4 x float> @llvm.SI.sample.(i32 15, <4 x i32> undef, + <8 x i32> undef, <4 x i32> undef, i32 16) + ret void +} + +declare <4 x float> @llvm.SI.sample.(i32, <4 x i32>, <8 x i32>, <4 x i32>, i32) diff --git a/test/CodeGen/R600/llvm.cos.ll b/test/CodeGen/R600/llvm.cos.ll new file mode 100644 index 0000000000..dc120bfb00 --- /dev/null +++ b/test/CodeGen/R600/llvm.cos.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: COS T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.cos.f32(float %r0) + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.cos.f32(float) readnone + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) diff --git a/test/CodeGen/R600/llvm.pow.ll b/test/CodeGen/R600/llvm.pow.ll new file mode 100644 index 0000000000..0ae9172579 --- /dev/null +++ b/test/CodeGen/R600/llvm.pow.ll @@ -0,0 +1,19 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: LOG_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK-NEXT: MUL_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +;CHECK-NEXT: EXP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.R600.load.input(i32 1) + %r2 = call float @llvm.pow.f32( float %r0, float %r1) + call void @llvm.AMDGPU.store.output(float %r2, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @llvm.pow.f32(float ,float ) readonly diff --git a/test/CodeGen/R600/llvm.sin.ll b/test/CodeGen/R600/llvm.sin.ll new file mode 100644 index 0000000000..5cd6998c93 --- /dev/null +++ b/test/CodeGen/R600/llvm.sin.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: SIN T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = call float @llvm.sin.f32( float %r0) + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.sin.f32(float) readnone + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) diff --git a/test/CodeGen/R600/load.constant_addrspace.f32.ll b/test/CodeGen/R600/load.constant_addrspace.f32.ll new file mode 100644 index 0000000000..93627283bb --- /dev/null +++ b/test/CodeGen/R600/load.constant_addrspace.f32.ll @@ -0,0 +1,9 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: VTX_READ_32 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @test(float addrspace(1)* %out, float addrspace(2)* %in) { + %1 = load float addrspace(2)* %in + store float %1, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/load.i8.ll b/test/CodeGen/R600/load.i8.ll new file mode 100644 index 0000000000..b070dcd520 --- /dev/null +++ b/test/CodeGen/R600/load.i8.ll @@ -0,0 +1,10 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: VTX_READ_8 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @test(i32 addrspace(1)* %out, i8 addrspace(1)* %in) { + %1 = load i8 addrspace(1)* %in + %2 = zext i8 %1 to i32 + store i32 %2, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/predicates.ll b/test/CodeGen/R600/predicates.ll new file mode 100644 index 0000000000..18895a423e --- /dev/null +++ b/test/CodeGen/R600/predicates.ll @@ -0,0 +1,100 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; These tests make sure the compiler is optimizing branches using predicates +; when it is legal to do so. + +; CHECK: @simple_if +; CHECK: PRED_SET{{[EGN][ET]*}}_INT Pred, +; CHECK: LSHL T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +define void @simple_if(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sgt i32 %in, 0 + br i1 %0, label %IF, label %ENDIF + +IF: + %1 = shl i32 %in, 1 + br label %ENDIF + +ENDIF: + %2 = phi i32 [ %in, %entry ], [ %1, %IF ] + store i32 %2, i32 addrspace(1)* %out + ret void +} + +; CHECK: @simple_if_else +; CHECK: PRED_SET{{[EGN][ET]*}}_INT Pred, +; CHECK: LSH{{[LR] T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +; CHECK: LSH{{[LR] T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +define void @simple_if_else(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sgt i32 %in, 0 + br i1 %0, label %IF, label %ELSE + +IF: + %1 = shl i32 %in, 1 + br label %ENDIF + +ELSE: + %2 = lshr i32 %in, 1 + br label %ENDIF + +ENDIF: + %3 = phi i32 [ %1, %IF ], [ %2, %ELSE ] + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @nested_if +; CHECK: IF_PREDICATE_SET +; CHECK: PRED_SET{{[EGN][ET]*}}_INT Pred, +; CHECK: LSHL T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +; CHECK: ENDIF +define void @nested_if(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sgt i32 %in, 0 + br i1 %0, label %IF0, label %ENDIF + +IF0: + %1 = add i32 %in, 10 + %2 = icmp sgt i32 %1, 0 + br i1 %2, label %IF1, label %ENDIF + +IF1: + %3 = shl i32 %1, 1 + br label %ENDIF + +ENDIF: + %4 = phi i32 [%in, %entry], [%1, %IF0], [%3, %IF1] + store i32 %4, i32 addrspace(1)* %out + ret void +} + +; CHECK: @nested_if_else +; CHECK: IF_PREDICATE_SET +; CHECK: PRED_SET{{[EGN][ET]*}}_INT Pred, +; CHECK: LSH{{[LR] T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +; CHECK: LSH{{[LR] T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, 1, 0(0.000000e+00) Pred_sel +; CHECK: ENDIF +define void @nested_if_else(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sgt i32 %in, 0 + br i1 %0, label %IF0, label %ENDIF + +IF0: + %1 = add i32 %in, 10 + %2 = icmp sgt i32 %1, 0 + br i1 %2, label %IF1, label %ELSE1 + +IF1: + %3 = shl i32 %1, 1 + br label %ENDIF + +ELSE1: + %4 = lshr i32 %in, 1 + br label %ENDIF + +ENDIF: + %5 = phi i32 [%in, %entry], [%3, %IF1], [%4, %ELSE1] + store i32 %5, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/reciprocal.ll b/test/CodeGen/R600/reciprocal.ll new file mode 100644 index 0000000000..6838c1ae36 --- /dev/null +++ b/test/CodeGen/R600/reciprocal.ll @@ -0,0 +1,16 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: RECIP_IEEE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test() { + %r0 = call float @llvm.R600.load.input(i32 0) + %r1 = fdiv float 1.0, %r0 + call void @llvm.AMDGPU.store.output(float %r1, i32 0) + ret void +} + +declare float @llvm.R600.load.input(i32) readnone + +declare void @llvm.AMDGPU.store.output(float, i32) + +declare float @llvm.AMDGPU.rcp(float ) readnone diff --git a/test/CodeGen/R600/schedule-fs-loop-nested-if.ll b/test/CodeGen/R600/schedule-fs-loop-nested-if.ll new file mode 100644 index 0000000000..ba9620c40a --- /dev/null +++ b/test/CodeGen/R600/schedule-fs-loop-nested-if.ll @@ -0,0 +1,83 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = call float @llvm.R600.interp.input(i32 0, i32 0) + %1 = call float @llvm.R600.interp.input(i32 1, i32 0) + %2 = call float @llvm.R600.interp.input(i32 2, i32 0) + %3 = call float @llvm.R600.interp.input(i32 3, i32 0) + %4 = fcmp ult float %1, 0.000000e+00 + %5 = select i1 %4, float 1.000000e+00, float 0.000000e+00 + %6 = fsub float -0.000000e+00, %5 + %7 = fptosi float %6 to i32 + %8 = bitcast i32 %7 to float + %9 = fcmp ult float %0, 5.700000e+01 + %10 = select i1 %9, float 1.000000e+00, float 0.000000e+00 + %11 = fsub float -0.000000e+00, %10 + %12 = fptosi float %11 to i32 + %13 = bitcast i32 %12 to float + %14 = bitcast float %8 to i32 + %15 = bitcast float %13 to i32 + %16 = and i32 %14, %15 + %17 = bitcast i32 %16 to float + %18 = bitcast float %17 to i32 + %19 = icmp ne i32 %18, 0 + %20 = fcmp ult float %0, 0.000000e+00 + %21 = select i1 %20, float 1.000000e+00, float 0.000000e+00 + %22 = fsub float -0.000000e+00, %21 + %23 = fptosi float %22 to i32 + %24 = bitcast i32 %23 to float + %25 = bitcast float %24 to i32 + %26 = icmp ne i32 %25, 0 + br i1 %19, label %IF, label %ELSE + +IF: ; preds = %main_body + %. = select i1 %26, float 0.000000e+00, float 1.000000e+00 + %.18 = select i1 %26, float 1.000000e+00, float 0.000000e+00 + br label %ENDIF + +ELSE: ; preds = %main_body + br i1 %26, label %ENDIF, label %ELSE17 + +ENDIF: ; preds = %ELSE17, %ELSE, %IF + %temp1.0 = phi float [ %., %IF ], [ %48, %ELSE17 ], [ 0.000000e+00, %ELSE ] + %temp2.0 = phi float [ 0.000000e+00, %IF ], [ %49, %ELSE17 ], [ 1.000000e+00, %ELSE ] + %temp.0 = phi float [ %.18, %IF ], [ %47, %ELSE17 ], [ 0.000000e+00, %ELSE ] + %27 = call float @llvm.AMDIL.clamp.(float %temp.0, float 0.000000e+00, float 1.000000e+00) + %28 = call float @llvm.AMDIL.clamp.(float %temp1.0, float 0.000000e+00, float 1.000000e+00) + %29 = call float @llvm.AMDIL.clamp.(float %temp2.0, float 0.000000e+00, float 1.000000e+00) + %30 = call float @llvm.AMDIL.clamp.(float 1.000000e+00, float 0.000000e+00, float 1.000000e+00) + %31 = insertelement <4 x float> undef, float %27, i32 0 + %32 = insertelement <4 x float> %31, float %28, i32 1 + %33 = insertelement <4 x float> %32, float %29, i32 2 + %34 = insertelement <4 x float> %33, float %30, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %34, i32 0, i32 0) + ret void + +ELSE17: ; preds = %ELSE + %35 = fadd float 0.000000e+00, 0x3FC99999A0000000 + %36 = fadd float 0.000000e+00, 0x3FC99999A0000000 + %37 = fadd float 0.000000e+00, 0x3FC99999A0000000 + %38 = fadd float %35, 0x3FC99999A0000000 + %39 = fadd float %36, 0x3FC99999A0000000 + %40 = fadd float %37, 0x3FC99999A0000000 + %41 = fadd float %38, 0x3FC99999A0000000 + %42 = fadd float %39, 0x3FC99999A0000000 + %43 = fadd float %40, 0x3FC99999A0000000 + %44 = fadd float %41, 0x3FC99999A0000000 + %45 = fadd float %42, 0x3FC99999A0000000 + %46 = fadd float %43, 0x3FC99999A0000000 + %47 = fadd float %44, 0x3FC99999A0000000 + %48 = fadd float %45, 0x3FC99999A0000000 + %49 = fadd float %46, 0x3FC99999A0000000 + br label %ENDIF +} + +declare float @llvm.R600.interp.input(i32, i32) #0 + +declare float @llvm.AMDIL.clamp.(float, float, float) #0 + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) + +attributes #0 = { readnone } diff --git a/test/CodeGen/R600/schedule-fs-loop-nested.ll b/test/CodeGen/R600/schedule-fs-loop-nested.ll new file mode 100644 index 0000000000..5e875c49ab --- /dev/null +++ b/test/CodeGen/R600/schedule-fs-loop-nested.ll @@ -0,0 +1,88 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = load <4 x float> addrspace(9)* null + %1 = extractelement <4 x float> %0, i32 3 + %2 = fptosi float %1 to i32 + %3 = bitcast i32 %2 to float + %4 = bitcast float %3 to i32 + %5 = sdiv i32 %4, 4 + %6 = bitcast i32 %5 to float + %7 = bitcast float %6 to i32 + %8 = mul i32 %7, 4 + %9 = bitcast i32 %8 to float + %10 = bitcast float %9 to i32 + %11 = sub i32 0, %10 + %12 = bitcast i32 %11 to float + %13 = bitcast float %3 to i32 + %14 = bitcast float %12 to i32 + %15 = add i32 %13, %14 + %16 = bitcast i32 %15 to float + %17 = load <4 x float> addrspace(9)* null + %18 = extractelement <4 x float> %17, i32 0 + %19 = load <4 x float> addrspace(9)* null + %20 = extractelement <4 x float> %19, i32 1 + %21 = load <4 x float> addrspace(9)* null + %22 = extractelement <4 x float> %21, i32 2 + br label %LOOP + +LOOP: ; preds = %IF31, %main_body + %temp12.0 = phi float [ 0.000000e+00, %main_body ], [ %47, %IF31 ] + %temp6.0 = phi float [ %22, %main_body ], [ %temp6.1, %IF31 ] + %temp5.0 = phi float [ %20, %main_body ], [ %temp5.1, %IF31 ] + %temp4.0 = phi float [ %18, %main_body ], [ %temp4.1, %IF31 ] + %23 = bitcast float %temp12.0 to i32 + %24 = bitcast float %6 to i32 + %25 = icmp sge i32 %23, %24 + %26 = sext i1 %25 to i32 + %27 = bitcast i32 %26 to float + %28 = bitcast float %27 to i32 + %29 = icmp ne i32 %28, 0 + br i1 %29, label %IF, label %LOOP29 + +IF: ; preds = %LOOP + %30 = call float @llvm.AMDIL.clamp.(float %temp4.0, float 0.000000e+00, float 1.000000e+00) + %31 = call float @llvm.AMDIL.clamp.(float %temp5.0, float 0.000000e+00, float 1.000000e+00) + %32 = call float @llvm.AMDIL.clamp.(float %temp6.0, float 0.000000e+00, float 1.000000e+00) + %33 = call float @llvm.AMDIL.clamp.(float 1.000000e+00, float 0.000000e+00, float 1.000000e+00) + %34 = insertelement <4 x float> undef, float %30, i32 0 + %35 = insertelement <4 x float> %34, float %31, i32 1 + %36 = insertelement <4 x float> %35, float %32, i32 2 + %37 = insertelement <4 x float> %36, float %33, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %37, i32 0, i32 0) + ret void + +LOOP29: ; preds = %LOOP, %ENDIF30 + %temp6.1 = phi float [ %temp4.1, %ENDIF30 ], [ %temp6.0, %LOOP ] + %temp5.1 = phi float [ %temp6.1, %ENDIF30 ], [ %temp5.0, %LOOP ] + %temp4.1 = phi float [ %temp5.1, %ENDIF30 ], [ %temp4.0, %LOOP ] + %temp20.0 = phi float [ %50, %ENDIF30 ], [ 0.000000e+00, %LOOP ] + %38 = bitcast float %temp20.0 to i32 + %39 = bitcast float %16 to i32 + %40 = icmp sge i32 %38, %39 + %41 = sext i1 %40 to i32 + %42 = bitcast i32 %41 to float + %43 = bitcast float %42 to i32 + %44 = icmp ne i32 %43, 0 + br i1 %44, label %IF31, label %ENDIF30 + +IF31: ; preds = %LOOP29 + %45 = bitcast float %temp12.0 to i32 + %46 = add i32 %45, 1 + %47 = bitcast i32 %46 to float + br label %LOOP + +ENDIF30: ; preds = %LOOP29 + %48 = bitcast float %temp20.0 to i32 + %49 = add i32 %48, 1 + %50 = bitcast i32 %49 to float + br label %LOOP29 +} + +declare float @llvm.AMDIL.clamp.(float, float, float) #0 + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) + +attributes #0 = { readnone } diff --git a/test/CodeGen/R600/schedule-fs-loop.ll b/test/CodeGen/R600/schedule-fs-loop.ll new file mode 100644 index 0000000000..d142cacd43 --- /dev/null +++ b/test/CodeGen/R600/schedule-fs-loop.ll @@ -0,0 +1,55 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = load <4 x float> addrspace(9)* null + %1 = extractelement <4 x float> %0, i32 3 + %2 = fptosi float %1 to i32 + %3 = bitcast i32 %2 to float + %4 = load <4 x float> addrspace(9)* null + %5 = extractelement <4 x float> %4, i32 0 + %6 = load <4 x float> addrspace(9)* null + %7 = extractelement <4 x float> %6, i32 1 + %8 = load <4 x float> addrspace(9)* null + %9 = extractelement <4 x float> %8, i32 2 + br label %LOOP + +LOOP: ; preds = %ENDIF, %main_body + %temp4.0 = phi float [ %5, %main_body ], [ %temp5.0, %ENDIF ] + %temp5.0 = phi float [ %7, %main_body ], [ %temp6.0, %ENDIF ] + %temp6.0 = phi float [ %9, %main_body ], [ %temp4.0, %ENDIF ] + %temp8.0 = phi float [ 0.000000e+00, %main_body ], [ %27, %ENDIF ] + %10 = bitcast float %temp8.0 to i32 + %11 = bitcast float %3 to i32 + %12 = icmp sge i32 %10, %11 + %13 = sext i1 %12 to i32 + %14 = bitcast i32 %13 to float + %15 = bitcast float %14 to i32 + %16 = icmp ne i32 %15, 0 + br i1 %16, label %IF, label %ENDIF + +IF: ; preds = %LOOP + %17 = call float @llvm.AMDIL.clamp.(float %temp4.0, float 0.000000e+00, float 1.000000e+00) + %18 = call float @llvm.AMDIL.clamp.(float %temp5.0, float 0.000000e+00, float 1.000000e+00) + %19 = call float @llvm.AMDIL.clamp.(float %temp6.0, float 0.000000e+00, float 1.000000e+00) + %20 = call float @llvm.AMDIL.clamp.(float 1.000000e+00, float 0.000000e+00, float 1.000000e+00) + %21 = insertelement <4 x float> undef, float %17, i32 0 + %22 = insertelement <4 x float> %21, float %18, i32 1 + %23 = insertelement <4 x float> %22, float %19, i32 2 + %24 = insertelement <4 x float> %23, float %20, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %24, i32 0, i32 0) + ret void + +ENDIF: ; preds = %LOOP + %25 = bitcast float %temp8.0 to i32 + %26 = add i32 %25, 1 + %27 = bitcast i32 %26 to float + br label %LOOP +} + +declare float @llvm.AMDIL.clamp.(float, float, float) #0 + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) + +attributes #0 = { readnone } diff --git a/test/CodeGen/R600/schedule-if-2.ll b/test/CodeGen/R600/schedule-if-2.ll new file mode 100644 index 0000000000..6afd677292 --- /dev/null +++ b/test/CodeGen/R600/schedule-if-2.ll @@ -0,0 +1,94 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 2) + %1 = extractelement <4 x float> %0, i32 0 + %2 = fadd float 1.000000e+03, %1 + %3 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %4 = extractelement <4 x float> %3, i32 0 + %5 = bitcast float %4 to i32 + %6 = icmp eq i32 %5, 0 + %7 = sext i1 %6 to i32 + %8 = bitcast i32 %7 to float + %9 = bitcast float %8 to i32 + %10 = icmp ne i32 %9, 0 + br i1 %10, label %IF, label %ELSE + +IF: ; preds = %main_body + %11 = call float @fabs(float %2) + %12 = fcmp ueq float %11, 0x7FF0000000000000 + %13 = select i1 %12, float 1.000000e+00, float 0.000000e+00 + %14 = fsub float -0.000000e+00, %13 + %15 = fptosi float %14 to i32 + %16 = bitcast i32 %15 to float + %17 = bitcast float %16 to i32 + %18 = icmp ne i32 %17, 0 + %. = select i1 %18, float 0x36A0000000000000, float 0.000000e+00 + %19 = fcmp une float %2, %2 + %20 = select i1 %19, float 1.000000e+00, float 0.000000e+00 + %21 = fsub float -0.000000e+00, %20 + %22 = fptosi float %21 to i32 + %23 = bitcast i32 %22 to float + %24 = bitcast float %23 to i32 + %25 = icmp ne i32 %24, 0 + %temp8.0 = select i1 %25, float 0x36A0000000000000, float 0.000000e+00 + %26 = bitcast float %. to i32 + %27 = sitofp i32 %26 to float + %28 = bitcast float %temp8.0 to i32 + %29 = sitofp i32 %28 to float + %30 = fcmp ugt float %2, 0.000000e+00 + %31 = select i1 %30, float 1.000000e+00, float %2 + %32 = fcmp uge float %31, 0.000000e+00 + %33 = select i1 %32, float %31, float -1.000000e+00 + %34 = fadd float %33, 1.000000e+00 + %35 = fmul float %34, 5.000000e-01 + br label %ENDIF + +ELSE: ; preds = %main_body + %36 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %37 = extractelement <4 x float> %36, i32 0 + %38 = bitcast float %37 to i32 + %39 = icmp eq i32 %38, 1 + %40 = sext i1 %39 to i32 + %41 = bitcast i32 %40 to float + %42 = bitcast float %41 to i32 + %43 = icmp ne i32 %42, 0 + br i1 %43, label %IF23, label %ENDIF + +ENDIF: ; preds = %IF23, %ELSE, %IF + %temp4.0 = phi float [ %2, %IF ], [ %56, %IF23 ], [ 0.000000e+00, %ELSE ] + %temp5.0 = phi float [ %27, %IF ], [ %60, %IF23 ], [ 0.000000e+00, %ELSE ] + %temp6.0 = phi float [ %29, %IF ], [ 0.000000e+00, %ELSE ], [ 0.000000e+00, %IF23 ] + %temp7.0 = phi float [ %35, %IF ], [ 0.000000e+00, %ELSE ], [ 0.000000e+00, %IF23 ] + %44 = insertelement <4 x float> undef, float %temp4.0, i32 0 + %45 = insertelement <4 x float> %44, float %temp5.0, i32 1 + %46 = insertelement <4 x float> %45, float %temp6.0, i32 2 + %47 = insertelement <4 x float> %46, float %temp7.0, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %47, i32 0, i32 0) + ret void + +IF23: ; preds = %ELSE + %48 = fcmp ult float 0.000000e+00, %2 + %49 = select i1 %48, float 1.000000e+00, float 0.000000e+00 + %50 = fsub float -0.000000e+00, %49 + %51 = fptosi float %50 to i32 + %52 = bitcast i32 %51 to float + %53 = bitcast float %52 to i32 + %54 = icmp ne i32 %53, 0 + %.28 = select i1 %54, float 0x36A0000000000000, float 0.000000e+00 + %55 = bitcast float %.28 to i32 + %56 = sitofp i32 %55 to float + %57 = load <4 x float> addrspace(8)* null + %58 = extractelement <4 x float> %57, i32 0 + %59 = fsub float -0.000000e+00, %58 + %60 = fadd float %2, %59 + br label %ENDIF +} + +declare float @fabs(float) #0 + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) + +attributes #0 = { readonly } diff --git a/test/CodeGen/R600/schedule-if.ll b/test/CodeGen/R600/schedule-if.ll new file mode 100644 index 0000000000..347d92fd6a --- /dev/null +++ b/test/CodeGen/R600/schedule-if.ll @@ -0,0 +1,46 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %1 = extractelement <4 x float> %0, i32 0 + %2 = bitcast float %1 to i32 + %3 = icmp eq i32 %2, 0 + %4 = sext i1 %3 to i32 + %5 = bitcast i32 %4 to float + %6 = bitcast float %5 to i32 + %7 = icmp ne i32 %6, 0 + br i1 %7, label %ENDIF, label %ELSE + +ELSE: ; preds = %main_body + %8 = load <4 x float> addrspace(8)* getelementptr ([1024 x <4 x float>] addrspace(8)* null, i64 0, i32 1) + %9 = extractelement <4 x float> %8, i32 0 + %10 = bitcast float %9 to i32 + %11 = icmp eq i32 %10, 1 + %12 = sext i1 %11 to i32 + %13 = bitcast i32 %12 to float + %14 = bitcast float %13 to i32 + %15 = icmp ne i32 %14, 0 + br i1 %15, label %IF13, label %ENDIF + +ENDIF: ; preds = %IF13, %ELSE, %main_body + %temp.0 = phi float [ 1.000000e+03, %main_body ], [ 1.000000e+00, %IF13 ], [ 0.000000e+00, %ELSE ] + %temp1.0 = phi float [ 0.000000e+00, %main_body ], [ %23, %IF13 ], [ 0.000000e+00, %ELSE ] + %temp3.0 = phi float [ 1.000000e+00, %main_body ], [ 0.000000e+00, %ELSE ], [ 0.000000e+00, %IF13 ] + %16 = insertelement <4 x float> undef, float %temp.0, i32 0 + %17 = insertelement <4 x float> %16, float %temp1.0, i32 1 + %18 = insertelement <4 x float> %17, float 0.000000e+00, i32 2 + %19 = insertelement <4 x float> %18, float %temp3.0, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %19, i32 0, i32 0) + ret void + +IF13: ; preds = %ELSE + %20 = load <4 x float> addrspace(8)* null + %21 = extractelement <4 x float> %20, i32 0 + %22 = fsub float -0.000000e+00, %21 + %23 = fadd float 1.000000e+03, %22 + br label %ENDIF +} + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) diff --git a/test/CodeGen/R600/schedule-vs-if-nested-loop.ll b/test/CodeGen/R600/schedule-vs-if-nested-loop.ll new file mode 100644 index 0000000000..44b7c2f680 --- /dev/null +++ b/test/CodeGen/R600/schedule-vs-if-nested-loop.ll @@ -0,0 +1,134 @@ +;RUN: llc < %s -march=r600 -mcpu=cayman -stress-sched -verify-misched +;REQUIRES: asserts + +define void @main() { +main_body: + %0 = call float @llvm.R600.load.input(i32 4) + %1 = call float @llvm.R600.load.input(i32 5) + %2 = call float @llvm.R600.load.input(i32 6) + %3 = call float @llvm.R600.load.input(i32 7) + %4 = fcmp ult float %0, 0.000000e+00 + %5 = select i1 %4, float 1.000000e+00, float 0.000000e+00 + %6 = fsub float -0.000000e+00, %5 + %7 = fptosi float %6 to i32 + %8 = bitcast i32 %7 to float + %9 = bitcast float %8 to i32 + %10 = icmp ne i32 %9, 0 + br i1 %10, label %LOOP, label %ENDIF + +ENDIF: ; preds = %ENDIF16, %LOOP, %main_body + %temp.0 = phi float [ 0.000000e+00, %main_body ], [ %temp.1, %LOOP ], [ %temp.1, %ENDIF16 ] + %temp1.0 = phi float [ 1.000000e+00, %main_body ], [ %temp1.1, %LOOP ], [ %temp1.1, %ENDIF16 ] + %temp2.0 = phi float [ 0.000000e+00, %main_body ], [ %temp2.1, %LOOP ], [ %temp2.1, %ENDIF16 ] + %temp3.0 = phi float [ 0.000000e+00, %main_body ], [ %temp3.1, %LOOP ], [ %temp3.1, %ENDIF16 ] + %11 = load <4 x float> addrspace(9)* null + %12 = extractelement <4 x float> %11, i32 0 + %13 = fmul float %12, %0 + %14 = load <4 x float> addrspace(9)* null + %15 = extractelement <4 x float> %14, i32 1 + %16 = fmul float %15, %0 + %17 = load <4 x float> addrspace(9)* null + %18 = extractelement <4 x float> %17, i32 2 + %19 = fmul float %18, %0 + %20 = load <4 x float> addrspace(9)* null + %21 = extractelement <4 x float> %20, i32 3 + %22 = fmul float %21, %0 + %23 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 1) + %24 = extractelement <4 x float> %23, i32 0 + %25 = fmul float %24, %1 + %26 = fadd float %25, %13 + %27 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 1) + %28 = extractelement <4 x float> %27, i32 1 + %29 = fmul float %28, %1 + %30 = fadd float %29, %16 + %31 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 1) + %32 = extractelement <4 x float> %31, i32 2 + %33 = fmul float %32, %1 + %34 = fadd float %33, %19 + %35 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 1) + %36 = extractelement <4 x float> %35, i32 3 + %37 = fmul float %36, %1 + %38 = fadd float %37, %22 + %39 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 2) + %40 = extractelement <4 x float> %39, i32 0 + %41 = fmul float %40, %2 + %42 = fadd float %41, %26 + %43 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 2) + %44 = extractelement <4 x float> %43, i32 1 + %45 = fmul float %44, %2 + %46 = fadd float %45, %30 + %47 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 2) + %48 = extractelement <4 x float> %47, i32 2 + %49 = fmul float %48, %2 + %50 = fadd float %49, %34 + %51 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 2) + %52 = extractelement <4 x float> %51, i32 3 + %53 = fmul float %52, %2 + %54 = fadd float %53, %38 + %55 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 3) + %56 = extractelement <4 x float> %55, i32 0 + %57 = fmul float %56, %3 + %58 = fadd float %57, %42 + %59 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 3) + %60 = extractelement <4 x float> %59, i32 1 + %61 = fmul float %60, %3 + %62 = fadd float %61, %46 + %63 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 3) + %64 = extractelement <4 x float> %63, i32 2 + %65 = fmul float %64, %3 + %66 = fadd float %65, %50 + %67 = load <4 x float> addrspace(9)* getelementptr ([1024 x <4 x float>] addrspace(9)* null, i64 0, i32 3) + %68 = extractelement <4 x float> %67, i32 3 + %69 = fmul float %68, %3 + %70 = fadd float %69, %54 + %71 = insertelement <4 x float> undef, float %58, i32 0 + %72 = insertelement <4 x float> %71, float %62, i32 1 + %73 = insertelement <4 x float> %72, float %66, i32 2 + %74 = insertelement <4 x float> %73, float %70, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %74, i32 60, i32 1) + %75 = insertelement <4 x float> undef, float %temp.0, i32 0 + %76 = insertelement <4 x float> %75, float %temp1.0, i32 1 + %77 = insertelement <4 x float> %76, float %temp2.0, i32 2 + %78 = insertelement <4 x float> %77, float %temp3.0, i32 3 + call void @llvm.R600.store.swizzle(<4 x float> %78, i32 0, i32 2) + ret void + +LOOP: ; preds = %main_body, %ENDIF19 + %temp.1 = phi float [ %93, %ENDIF19 ], [ 0.000000e+00, %main_body ] + %temp1.1 = phi float [ %94, %ENDIF19 ], [ 1.000000e+00, %main_body ] + %temp2.1 = phi float [ %95, %ENDIF19 ], [ 0.000000e+00, %main_body ] + %temp3.1 = phi float [ %96, %ENDIF19 ], [ 0.000000e+00, %main_body ] + %temp4.0 = phi float [ %97, %ENDIF19 ], [ -2.000000e+00, %main_body ] + %79 = fcmp uge float %temp4.0, %0 + %80 = select i1 %79, float 1.000000e+00, float 0.000000e+00 + %81 = fsub float -0.000000e+00, %80 + %82 = fptosi float %81 to i32 + %83 = bitcast i32 %82 to float + %84 = bitcast float %83 to i32 + %85 = icmp ne i32 %84, 0 + br i1 %85, label %ENDIF, label %ENDIF16 + +ENDIF16: ; preds = %LOOP + %86 = fcmp une float %2, %temp4.0 + %87 = select i1 %86, float 1.000000e+00, float 0.000000e+00 + %88 = fsub float -0.000000e+00, %87 + %89 = fptosi float %88 to i32 + %90 = bitcast i32 %89 to float + %91 = bitcast float %90 to i32 + %92 = icmp ne i32 %91, 0 + br i1 %92, label %ENDIF, label %ENDIF19 + +ENDIF19: ; preds = %ENDIF16 + %93 = fadd float %temp.1, 1.000000e+00 + %94 = fadd float %temp1.1, 0.000000e+00 + %95 = fadd float %temp2.1, 0.000000e+00 + %96 = fadd float %temp3.1, 0.000000e+00 + %97 = fadd float %temp4.0, 1.000000e+00 + br label %LOOP +} + +declare float @llvm.R600.load.input(i32) #0 + +declare void @llvm.R600.store.swizzle(<4 x float>, i32, i32) + +attributes #0 = { readnone } diff --git a/test/CodeGen/R600/sdiv.ll b/test/CodeGen/R600/sdiv.ll new file mode 100644 index 0000000000..3556facfba --- /dev/null +++ b/test/CodeGen/R600/sdiv.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; The code generated by sdiv is long and complex and may frequently change. +; The goal of this test is to make sure the ISel doesn't fail. +; +; This program was previously failing to compile when one of the selectcc +; opcodes generated by the sdiv lowering was being legalized and optimized to: +; selectcc Remainder -1, 0, -1, SETGT +; This was fixed by adding an additional pattern in R600Instructions.td to +; match this pattern with a CNDGE_INT. + +; CHECK: RETURN + +define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %den_ptr = getelementptr i32 addrspace(1)* %in, i32 1 + %num = load i32 addrspace(1) * %in + %den = load i32 addrspace(1) * %den_ptr + %result = sdiv i32 %num, %den + store i32 %result, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/selectcc-icmp-select-float.ll b/test/CodeGen/R600/selectcc-icmp-select-float.ll new file mode 100644 index 0000000000..359ca1e6f8 --- /dev/null +++ b/test/CodeGen/R600/selectcc-icmp-select-float.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; Note additional optimizations may cause this SGT to be replaced with a +; CND* instruction. +; CHECK: SETGT_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], literal.x, -1}} +; Test a selectcc with i32 LHS/RHS and float True/False + +define void @test(float addrspace(1)* %out, i32 addrspace(1)* %in) { +entry: + %0 = load i32 addrspace(1)* %in + %1 = icmp sge i32 %0, 0 + %2 = select i1 %1, float 1.0, float 0.0 + store float %2, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/selectcc-opt.ll b/test/CodeGen/R600/selectcc-opt.ll new file mode 100644 index 0000000000..02d9353904 --- /dev/null +++ b/test/CodeGen/R600/selectcc-opt.ll @@ -0,0 +1,64 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: @test_a +; CHECK-NOT: CND +; CHECK: SET{{[NEQGTL]+}}_DX10 + +define void @test_a(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ult float %in, 0.000000e+00 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + %4 = bitcast i32 %3 to float + %5 = bitcast float %4 to i32 + %6 = icmp ne i32 %5, 0 + br i1 %6, label %IF, label %ENDIF + +IF: + %7 = getelementptr i32 addrspace(1)* %out, i32 1 + store i32 0, i32 addrspace(1)* %7 + br label %ENDIF + +ENDIF: + store i32 0, i32 addrspace(1)* %out + ret void +} + +; Same as test_a, but the branch labels are swapped to produce the inverse cc +; for the icmp instruction + +; CHECK: @test_b +; CHECK: SET{{[GTEQN]+}}_DX10 +; CHECK-NEXT: PRED_ +define void @test_b(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ult float %in, 0.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + %4 = bitcast i32 %3 to float + %5 = bitcast float %4 to i32 + %6 = icmp ne i32 %5, 0 + br i1 %6, label %ENDIF, label %IF + +IF: + %7 = getelementptr i32 addrspace(1)* %out, i32 1 + store i32 0, i32 addrspace(1)* %7 + br label %ENDIF + +ENDIF: + store i32 0, i32 addrspace(1)* %out + ret void +} + +; Test a CND*_INT instruction with float true/false values +; CHECK: @test_c +; CHECK: CND{{[GTE]+}}_INT +define void @test_c(float addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sgt i32 %in, 0 + %1 = select i1 %0, float 2.0, float 3.0 + store float %1, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/selectcc_cnde.ll b/test/CodeGen/R600/selectcc_cnde.ll new file mode 100644 index 0000000000..f0a0f512ba --- /dev/null +++ b/test/CodeGen/R600/selectcc_cnde.ll @@ -0,0 +1,11 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK-NOT: SETE +;CHECK: CNDE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], 1.0, literal.x, [-0-9]+\(2.0}} +define void @test(float addrspace(1)* %out, float addrspace(1)* %in) { + %1 = load float addrspace(1)* %in + %2 = fcmp oeq float %1, 0.0 + %3 = select i1 %2, float 1.0, float 2.0 + store float %3, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/selectcc_cnde_int.ll b/test/CodeGen/R600/selectcc_cnde_int.ll new file mode 100644 index 0000000000..b38078e26d --- /dev/null +++ b/test/CodeGen/R600/selectcc_cnde_int.ll @@ -0,0 +1,11 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK-NOT: SETE_INT +;CHECK: CNDE_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], 1, literal.x, 2}} +define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %1 = load i32 addrspace(1)* %in + %2 = icmp eq i32 %1, 0 + %3 = select i1 %2, i32 1, i32 2 + store i32 %3, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/set-dx10.ll b/test/CodeGen/R600/set-dx10.ll new file mode 100644 index 0000000000..54febcf0e6 --- /dev/null +++ b/test/CodeGen/R600/set-dx10.ll @@ -0,0 +1,137 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; These tests check that floating point comparisons which are used by select +; to store integer true (-1) and false (0) values are lowered to one of the +; SET*DX10 instructions. + +; CHECK: @fcmp_une_select_fptosi +; CHECK: SETNE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_une_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp une float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_une_select_i32 +; CHECK: SETNE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_une_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp une float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ueq_select_fptosi +; CHECK: SETE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_ueq_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ueq float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ueq_select_i32 +; CHECK: SETE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_ueq_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ueq float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ugt_select_fptosi +; CHECK: SETGT_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_ugt_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ugt float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ugt_select_i32 +; CHECK: SETGT_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_ugt_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ugt float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_uge_select_fptosi +; CHECK: SETGE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_uge_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp uge float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_uge_select_i32 +; CHECK: SETGE_DX10 T{{[0-9]+\.[XYZW]}}, T{{[0-9]+\.[XYZW]}}, literal.x, 1084227584(5.000000e+00) +define void @fcmp_uge_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp uge float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ule_select_fptosi +; CHECK: SETGE_DX10 T{{[0-9]+\.[XYZW]}}, literal.x, T{{[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @fcmp_ule_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ule float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ule_select_i32 +; CHECK: SETGE_DX10 T{{[0-9]+\.[XYZW]}}, literal.x, T{{[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @fcmp_ule_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ule float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ult_select_fptosi +; CHECK: SETGT_DX10 T{{[0-9]+\.[XYZW]}}, literal.x, T{{[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @fcmp_ult_select_fptosi(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ult float %in, 5.0 + %1 = select i1 %0, float 1.000000e+00, float 0.000000e+00 + %2 = fsub float -0.000000e+00, %1 + %3 = fptosi float %2 to i32 + store i32 %3, i32 addrspace(1)* %out + ret void +} + +; CHECK: @fcmp_ult_select_i32 +; CHECK: SETGT_DX10 T{{[0-9]+\.[XYZW]}}, literal.x, T{{[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @fcmp_ult_select_i32(i32 addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ult float %in, 5.0 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/setcc.v4i32.ll b/test/CodeGen/R600/setcc.v4i32.ll new file mode 100644 index 0000000000..0752f2e63d --- /dev/null +++ b/test/CodeGen/R600/setcc.v4i32.ll @@ -0,0 +1,12 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s +;CHECK: SETE_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32> addrspace(1) * %in + %b = load <4 x i32> addrspace(1) * %b_ptr + %result = icmp eq <4 x i32> %a, %b + %sext = sext <4 x i1> %result to <4 x i32> + store <4 x i32> %sext, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/short-args.ll b/test/CodeGen/R600/short-args.ll new file mode 100644 index 0000000000..b69e327bf6 --- /dev/null +++ b/test/CodeGen/R600/short-args.ll @@ -0,0 +1,41 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: @i8_arg +; CHECK: VTX_READ_8 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @i8_arg(i32 addrspace(1)* nocapture %out, i8 %in) nounwind { +entry: + %0 = zext i8 %in to i32 + store i32 %0, i32 addrspace(1)* %out, align 4 + ret void +} + +; CHECK: @i8_zext_arg +; CHECK: VTX_READ_8 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @i8_zext_arg(i32 addrspace(1)* nocapture %out, i8 zeroext %in) nounwind { +entry: + %0 = zext i8 %in to i32 + store i32 %0, i32 addrspace(1)* %out, align 4 + ret void +} + +; CHECK: @i16_arg +; CHECK: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @i16_arg(i32 addrspace(1)* nocapture %out, i16 %in) nounwind { +entry: + %0 = zext i16 %in to i32 + store i32 %0, i32 addrspace(1)* %out, align 4 + ret void +} + +; CHECK: @i16_zext_arg +; CHECK: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}} + +define void @i16_zext_arg(i32 addrspace(1)* nocapture %out, i16 zeroext %in) nounwind { +entry: + %0 = zext i16 %in to i32 + store i32 %0, i32 addrspace(1)* %out, align 4 + ret void +} diff --git a/test/CodeGen/R600/store.v4f32.ll b/test/CodeGen/R600/store.v4f32.ll new file mode 100644 index 0000000000..8b0d244459 --- /dev/null +++ b/test/CodeGen/R600/store.v4f32.ll @@ -0,0 +1,9 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: RAT_WRITE_CACHELESS_128 T{{[0-9]+\.XYZW, T[0-9]+\.X}}, 1 + +define void @test(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %1 = load <4 x float> addrspace(1) * %in + store <4 x float> %1, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/store.v4i32.ll b/test/CodeGen/R600/store.v4i32.ll new file mode 100644 index 0000000000..a659815dde --- /dev/null +++ b/test/CodeGen/R600/store.v4i32.ll @@ -0,0 +1,9 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;CHECK: RAT_WRITE_CACHELESS_128 T{{[0-9]+\.XYZW, T[0-9]+\.X}}, 1 + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %1 = load <4 x i32> addrspace(1) * %in + store <4 x i32> %1, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/udiv.v4i32.ll b/test/CodeGen/R600/udiv.v4i32.ll new file mode 100644 index 0000000000..47657a6be7 --- /dev/null +++ b/test/CodeGen/R600/udiv.v4i32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;The code generated by udiv is long and complex and may frequently change. +;The goal of this test is to make sure the ISel doesn't fail when it gets +;a v4i32 udiv +;CHECK: RETURN + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32> addrspace(1) * %in + %b = load <4 x i32> addrspace(1) * %b_ptr + %result = udiv <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/unsupported-cc.ll b/test/CodeGen/R600/unsupported-cc.ll new file mode 100644 index 0000000000..b48c591518 --- /dev/null +++ b/test/CodeGen/R600/unsupported-cc.ll @@ -0,0 +1,83 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; These tests are for condition codes that are not supported by the hardware + +; CHECK: @slt +; CHECK: SETGT_INT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 5(7.006492e-45) +define void @slt(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp slt i32 %in, 5 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @ult_i32 +; CHECK: SETGT_UINT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 5(7.006492e-45) +define void @ult_i32(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp ult i32 %in, 5 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @ult_float +; CHECK: SETGT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @ult_float(float addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ult float %in, 5.0 + %1 = select i1 %0, float 1.0, float 0.0 + store float %1, float addrspace(1)* %out + ret void +} + +; CHECK: @olt +; CHECK: SETGT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @olt(float addrspace(1)* %out, float %in) { +entry: + %0 = fcmp olt float %in, 5.0 + %1 = select i1 %0, float 1.0, float 0.0 + store float %1, float addrspace(1)* %out + ret void +} + +; CHECK: @sle +; CHECK: SETGT_INT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 6(8.407791e-45) +define void @sle(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp sle i32 %in, 5 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @ule_i32 +; CHECK: SETGT_UINT T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 6(8.407791e-45) +define void @ule_i32(i32 addrspace(1)* %out, i32 %in) { +entry: + %0 = icmp ule i32 %in, 5 + %1 = select i1 %0, i32 -1, i32 0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; CHECK: @ule_float +; CHECK: SETGE T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @ule_float(float addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ule float %in, 5.0 + %1 = select i1 %0, float 1.0, float 0.0 + store float %1, float addrspace(1)* %out + ret void +} + +; CHECK: @ole +; CHECK: SETGE T{{[0-9]+\.[XYZW]}}, literal.x, {{T[0-9]+\.[XYZW]}}, 1084227584(5.000000e+00) +define void @ole(float addrspace(1)* %out, float %in) { +entry: + %0 = fcmp ole float %in, 5.0 + %1 = select i1 %0, float 1.0, float 0.0 + store float %1, float addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/urem.v4i32.ll b/test/CodeGen/R600/urem.v4i32.ll new file mode 100644 index 0000000000..2e7388caa6 --- /dev/null +++ b/test/CodeGen/R600/urem.v4i32.ll @@ -0,0 +1,15 @@ +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +;The code generated by urem is long and complex and may frequently change. +;The goal of this test is to make sure the ISel doesn't fail when it gets +;a v4i32 urem +;CHECK: RETURN + +define void @test(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32> addrspace(1) * %in + %b = load <4 x i32> addrspace(1) * %b_ptr + %result = urem <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/vec4-expand.ll b/test/CodeGen/R600/vec4-expand.ll new file mode 100644 index 0000000000..8f62bc6929 --- /dev/null +++ b/test/CodeGen/R600/vec4-expand.ll @@ -0,0 +1,53 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s + +; CHECK: @fp_to_sint +; CHECK: FLT_TO_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @fp_to_sint(<4 x i32> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %value = load <4 x float> addrspace(1) * %in + %result = fptosi <4 x float> %value to <4 x i32> + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} + +; CHECK: @fp_to_uint +; CHECK: FLT_TO_UINT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_UINT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_UINT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: FLT_TO_UINT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @fp_to_uint(<4 x i32> addrspace(1)* %out, <4 x float> addrspace(1)* %in) { + %value = load <4 x float> addrspace(1) * %in + %result = fptoui <4 x float> %value to <4 x i32> + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} + +; CHECK: @sint_to_fp +; CHECK: INT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: INT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: INT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: INT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @sint_to_fp(<4 x float> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %value = load <4 x i32> addrspace(1) * %in + %result = sitofp <4 x i32> %value to <4 x float> + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} + +; CHECK: @uint_to_fp +; CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; CHECK: UINT_TO_FLT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} + +define void @uint_to_fp(<4 x float> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %value = load <4 x i32> addrspace(1) * %in + %result = uitofp <4 x i32> %value to <4 x float> + store <4 x float> %result, <4 x float> addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/SI/sanity.ll b/test/CodeGen/SI/sanity.ll new file mode 100644 index 0000000000..62cdcf5eca --- /dev/null +++ b/test/CodeGen/SI/sanity.ll @@ -0,0 +1,37 @@ +;RUN: llc < %s -march=r600 -mcpu=SI | FileCheck %s + +; CHECK: S_ENDPGM + +define void @main() { +main_body: + call void @llvm.AMDGPU.shader.type(i32 1) + %0 = load <4 x i32> addrspace(2)* addrspace(8)* inttoptr (i32 6 to <4 x i32> addrspace(2)* addrspace(8)*) + %1 = getelementptr <4 x i32> addrspace(2)* %0, i32 0 + %2 = load <4 x i32> addrspace(2)* %1 + %3 = call i32 @llvm.SI.vs.load.buffer.index() + %4 = call <4 x float> @llvm.SI.vs.load.input(<4 x i32> %2, i32 0, i32 %3) + %5 = extractelement <4 x float> %4, i32 0 + %6 = extractelement <4 x float> %4, i32 1 + %7 = extractelement <4 x float> %4, i32 2 + %8 = extractelement <4 x float> %4, i32 3 + %9 = load <4 x i32> addrspace(2)* addrspace(8)* inttoptr (i32 6 to <4 x i32> addrspace(2)* addrspace(8)*) + %10 = getelementptr <4 x i32> addrspace(2)* %9, i32 1 + %11 = load <4 x i32> addrspace(2)* %10 + %12 = call i32 @llvm.SI.vs.load.buffer.index() + %13 = call <4 x float> @llvm.SI.vs.load.input(<4 x i32> %11, i32 0, i32 %12) + %14 = extractelement <4 x float> %13, i32 0 + %15 = extractelement <4 x float> %13, i32 1 + %16 = extractelement <4 x float> %13, i32 2 + %17 = extractelement <4 x float> %13, i32 3 + call void @llvm.SI.export(i32 15, i32 0, i32 0, i32 32, i32 0, float %14, float %15, float %16, float %17) + call void @llvm.SI.export(i32 15, i32 0, i32 1, i32 12, i32 0, float %5, float %6, float %7, float %8) + ret void +} + +declare void @llvm.AMDGPU.shader.type(i32) + +declare i32 @llvm.SI.vs.load.buffer.index() readnone + +declare <4 x float> @llvm.SI.vs.load.input(<4 x i32>, i32, i32) + +declare void @llvm.SI.export(i32, i32, i32, i32, i32, float, float, float, float) diff --git a/test/CodeGen/SPARC/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/SPARC/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 3b644986f2..0000000000 --- a/test/CodeGen/SPARC/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=sparc -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/SPARC/DbgValueOtherTargets.test b/test/CodeGen/SPARC/DbgValueOtherTargets.test new file mode 100644 index 0000000000..749a7b5346 --- /dev/null +++ b/test/CodeGen/SPARC/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=sparc -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/Thumb/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/Thumb/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index b9039774d4..0000000000 --- a/test/CodeGen/Thumb/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=thumb -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/Thumb/DbgValueOtherTargets.test b/test/CodeGen/Thumb/DbgValueOtherTargets.test new file mode 100644 index 0000000000..aa31a7c75c --- /dev/null +++ b/test/CodeGen/Thumb/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=thumb -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/Thumb/iabs.ll b/test/CodeGen/Thumb/iabs.ll index 2e77660c45..76224bc534 100644 --- a/test/CodeGen/Thumb/iabs.ll +++ b/test/CodeGen/Thumb/iabs.ll @@ -1,22 +1,20 @@ -; RUN: llc < %s -march=thumb -stats 2>&1 | \ -; RUN: grep "4 .*Number of machine instrs printed" - -;; Integer absolute value, should produce something as good as: -;; Thumb: -;; movs r0, r0 -;; bpl -;; rsb r0, r0, #0 (with opitmization, bpl + rsb is if-converted into rsbmi) -;; bx lr +; RUN: llc < %s -mtriple=thumb-unknown-unknown -filetype=obj -o %t.o +; RUN: llvm-objdump -disassemble -arch=thumb %t.o | FileCheck %s define i32 @test(i32 %a) { %tmp1neg = sub i32 0, %a %b = icmp sgt i32 %a, -1 %abs = select i1 %b, i32 %a, i32 %tmp1neg ret i32 %abs -; CHECK: movs r0, r0 -; CHECK: bpl -; CHECK: rsb r0, r0, #0 -; CHECK: bx lr -} +; This test just checks that 4 instructions were emitted + +; CHECK: {{text}} +; CHECK: 0: +; CHECK-NEXT: 2: +; CHECK-NEXT: 4: +; CHECK-NEXT: 6: + +; CHECK-NOT: 8: +} diff --git a/test/CodeGen/Thumb/stack-coloring-without-frame-ptr.ll b/test/CodeGen/Thumb/stack-coloring-without-frame-ptr.ll new file mode 100644 index 0000000000..3f6407a0a3 --- /dev/null +++ b/test/CodeGen/Thumb/stack-coloring-without-frame-ptr.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -march=thumb -mcpu=arm1022e + +%iterator = type { i8**, i8**, i8**, i8*** } +%insert_iterator = type { %deque*, %iterator } +%deque = type { %iterator, %iterator, i8***, i32 } + +define i32 @test_thumbv5e_fp_elim() nounwind optsize { +entry: + %var1 = alloca %iterator, align 4 + %var2 = alloca %insert_iterator, align 4 + %var3 = alloca %deque, align 4 + + %0 = bitcast %deque* %var3 to i8* + %1 = bitcast %iterator* %var1 to i8* + call void @llvm.lifetime.start(i64 16, i8* %1) nounwind + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %0, i32 16, i32 4, i1 false) + call void @llvm.lifetime.end(i64 16, i8* %1) nounwind + + %2 = bitcast %insert_iterator* %var2 to i8* + call void @llvm.lifetime.start(i64 20, i8* %2) nounwind + + ret i32 0 +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind + +declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind + +declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind diff --git a/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll b/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll new file mode 100644 index 0000000000..502b138f65 --- /dev/null +++ b/test/CodeGen/Thumb2/2013-02-19-tail-call-register-hint.ll @@ -0,0 +1,53 @@ +; RUN: llc < %s -mtriple=thumbv7s-apple-ios6.0.0 -verify-machineinstrs + +; Check to make sure the tail-call return at the end doesn't use a +; callee-saved register. Register hinting from t2LDRDri was getting this +; wrong. The intervening call will force allocation to try a high register +; first, so the hint will attempt to fire, but must be rejected due to +; not being in the allocation order for the tcGPR register class. +; The machine instruction verifier will make sure that all actually worked +; out the way it's supposed to. + +%"myclass" = type { %struct.foo } +%struct.foo = type { i32, [40 x i8] } + +define hidden void @func(i8* %Data) nounwind ssp { + %1 = getelementptr inbounds i8* %Data, i32 12 + %2 = bitcast i8* %1 to %"myclass"* + tail call void @abc(%"myclass"* %2) nounwind + tail call void @def(%"myclass"* %2) nounwind + %3 = getelementptr inbounds i8* %Data, i32 8 + %4 = bitcast i8* %3 to i8** + %5 = load i8** %4, align 4, !tbaa !0 + tail call void @ghi(i8* %5) nounwind + %6 = bitcast i8* %Data to void (i8*)** + %7 = load void (i8*)** %6, align 4, !tbaa !0 + %8 = getelementptr inbounds i8* %Data, i32 4 + %9 = bitcast i8* %8 to i8** + %10 = load i8** %9, align 4, !tbaa !0 + %11 = icmp eq i8* %Data, null + br i1 %11, label %14, label %12 + +; <label>:12 ; preds = %0 + %13 = tail call %"myclass"* @jkl(%"myclass"* %2) nounwind + tail call void @mno(i8* %Data) nounwind + br label %14 + +; <label>:14 ; preds = %12, %0 + tail call void %7(i8* %10) nounwind + ret void +} + +declare void @mno(i8*) + +declare void @def(%"myclass"*) + +declare void @abc(%"myclass"*) + +declare void @ghi(i8*) + +declare %"myclass"* @jkl(%"myclass"*) nounwind + +!0 = metadata !{metadata !"any pointer", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/Thumb2/2013-03-02-vduplane-nonconstant-source-index.ll b/test/CodeGen/Thumb2/2013-03-02-vduplane-nonconstant-source-index.ll new file mode 100644 index 0000000000..937ecc0d66 --- /dev/null +++ b/test/CodeGen/Thumb2/2013-03-02-vduplane-nonconstant-source-index.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s + +define void @bar(<4 x i32>* %p, i32 %lane, <4 x i32> %phitmp) nounwind { +; CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r[[SOURCE:[0-9]+]]:128] +; CHECK: add.w r[[ADDR:[0-9]+]], r[[SOURCE]], {{r[0-9]+}}, lsl #2 +; CHECK: vld1.32 {[[DREG:d[0-9]+]][], [[DREG2:d[0-9]+]][]}, [r[[ADDR]]:32] +; CHECK: vst1.32 {[[DREG]], [[DREG2]]}, [r0] + %val = extractelement <4 x i32> %phitmp, i32 %lane + %r1 = insertelement <4 x i32> undef, i32 %val, i32 1 + %r2 = insertelement <4 x i32> %r1, i32 %val, i32 2 + %r3 = insertelement <4 x i32> %r2, i32 %val, i32 3 + store <4 x i32> %r3, <4 x i32>* %p, align 4 + ret void +} diff --git a/test/CodeGen/Thumb2/2013-03-06-vector-sext-operand-scalarize.ll b/test/CodeGen/Thumb2/2013-03-06-vector-sext-operand-scalarize.ll new file mode 100644 index 0000000000..203815fadc --- /dev/null +++ b/test/CodeGen/Thumb2/2013-03-06-vector-sext-operand-scalarize.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +; Testing that these don't crash/assert. The loop vectorizer can end up +; with odd constructs like this. The code actually generated is incidental. +define <1 x i64> @test_zext(i32 %a) nounwind { +; CHECK: test_zext: + %Cmp = icmp uge i32 %a, 42 + %vec = insertelement <1 x i1> zeroinitializer, i1 %Cmp, i32 0 + %Se = zext <1 x i1> %vec to <1 x i64> + ret <1 x i64> %Se +} + +define <1 x i64> @test_sext(i32 %a) nounwind { +; CHECK: test_sext: + %Cmp = icmp uge i32 %a, 42 + %vec = insertelement <1 x i1> zeroinitializer, i1 %Cmp, i32 0 + %Se = sext <1 x i1> %vec to <1 x i64> + ret <1 x i64> %Se +} diff --git a/test/CodeGen/Thumb2/aligned-spill.ll b/test/CodeGen/Thumb2/aligned-spill.ll index c98ca80985..3a2803f91f 100644 --- a/test/CodeGen/Thumb2/aligned-spill.ll +++ b/test/CodeGen/Thumb2/aligned-spill.ll @@ -26,8 +26,8 @@ entry: ; NEON: bic r4, r4, #15 ; Stack pointer must be updated before the spills. ; NEON: mov sp, r4 -; NEON: vst1.64 {d8, d9, d10, d11}, [r4, :128]! -; NEON: vst1.64 {d12, d13, d14, d15}, [r4, :128] +; NEON: vst1.64 {d8, d9, d10, d11}, [r4:128]! +; NEON: vst1.64 {d12, d13, d14, d15}, [r4:128] ; Stack pointer adjustment for the stack frame contents. ; This could legally happen before the spills. ; Since the spill slot is only 8 bytes, technically it would be fine to only @@ -36,8 +36,8 @@ entry: ; NEON: sub sp, #16 ; The epilog is free to use another scratch register than r4. ; NEON: add r[[R4:[0-9]+]], sp, #16 -; NEON: vld1.64 {d8, d9, d10, d11}, [r[[R4]], :128]! -; NEON: vld1.64 {d12, d13, d14, d15}, [r[[R4]], :128] +; NEON: vld1.64 {d8, d9, d10, d11}, [r[[R4]]:128]! +; NEON: vld1.64 {d12, d13, d14, d15}, [r[[R4]]:128] ; The stack pointer restore must happen after the reloads. ; NEON: mov sp, ; NEON: pop @@ -57,8 +57,8 @@ entry: ; NEON: bic r4, r4, #15 ; Stack pointer must be updated before the spills. ; NEON: mov sp, r4 -; NEON: vst1.64 {d8, d9, d10, d11}, [r4, :128]! -; NEON: vst1.64 {d12, d13}, [r4, :128] +; NEON: vst1.64 {d8, d9, d10, d11}, [r4:128]! +; NEON: vst1.64 {d12, d13}, [r4:128] ; NEON: vstr d14, [r4, #16] ; Epilog ; NEON: vld1.64 {d8, d9, d10, d11}, @@ -84,7 +84,7 @@ entry: ; NEON: bic r4, r4, #15 ; Stack pointer must be updated before the spills. ; NEON: mov sp, r4 -; NEON: vst1.64 {d8, d9}, [r4, :128] +; NEON: vst1.64 {d8, d9}, [r4:128] ; NEON: vstr d10, [r4, #16] ; Epilog ; NEON: vld1.64 {d8, d9}, diff --git a/test/CodeGen/Thumb2/cortex-fp.ll b/test/CodeGen/Thumb2/cortex-fp.ll index b7df2fbf54..f6cea72cae 100644 --- a/test/CodeGen/Thumb2/cortex-fp.ll +++ b/test/CodeGen/Thumb2/cortex-fp.ll @@ -7,7 +7,7 @@ define float @foo(float %a, float %b) { entry: ; CHECK: foo ; CORTEXM3: blx ___mulsf3 -; CORTEXM4: vmul.f32 s0, s2, s0 +; CORTEXM4: vmul.f32 s ; CORTEXA8: vmul.f32 d %0 = fmul float %a, %b ret float %0 diff --git a/test/CodeGen/Thumb2/crash.ll b/test/CodeGen/Thumb2/crash.ll index cb4d08058f..6ce0b82b94 100644 --- a/test/CodeGen/Thumb2/crash.ll +++ b/test/CodeGen/Thumb2/crash.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -verify-machineinstrs +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -verify-machineinstrs -O0 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" target triple = "thumbv7-apple-darwin10" @@ -76,3 +77,11 @@ entry: store i32 %num, i32* %p2, align 4 ret void } + +; Check RAFast handling of inline assembly with many dense clobbers. +; The large tuple aliases of the vector registers can cause problems. +define void @rdar13249625(double* nocapture %p) nounwind { + %1 = tail call double asm sideeffect "@ $0", "=w,~{d0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15}"() nounwind + store double %1, double* %p, align 4 + ret void +} diff --git a/test/CodeGen/Thumb2/thumb2-ldr_post.ll b/test/CodeGen/Thumb2/thumb2-ldr_post.ll index 2178eecb43..bce847471b 100644 --- a/test/CodeGen/Thumb2/thumb2-ldr_post.ll +++ b/test/CodeGen/Thumb2/thumb2-ldr_post.ll @@ -1,5 +1,4 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ -; RUN: grep "ldr.*\[.*\]," | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s define i32 @test(i32 %a, i32 %b, i32 %c) { %tmp1 = mul i32 %a, %b ; <i32> [#uses=2] @@ -9,4 +8,5 @@ define i32 @test(i32 %a, i32 %b, i32 %c) { %tmp5 = mul i32 %tmp4, %tmp3 ; <i32> [#uses=1] ret i32 %tmp5 } +; CHECK: ldr r{{.*}}, [{{.*}}], diff --git a/test/CodeGen/Thumb2/thumb2-shifter.ll b/test/CodeGen/Thumb2/thumb2-shifter.ll index 98854a1205..05dd90cfbf 100644 --- a/test/CodeGen/Thumb2/thumb2-shifter.ll +++ b/test/CodeGen/Thumb2/thumb2-shifter.ll @@ -1,24 +1,27 @@ -; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s +; RUN: llc < %s -march=thumb -mcpu=cortex-a8 | FileCheck %s --check-prefix=A8 +; RUN: llc < %s -march=thumb -mcpu=swift | FileCheck %s --check-prefix=SWIFT + +; rdar://12892707 define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) { -; CHECK: t2ADDrs_lsl -; CHECK: add.w r0, r0, r1, lsl #16 +; A8: t2ADDrs_lsl +; A8: add.w r0, r0, r1, lsl #16 %A = shl i32 %Y, 16 %B = add i32 %X, %A ret i32 %B } define i32 @t2ADDrs_lsr(i32 %X, i32 %Y) { -; CHECK: t2ADDrs_lsr -; CHECK: add.w r0, r0, r1, lsr #16 +; A8: t2ADDrs_lsr +; A8: add.w r0, r0, r1, lsr #16 %A = lshr i32 %Y, 16 %B = add i32 %X, %A ret i32 %B } define i32 @t2ADDrs_asr(i32 %X, i32 %Y) { -; CHECK: t2ADDrs_asr -; CHECK: add.w r0, r0, r1, asr #16 +; A8: t2ADDrs_asr +; A8: add.w r0, r0, r1, asr #16 %A = ashr i32 %Y, 16 %B = add i32 %X, %A ret i32 %B @@ -26,8 +29,8 @@ define i32 @t2ADDrs_asr(i32 %X, i32 %Y) { ; i32 ror(n) = (x >> n) | (x << (32 - n)) define i32 @t2ADDrs_ror(i32 %X, i32 %Y) { -; CHECK: t2ADDrs_ror -; CHECK: add.w r0, r0, r1, ror #16 +; A8: t2ADDrs_ror +; A8: add.w r0, r0, r1, ror #16 %A = lshr i32 %Y, 16 %B = shl i32 %Y, 16 %C = or i32 %B, %A @@ -36,13 +39,66 @@ define i32 @t2ADDrs_ror(i32 %X, i32 %Y) { } define i32 @t2ADDrs_noRegShift(i32 %X, i32 %Y, i8 %sh) { -; CHECK: t2ADDrs_noRegShift -; CHECK: uxtb r2, r2 -; CHECK: lsls r1, r2 -; CHECK: add r0, r1 +; A8: t2ADDrs_noRegShift +; A8: uxtb r2, r2 +; A8: lsls r1, r2 +; A8: add r0, r1 + +; SWIFT: t2ADDrs_noRegShift +; SWIFT-NOT: lsls +; SWIFT: lsl.w + %shift.upgrd.1 = zext i8 %sh to i32 + %A = shl i32 %Y, %shift.upgrd.1 + %B = add i32 %X, %A + ret i32 %B +} + +define i32 @t2ADDrs_noRegShift2(i32 %X, i32 %Y, i8 %sh) { +; A8: t2ADDrs_noRegShift2 +; A8: uxtb r2, r2 +; A8: lsrs r1, r2 +; A8: add r0, r1 + +; SWIFT: t2ADDrs_noRegShift2 +; SWIFT-NOT: lsrs +; SWIFT: lsr.w + %shift.upgrd.1 = zext i8 %sh to i32 + %A = lshr i32 %Y, %shift.upgrd.1 + %B = add i32 %X, %A + ret i32 %B +} + +define i32 @t2ADDrs_noRegShift3(i32 %X, i32 %Y, i8 %sh) { +; A8: t2ADDrs_noRegShift3 +; A8: uxtb r2, r2 +; A8: asrs r1, r2 +; A8: add r0, r1 + +; SWIFT: t2ADDrs_noRegShift3 +; SWIFT-NOT: asrs +; SWIFT: asr.w + %shift.upgrd.1 = zext i8 %sh to i32 + %A = ashr i32 %Y, %shift.upgrd.1 + %B = add i32 %X, %A + ret i32 %B +} + +define i32 @t2ADDrs_optsize(i32 %X, i32 %Y, i8 %sh) optsize { +; SWIFT: t2ADDrs_optsize +; SWIFT-NOT: lsl.w +; SWIFT: lsls %shift.upgrd.1 = zext i8 %sh to i32 %A = shl i32 %Y, %shift.upgrd.1 %B = add i32 %X, %A ret i32 %B } +define i32 @t2ADDrs_minsize(i32 %X, i32 %Y, i8 %sh) minsize { +; SWIFT: t2ADDrs_minsize +; SWIFT-NOT: lsr.w +; SWIFT: lsrs + %shift.upgrd.1 = zext i8 %sh to i32 + %A = lshr i32 %Y, %shift.upgrd.1 + %B = add i32 %X, %A + ret i32 %B +} diff --git a/test/CodeGen/Thumb2/thumb2-spill-q.ll b/test/CodeGen/Thumb2/thumb2-spill-q.ll index d9a0617f5a..5bff268e2c 100644 --- a/test/CodeGen/Thumb2/thumb2-spill-q.ll +++ b/test/CodeGen/Thumb2/thumb2-spill-q.ll @@ -12,8 +12,8 @@ declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly define void @aaa(%quuz* %this, i8* %block) { ; CHECK: aaa: ; CHECK: bic r4, r4, #15 -; CHECK: vst1.64 {{.*}}[{{.*}}, :128] -; CHECK: vld1.64 {{.*}}[{{.*}}, :128] +; CHECK: vst1.64 {{.*}}[{{.*}}:128] +; CHECK: vld1.64 {{.*}}[{{.*}}:128] entry: %aligned_vec = alloca <4 x float>, align 16 %"alloca point" = bitcast i32 0 to i32 diff --git a/test/CodeGen/X86/2008-05-22-FoldUnalignedLoad.ll b/test/CodeGen/X86/2008-05-22-FoldUnalignedLoad.ll index 19a73543c6..fc38135032 100644 --- a/test/CodeGen/X86/2008-05-22-FoldUnalignedLoad.ll +++ b/test/CodeGen/X86/2008-05-22-FoldUnalignedLoad.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 | grep movups | count 2 +; RUN: llc < %s -march=x86 -mcpu=penryn | FileCheck %s define void @a(<4 x float>* %x) nounwind { entry: @@ -8,4 +8,10 @@ entry: ret void } +; CHECK: a: +; CHECK: movups +; CHECK: movups +; CHECK-NOT: movups +; CHECK: ret + declare <4 x float> @llvm.x86.sse.rcp.ps(<4 x float>) diff --git a/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll b/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll index d423bfc389..496779c468 100644 --- a/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll +++ b/test/CodeGen/X86/2008-08-31-EH_RETURN64.ll @@ -1,10 +1,15 @@ ; Check that eh_return & unwind_init were properly lowered -; RUN: llc < %s | grep %rbp | count 7 -; RUN: llc < %s | grep %rcx | count 3 +; RUN: llc < %s -verify-machineinstrs | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" +; CHECK: test +; CHECK: pushq %rbp +; CHECK: movq %rsp, %rbp +; CHECK: popq %rbp +; CHECK: movq %rcx, %rsp +; CHECK: ret # eh_return, addr: %rcx define i8* @test(i64 %a, i8* %b) { entry: call void @llvm.eh.unwind.init() @@ -15,3 +20,36 @@ entry: declare void @llvm.eh.return.i64(i64, i8*) declare void @llvm.eh.unwind.init() + +@b = common global i32 0, align 4 +@a = common global i32 0, align 4 + +; PR14750 +; This function contains a normal return as well as eh_return. +; CHECK: _Unwind_Resume_or_Rethrow +define i32 @_Unwind_Resume_or_Rethrow() nounwind uwtable ssp { +entry: + %0 = load i32* @b, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + ret i32 0 + +if.end: ; preds = %entry + %call = tail call i32 (...)* @_Unwind_ForcedUnwind_Phase2() nounwind + store i32 %call, i32* @a, align 4 + %tobool1 = icmp eq i32 %call, 0 + br i1 %tobool1, label %cond.end, label %cond.true + +cond.true: ; preds = %if.end + tail call void @abort() noreturn nounwind + unreachable + +cond.end: ; preds = %if.end + tail call void @llvm.eh.return.i64(i64 0, i8* null) + unreachable +} + +declare i32 @_Unwind_ForcedUnwind_Phase2(...) +declare void @abort() noreturn diff --git a/test/CodeGen/X86/2010-01-18-DbgValue.ll b/test/CodeGen/X86/2010-01-18-DbgValue.ll index 85ee091c34..7f2b8206b1 100644 --- a/test/CodeGen/X86/2010-01-18-DbgValue.ll +++ b/test/CodeGen/X86/2010-01-18-DbgValue.ll @@ -28,21 +28,24 @@ return: ; preds = %entry declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone -!0 = metadata !{i32 524545, metadata !1, metadata !"my_r0", metadata !2, i32 11, metadata !7} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 11, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524329, metadata !"b2.c", metadata !"/tmp/", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"b2.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!llvm.dbg.cu = !{!3} +!18 = metadata !{metadata !1} + +!0 = metadata !{i32 786689, metadata !1, metadata !"my_r0", metadata !2, i32 11, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 11, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, double (%struct.Rect*)* @foo, null, null, null, i32 11} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"b2.c", metadata !"/tmp/", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 1, metadata !"b2.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !18, null} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] !5 = metadata !{metadata !6, metadata !7} -!6 = metadata !{i32 524324, metadata !2, metadata !"double", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 524307, metadata !2, metadata !"Rect", metadata !2, i32 6, i64 256, i64 64, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_structure_type ] +!6 = metadata !{i32 786468, metadata !2, metadata !"double", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786451, metadata !2, metadata !"Rect", metadata !2, i32 6, i64 256, i64 64, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_structure_type ] !8 = metadata !{metadata !9, metadata !14} -!9 = metadata !{i32 524301, metadata !7, metadata !"P1", metadata !2, i32 7, i64 128, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] -!10 = metadata !{i32 524307, metadata !2, metadata !"Pt", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_structure_type ] +!9 = metadata !{i32 786445, metadata !7, metadata !"P1", metadata !2, i32 7, i64 128, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] +!10 = metadata !{i32 786451, metadata !2, metadata !"Pt", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_structure_type ] !11 = metadata !{metadata !12, metadata !13} -!12 = metadata !{i32 524301, metadata !10, metadata !"x", metadata !2, i32 2, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!13 = metadata !{i32 524301, metadata !10, metadata !"y", metadata !2, i32 3, i64 64, i64 64, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] -!14 = metadata !{i32 524301, metadata !7, metadata !"P2", metadata !2, i32 8, i64 128, i64 64, i64 128, i32 0, metadata !10} ; [ DW_TAG_member ] +!12 = metadata !{i32 786445, metadata !10, metadata !"x", metadata !2, i32 2, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] +!13 = metadata !{i32 786445, metadata !10, metadata !"y", metadata !2, i32 3, i64 64, i64 64, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] +!14 = metadata !{i32 786445, metadata !7, metadata !"P2", metadata !2, i32 8, i64 128, i64 64, i64 128, i32 0, metadata !10} ; [ DW_TAG_member ] !15 = metadata !{i32 11, i32 0, metadata !1, null} !16 = metadata !{i32 12, i32 0, metadata !17, null} -!17 = metadata !{i32 524299, metadata !1, i32 11, i32 0} ; [ DW_TAG_lexical_block ] +!17 = metadata !{i32 786443, metadata !1, i32 11, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/X86/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 42f19b3ad8..0000000000 --- a/test/CodeGen/X86/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=x86 -asm-verbose < %s | FileCheck %s -; RUN: llc -O0 -march=x86-64 -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} diff --git a/test/CodeGen/X86/2010-05-25-DotDebugLoc.ll b/test/CodeGen/X86/2010-05-25-DotDebugLoc.ll index 2fceab6f09..5707befb9c 100644 --- a/test/CodeGen/X86/2010-05-25-DotDebugLoc.ll +++ b/test/CodeGen/X86/2010-05-25-DotDebugLoc.ll @@ -198,27 +198,29 @@ declare float @copysignf(float, float) nounwind readnone declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.lv = !{!0, !11, !12, !13, !14, !16, !17, !18} - -!0 = metadata !{i32 524545, metadata !1, metadata !"a", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"__divsc3", metadata !"__divsc3", metadata !"__divsc3", metadata !2, i32 1922, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524329, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!llvm.dbg.cu = !{!3} +!43 = metadata !{metadata !0, metadata !11, metadata !12, metadata !13, metadata !14, metadata !16, metadata !17, metadata !18} +!44 = metadata !{metadata !1} + +!0 = metadata !{i32 786689, metadata !1, metadata !"a", metadata !2, i32 1921, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"__divsc3", metadata !"__divsc3", metadata !"__divsc3", metadata !2, i32 1922, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, %0 (float, float, float, float)* @__divsc3, null, null, metadata !43, i32 1922} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 1, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !44, null} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] !5 = metadata !{metadata !6, metadata !9, metadata !9, metadata !9, metadata !9} -!6 = metadata !{i32 524310, metadata !7, metadata !"SCtype", metadata !7, i32 170, i64 0, i64 0, i64 0, i32 0, metadata !8} ; [ DW_TAG_typedef ] -!7 = metadata !{i32 524329, metadata !"libgcc2.h", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] -!8 = metadata !{i32 524324, metadata !2, metadata !"complex float", metadata !2, i32 0, i64 64, i64 32, i64 0, i32 0, i32 3} ; [ DW_TAG_base_type ] -!9 = metadata !{i32 524310, metadata !7, metadata !"SFtype", metadata !7, i32 167, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ] -!10 = metadata !{i32 524324, metadata !2, metadata !"float", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!11 = metadata !{i32 524545, metadata !1, metadata !"b", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] -!12 = metadata !{i32 524545, metadata !1, metadata !"c", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] -!13 = metadata !{i32 524545, metadata !1, metadata !"d", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] -!14 = metadata !{i32 524544, metadata !15, metadata !"denom", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] -!15 = metadata !{i32 524299, metadata !1, i32 1922, i32 0} ; [ DW_TAG_lexical_block ] -!16 = metadata !{i32 524544, metadata !15, metadata !"ratio", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] -!17 = metadata !{i32 524544, metadata !15, metadata !"x", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] -!18 = metadata !{i32 524544, metadata !15, metadata !"y", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] +!6 = metadata !{i32 786454, metadata !7, metadata !"SCtype", metadata !7, i32 170, i64 0, i64 0, i64 0, i32 0, metadata !8} ; [ DW_TAG_typedef ] +!7 = metadata !{i32 786473, metadata !"libgcc2.h", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] +!8 = metadata !{i32 786468, metadata !2, metadata !"complex float", metadata !2, i32 0, i64 64, i64 32, i64 0, i32 0, i32 3} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 786454, metadata !7, metadata !"SFtype", metadata !7, i32 167, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ] +!10 = metadata !{i32 786468, metadata !2, metadata !"float", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!11 = metadata !{i32 786689, metadata !1, metadata !"b", metadata !2, i32 1921, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 786689, metadata !1, metadata !"c", metadata !2, i32 1921, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!13 = metadata !{i32 786689, metadata !1, metadata !"d", metadata !2, i32 1921, metadata !9, i32 0, null} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 786688, metadata !15, metadata !"denom", metadata !2, i32 1923, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 786443, metadata !1, i32 1922, i32 0} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 786688, metadata !15, metadata !"ratio", metadata !2, i32 1923, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] +!17 = metadata !{i32 786688, metadata !15, metadata !"x", metadata !2, i32 1923, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] +!18 = metadata !{i32 786688, metadata !15, metadata !"y", metadata !2, i32 1923, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] !19 = metadata !{i32 1929, i32 0, metadata !15, null} !20 = metadata !{i32 1931, i32 0, metadata !15, null} !21 = metadata !{i32 1932, i32 0, metadata !15, null} diff --git a/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll b/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll index 7909d2736b..fa1e426a8f 100644 --- a/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll +++ b/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll @@ -21,39 +21,43 @@ declare void @foo(i32) nounwind optsize noinline ssp declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.gv = !{!0} -!llvm.dbg.lv = !{!4, !8, !18, !25, !26} +!llvm.dbg.cu = !{!2} +!31 = metadata !{metadata !0} +!32 = metadata !{metadata !5, metadata !9, metadata !19} +!33 = metadata !{metadata !4} +!34 = metadata !{metadata !8} +!35 = metadata !{metadata !18, metadata !25, metadata !26} -!0 = metadata !{i32 524340, i32 0, metadata !1, metadata !"ret", metadata !"ret", metadata !"", metadata !1, i32 7, metadata !3, i1 false, i1 true, null} ; [ DW_TAG_variable ] -!1 = metadata !{i32 524329, metadata !"foo.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 524305, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!4 = metadata !{i32 524545, metadata !5, metadata !"x", metadata !1, i32 12, metadata !3} ; [ DW_TAG_arg_variable ] -!5 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 13, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!6 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786484, i32 0, metadata !1, metadata !"ret", metadata !"ret", metadata !"", metadata !1, i32 7, metadata !3, i1 false, i1 true, null} ; [ DW_TAG_variable ] +!1 = metadata !{i32 786473, metadata !"foo.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !32, metadata !31} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786468, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!4 = metadata !{i32 786689, metadata !5, metadata !"x", metadata !1, i32 12, metadata !3, i32 0, null} ; [ DW_TAG_arg_variable ] +!5 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 13, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, void (i32)* @foo, null, null, metadata !33, i32 13} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] !7 = metadata !{null, metadata !3} -!8 = metadata !{i32 524545, metadata !9, metadata !"myvar", metadata !1, i32 17, metadata !13} ; [ DW_TAG_arg_variable ] -!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 17, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{i32 786689, metadata !9, metadata !"myvar", metadata !1, i32 17, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 17, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i8* (%struct.a*)* @bar, null, null, metadata !34, i32 17} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] !11 = metadata !{metadata !12, metadata !13} -!12 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!13 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] -!14 = metadata !{i32 524307, metadata !1, metadata !"a", metadata !1, i32 2, i64 128, i64 64, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_structure_type ] +!12 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!13 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] +!14 = metadata !{i32 786451, metadata !1, metadata !"a", metadata !1, i32 2, i64 128, i64 64, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_structure_type ] !15 = metadata !{metadata !16, metadata !17} -!16 = metadata !{i32 524301, metadata !14, metadata !"c", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !3} ; [ DW_TAG_member ] -!17 = metadata !{i32 524301, metadata !14, metadata !"d", metadata !1, i32 4, i64 64, i64 64, i64 64, i32 0, metadata !13} ; [ DW_TAG_member ] -!18 = metadata !{i32 524545, metadata !19, metadata !"argc", metadata !1, i32 22, metadata !3} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 22, metadata !20, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!20 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !21, i32 0, null} ; [ DW_TAG_subroutine_type ] +!16 = metadata !{i32 786445, metadata !14, metadata !"c", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !3} ; [ DW_TAG_member ] +!17 = metadata !{i32 786445, metadata !14, metadata !"d", metadata !1, i32 4, i64 64, i64 64, i64 64, i32 0, metadata !13} ; [ DW_TAG_member ] +!18 = metadata !{i32 786689, metadata !19, metadata !"argc", metadata !1, i32 22, metadata !3, i32 0, null} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 22, metadata !20, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, null, null, null, metadata !35, i32 22} ; [ DW_TAG_subprogram ] +!20 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !21, i32 0, null} ; [ DW_TAG_subroutine_type ] !21 = metadata !{metadata !3, metadata !3, metadata !22} -!22 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] -!23 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !24} ; [ DW_TAG_pointer_type ] -!24 = metadata !{i32 524324, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!25 = metadata !{i32 524545, metadata !19, metadata !"argv", metadata !1, i32 22, metadata !22} ; [ DW_TAG_arg_variable ] -!26 = metadata !{i32 524544, metadata !27, metadata !"e", metadata !1, i32 23, metadata !14} ; [ DW_TAG_auto_variable ] -!27 = metadata !{i32 524299, metadata !19, i32 22, i32 0} ; [ DW_TAG_lexical_block ] +!22 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] +!23 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !24} ; [ DW_TAG_pointer_type ] +!24 = metadata !{i32 786468, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!25 = metadata !{i32 786689, metadata !19, metadata !"argv", metadata !1, i32 22, metadata !22, i32 0, null} ; [ DW_TAG_arg_variable ] +!26 = metadata !{i32 786688, metadata !27, metadata !"e", metadata !1, i32 23, metadata !14, i32 0, null} ; [ DW_TAG_auto_variable ] +!27 = metadata !{i32 786443, metadata !19, i32 22, i32 0} ; [ DW_TAG_lexical_block ] !28 = metadata !{i32 18, i32 0, metadata !29, null} -!29 = metadata !{i32 524299, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ] +!29 = metadata !{i32 786443, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ] !30 = metadata !{i32 19, i32 0, metadata !29, null} ; The variable bar:myvar changes registers after the first movq. @@ -79,4 +83,4 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone ; CHECK-NEXT: .short Lset{{.*}} ; CHECK-NEXT: Ltmp{{.*}}: ; CHECK-NEXT: .byte 83 -; CHECK-NEXT: Ltmp{{.*}}:
\ No newline at end of file +; CHECK-NEXT: Ltmp{{.*}}: diff --git a/test/CodeGen/X86/2010-05-28-Crash.ll b/test/CodeGen/X86/2010-05-28-Crash.ll index 1a0da3177a..e1154e340d 100644 --- a/test/CodeGen/X86/2010-05-28-Crash.ll +++ b/test/CodeGen/X86/2010-05-28-Crash.ll @@ -22,23 +22,26 @@ entry: ret i32 %1, !dbg !13 } -!llvm.dbg.lv = !{!0, !7} +!llvm.dbg.cu = !{!3} +!15 = metadata !{metadata !0} +!16 = metadata !{metadata !7} +!17 = metadata !{metadata !1, metadata !8} -!0 = metadata !{i32 524545, metadata !1, metadata !"y", metadata !2, i32 2, metadata !6} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 2, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524329, metadata !"f.c", metadata !"/tmp", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"f.c", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786689, metadata !1, metadata !"y", metadata !2, i32 2, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 2, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (i32)* @foo, null, null, metadata !15, i32 2} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"f.c", metadata !"/tmp", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 1, metadata !"f.c", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !17, null} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] !5 = metadata !{metadata !6, metadata !6} -!6 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 524545, metadata !8, metadata !"x", metadata !2, i32 6, metadata !6} ; [ DW_TAG_arg_variable ] -!8 = metadata !{i32 524334, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"bar", metadata !2, i32 6, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786689, metadata !8, metadata !"x", metadata !2, i32 6, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] +!8 = metadata !{i32 786478, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"bar", metadata !2, i32 6, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (i32)* @bar, null, null, metadata !16, i32 6} ; [ DW_TAG_subprogram ] !9 = metadata !{i32 3, i32 0, metadata !10, null} -!10 = metadata !{i32 524299, metadata !1, i32 2, i32 0} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 786443, metadata !1, i32 2, i32 0} ; [ DW_TAG_lexical_block ] !11 = metadata !{i32 1} !12 = metadata !{i32 3, i32 0, metadata !10, metadata !13} !13 = metadata !{i32 7, i32 0, metadata !14, null} -!14 = metadata !{i32 524299, metadata !8, i32 6, i32 0} ; [ DW_TAG_lexical_block ] +!14 = metadata !{i32 786443, metadata !8, i32 6, i32 0} ; [ DW_TAG_lexical_block ] ;CHECK: DEBUG_VALUE: bar:x <- E ;CHECK: Ltmp diff --git a/test/CodeGen/X86/2010-06-01-DeadArg-DbgInfo.ll b/test/CodeGen/X86/2010-06-01-DeadArg-DbgInfo.ll index a9c03ee563..898f808128 100644 --- a/test/CodeGen/X86/2010-06-01-DeadArg-DbgInfo.ll +++ b/test/CodeGen/X86/2010-06-01-DeadArg-DbgInfo.ll @@ -21,34 +21,34 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.lv = !{!0, !14, !15, !16, !17, !24, !25, !28} -!0 = metadata !{i32 524545, metadata !1, metadata !"this", metadata !3, i32 11, metadata !12} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"_ZN3foo3barEi", metadata !3, i32 11, metadata !9, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524307, metadata !3, metadata !"foo", metadata !3, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_structure_type ] -!3 = metadata !{i32 524329, metadata !"foo.cp", metadata !"/tmp/", metadata !4} ; [ DW_TAG_file_type ] -!4 = metadata !{i32 524305, i32 0, i32 4, metadata !"foo.cp", metadata !"/tmp/", metadata !"4.2.1 LLVM build", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!0 = metadata !{i32 786689, metadata !1, metadata !"this", metadata !3, i32 11, metadata !12, i32 0, null} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"_ZN3foo3barEi", metadata !3, i32 11, metadata !9, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 true, i32 (%struct.foo*, i32)* @_ZN3foo3bazEi, null, null, null, i32 11} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786451, metadata !3, metadata !"foo", metadata !3, i32 3, i64 32, i64 32, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_structure_type ] +!3 = metadata !{i32 786473, metadata !"foo.cp", metadata !"/tmp/", metadata !4} ; [ DW_TAG_file_type ] +!4 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cp", metadata !"/tmp/", metadata !"4.2.1 LLVM build", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] !5 = metadata !{metadata !6, metadata !1, metadata !8} -!6 = metadata !{i32 524301, metadata !2, metadata !"y", metadata !3, i32 8, i64 32, i64 32, i64 0, i32 0, metadata !7} ; [ DW_TAG_member ] -!7 = metadata !{i32 524324, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 524334, i32 0, metadata !2, metadata !"baz", metadata !"baz", metadata !"_ZN3foo3bazEi", metadata !3, i32 15, metadata !9, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!9 = metadata !{i32 524309, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !10, i32 0, null} ; [ DW_TAG_subroutine_type ] +!6 = metadata !{i32 786445, metadata !2, metadata !"y", metadata !3, i32 8, i64 32, i64 32, i64 0, i32 0, metadata !7} ; [ DW_TAG_member ] +!7 = metadata !{i32 786468, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786478, i32 0, metadata !2, metadata !"baz", metadata !"baz", metadata !"_ZN3foo3bazEi", metadata !3, i32 15, metadata !9, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 true, i32 (%struct.foo*, i32)* @_ZN3foo3bazEi, null, null, null, i32 15} ; [ DW_TAG_subprogram ] +!9 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !10, i32 0, null} ; [ DW_TAG_subroutine_type ] !10 = metadata !{metadata !7, metadata !11, metadata !7} -!11 = metadata !{i32 524303, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !2} ; [ DW_TAG_pointer_type ] -!12 = metadata !{i32 524326, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !13} ; [ DW_TAG_const_type ] -!13 = metadata !{i32 524303, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !2} ; [ DW_TAG_pointer_type ] -!14 = metadata !{i32 524545, metadata !1, metadata !"x", metadata !3, i32 11, metadata !7} ; [ DW_TAG_arg_variable ] -!15 = metadata !{i32 524545, metadata !8, metadata !"this", metadata !3, i32 15, metadata !12} ; [ DW_TAG_arg_variable ] -!16 = metadata !{i32 524545, metadata !8, metadata !"x", metadata !3, i32 15, metadata !7} ; [ DW_TAG_arg_variable ] -!17 = metadata !{i32 524545, metadata !18, metadata !"argc", metadata !3, i32 19, metadata !7} ; [ DW_TAG_arg_variable ] -!18 = metadata !{i32 524334, i32 0, metadata !3, metadata !"main", metadata !"main", metadata !"main", metadata !3, i32 19, metadata !19, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] -!19 = metadata !{i32 524309, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !20, i32 0, null} ; [ DW_TAG_subroutine_type ] +!11 = metadata !{i32 786447, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !2} ; [ DW_TAG_pointer_type ] +!12 = metadata !{i32 786470, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !13} ; [ DW_TAG_const_type ] +!13 = metadata !{i32 786447, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !2} ; [ DW_TAG_pointer_type ] +!14 = metadata !{i32 786689, metadata !1, metadata !"x", metadata !3, i32 11, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!15 = metadata !{i32 786689, metadata !8, metadata !"this", metadata !3, i32 15, metadata !12, i32 0, null} ; [ DW_TAG_arg_variable ] +!16 = metadata !{i32 786689, metadata !8, metadata !"x", metadata !3, i32 15, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 786689, metadata !18, metadata !"argc", metadata !3, i32 19, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 786478, i32 0, metadata !3, metadata !"main", metadata !"main", metadata !"main", metadata !3, i32 19, metadata !19, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 true, null, null, null, null, i32 19} ; [ DW_TAG_subprogram ] +!19 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !20, i32 0, null} ; [ DW_TAG_subroutine_type ] !20 = metadata !{metadata !7, metadata !7, metadata !21} -!21 = metadata !{i32 524303, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] -!22 = metadata !{i32 524303, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] -!23 = metadata !{i32 524324, metadata !3, metadata !"char", metadata !3, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!24 = metadata !{i32 524545, metadata !18, metadata !"argv", metadata !3, i32 19, metadata !21} ; [ DW_TAG_arg_variable ] -!25 = metadata !{i32 524544, metadata !26, metadata !"a", metadata !3, i32 20, metadata !2} ; [ DW_TAG_auto_variable ] -!26 = metadata !{i32 524299, metadata !27, i32 19, i32 0} ; [ DW_TAG_lexical_block ] -!27 = metadata !{i32 524299, metadata !18, i32 19, i32 0} ; [ DW_TAG_lexical_block ] -!28 = metadata !{i32 524544, metadata !26, metadata !"b", metadata !3, i32 21, metadata !7} ; [ DW_TAG_auto_variable ] +!21 = metadata !{i32 786447, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !22} ; [ DW_TAG_pointer_type ] +!22 = metadata !{i32 786447, metadata !3, metadata !"", metadata !3, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] +!23 = metadata !{i32 786468, metadata !3, metadata !"char", metadata !3, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!24 = metadata !{i32 786689, metadata !18, metadata !"argv", metadata !3, i32 19, metadata !21, i32 0, null} ; [ DW_TAG_arg_variable ] +!25 = metadata !{i32 786688, metadata !26, metadata !"a", metadata !3, i32 20, metadata !2, i32 0, null} ; [ DW_TAG_auto_variable ] +!26 = metadata !{i32 786443, metadata !27, i32 19, i32 0} ; [ DW_TAG_lexical_block ] +!27 = metadata !{i32 786443, metadata !18, i32 19, i32 0} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786688, metadata !26, metadata !"b", metadata !3, i32 21, metadata !7, i32 0, null} ; [ DW_TAG_auto_variable ] !29 = metadata !{i32 16, i32 0, metadata !30, null} -!30 = metadata !{i32 524299, metadata !8, i32 15, i32 0} ; [ DW_TAG_lexical_block ] +!30 = metadata !{i32 786443, metadata !8, i32 15, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/2010-08-04-StackVariable.ll b/test/CodeGen/X86/2010-08-04-StackVariable.ll index ba36fe7c12..4ae6996c02 100644 --- a/test/CodeGen/X86/2010-08-04-StackVariable.ll +++ b/test/CodeGen/X86/2010-08-04-StackVariable.ll @@ -74,51 +74,52 @@ return: ; preds = %entry declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !9, !16, !17, !20} +!llvm.dbg.cu = !{!3} +!46 = metadata !{metadata !0, metadata !9, metadata !16, metadata !17, metadata !20} -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"", metadata !2, i32 11, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 524307, metadata !2, metadata !"SVal", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_structure_type ] -!2 = metadata !{i32 524329, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 4, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"", metadata !2, i32 11, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null, null, null, null, i32 11} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786451, metadata !2, metadata !"SVal", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_structure_type ] +!2 = metadata !{i32 786473, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 4, metadata !"small.cc", metadata !"/Users/manav/R8248330", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !46, null} ; [ DW_TAG_compile_unit ] !4 = metadata !{metadata !5, metadata !7, metadata !0, metadata !9} -!5 = metadata !{i32 524301, metadata !1, metadata !"Data", metadata !2, i32 7, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!6 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!7 = metadata !{i32 524301, metadata !1, metadata !"Kind", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !8} ; [ DW_TAG_member ] -!8 = metadata !{i32 524324, metadata !2, metadata !"unsigned int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"~SVal", metadata !"~SVal", metadata !"", metadata !2, i32 12, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786445, metadata !1, metadata !"Data", metadata !2, i32 7, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] +!6 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 786445, metadata !1, metadata !"Kind", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !8} ; [ DW_TAG_member ] +!8 = metadata !{i32 786468, metadata !2, metadata !"unsigned int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"~SVal", metadata !"~SVal", metadata !"", metadata !2, i32 12, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i1 false, i1 false, null, null, null, null, i32 12} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] !11 = metadata !{null, metadata !12, metadata !13} -!12 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] -!13 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_subroutine_type ] +!12 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] +!13 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_subroutine_type ] !15 = metadata !{null, metadata !12} -!16 = metadata !{i32 524334, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"_ZN4SValC1Ev", metadata !2, i32 11, metadata !14, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, void (%struct.SVal*)* @_ZN4SValC1Ev} ; [ DW_TAG_subprogram ] -!17 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3fooi4SVal", metadata !2, i32 16, metadata !18, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32, %struct.SVal*)* @_Z3fooi4SVal} ; [ DW_TAG_subprogram ] -!18 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !19, i32 0, null} ; [ DW_TAG_subroutine_type ] +!16 = metadata !{i32 786478, i32 0, metadata !1, metadata !"SVal", metadata !"SVal", metadata !"_ZN4SValC1Ev", metadata !2, i32 11, metadata !14, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, void (%struct.SVal*)* @_ZN4SValC1Ev, null, null, null, i32 11} ; [ DW_TAG_subprogram ] +!17 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"_Z3fooi4SVal", metadata !2, i32 16, metadata !18, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32, %struct.SVal*)* @_Z3fooi4SVal, null, null, null, i32 16} ; [ DW_TAG_subprogram ] +!18 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !19, i32 0, null} ; [ DW_TAG_subroutine_type ] !19 = metadata !{metadata !13, metadata !13, metadata !1} -!20 = metadata !{i32 524334, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"main", metadata !2, i32 23, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!21 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, null} ; [ DW_TAG_subroutine_type ] +!20 = metadata !{i32 786478, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"main", metadata !2, i32 23, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @main, null, null, null, i32 23} ; [ DW_TAG_subprogram ] +!21 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, null} ; [ DW_TAG_subroutine_type ] !22 = metadata !{metadata !13} -!23 = metadata !{i32 524545, metadata !17, metadata !"i", metadata !2, i32 16, metadata !13} ; [ DW_TAG_arg_variable ] +!23 = metadata !{i32 786689, metadata !17, metadata !"i", metadata !2, i32 16, metadata !13, i32 0, null} ; [ DW_TAG_arg_variable ] !24 = metadata !{i32 16, i32 0, metadata !17, null} -!25 = metadata !{i32 524545, metadata !17, metadata !"location", metadata !2, i32 16, metadata !26} ; [ DW_TAG_arg_variable ] -!26 = metadata !{i32 524304, metadata !2, metadata !"SVal", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_reference_type ] +!25 = metadata !{i32 786689, metadata !17, metadata !"location", metadata !2, i32 16, metadata !26, i32 0, null} ; [ DW_TAG_arg_variable ] +!26 = metadata !{i32 786448, metadata !2, metadata !"SVal", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_reference_type ] !27 = metadata !{i32 17, i32 0, metadata !28, null} -!28 = metadata !{i32 524299, metadata !17, i32 16, i32 0, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786443, metadata !17, i32 16, i32 0, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] !29 = metadata !{i32 18, i32 0, metadata !28, null} !30 = metadata !{i32 20, i32 0, metadata !28, null} -!31 = metadata !{i32 524545, metadata !16, metadata !"this", metadata !2, i32 11, metadata !32} ; [ DW_TAG_arg_variable ] -!32 = metadata !{i32 524326, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !33} ; [ DW_TAG_const_type ] -!33 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_pointer_type ] +!31 = metadata !{i32 786689, metadata !16, metadata !"this", metadata !2, i32 11, metadata !32, i32 0, null} ; [ DW_TAG_arg_variable ] +!32 = metadata !{i32 786470, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !33} ; [ DW_TAG_const_type ] +!33 = metadata !{i32 786447, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !1} ; [ DW_TAG_pointer_type ] !34 = metadata !{i32 11, i32 0, metadata !16, null} !35 = metadata !{i32 11, i32 0, metadata !36, null} -!36 = metadata !{i32 524299, metadata !37, i32 11, i32 0, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] -!37 = metadata !{i32 524299, metadata !16, i32 11, i32 0, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] -!38 = metadata !{i32 524544, metadata !39, metadata !"v", metadata !2, i32 24, metadata !1} ; [ DW_TAG_auto_variable ] -!39 = metadata !{i32 524299, metadata !40, i32 23, i32 0, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] -!40 = metadata !{i32 524299, metadata !20, i32 23, i32 0, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] +!36 = metadata !{i32 786443, metadata !37, i32 11, i32 0, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!37 = metadata !{i32 786443, metadata !16, i32 11, i32 0, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!38 = metadata !{i32 786688, metadata !39, metadata !"v", metadata !2, i32 24, metadata !1, i32 0, null} ; [ DW_TAG_auto_variable ] +!39 = metadata !{i32 786443, metadata !40, i32 23, i32 0, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] +!40 = metadata !{i32 786443, metadata !20, i32 23, i32 0, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] !41 = metadata !{i32 24, i32 0, metadata !39, null} !42 = metadata !{i32 25, i32 0, metadata !39, null} !43 = metadata !{i32 26, i32 0, metadata !39, null} -!44 = metadata !{i32 524544, metadata !39, metadata !"k", metadata !2, i32 26, metadata !13} ; [ DW_TAG_auto_variable ] +!44 = metadata !{i32 786688, metadata !39, metadata !"k", metadata !2, i32 26, metadata !13, i32 0, null} ; [ DW_TAG_auto_variable ] !45 = metadata !{i32 27, i32 0, metadata !39, null} diff --git a/test/CodeGen/X86/2010-08-10-DbgConstant.ll b/test/CodeGen/X86/2010-08-10-DbgConstant.ll deleted file mode 100644 index b3cc35d723..0000000000 --- a/test/CodeGen/X86/2010-08-10-DbgConstant.ll +++ /dev/null @@ -1,25 +0,0 @@ -; RUN: llc -mtriple=i686-linux -O0 < %s | FileCheck %s -; CHECK: DW_TAG_constant -; CHECK-NEXT: .long .Lstring3 #{{#?}} DW_AT_name - -define void @foo() nounwind ssp { -entry: - call void @bar(i32 201), !dbg !8 - ret void, !dbg !8 -} - -declare void @bar(i32) - -!llvm.dbg.sp = !{!0} -!llvm.dbg.gv = !{!5} - -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, void ()* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 524329, metadata !"/tmp/l.c", metadata !"/Volumes/Lalgate/clean/D", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"/tmp/l.c", metadata !"/Volumes/Lalgate/clean/D", metadata !"clang 2.8", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{null} -!5 = metadata !{i32 524327, i32 0, metadata !1, metadata !"ro", metadata !"ro", metadata !"ro", metadata !1, i32 1, metadata !6, i1 true, i1 true, i32 201} ; [ DW_TAG_constant ] -!6 = metadata !{i32 524326, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_const_type ] -!7 = metadata !{i32 524324, metadata !1, metadata !"unsigned int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 3, i32 14, metadata !9, null} -!9 = metadata !{i32 524299, metadata !0, i32 3, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/2010-09-16-EmptyFilename.ll b/test/CodeGen/X86/2010-09-16-EmptyFilename.ll index bed8c8a77b..60fb68b791 100644 --- a/test/CodeGen/X86/2010-09-16-EmptyFilename.ll +++ b/test/CodeGen/X86/2010-09-16-EmptyFilename.ll @@ -12,18 +12,19 @@ entry: ret i32 21, !dbg !10 } -!llvm.dbg.sp = !{!0, !6} +!llvm.dbg.cu = !{!2} +!13 = metadata !{metadata !0, metadata !6} -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 53, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 524329, metadata !"", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"bug.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 114084)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 53, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"bug.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 114084)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !13, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null, null, metadata !13, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 524334, i32 0, metadata !7, metadata !"bar", metadata !"bar", metadata !"bar", metadata !7, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @bar} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 524329, metadata !"bug.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!5 = metadata !{i32 786468, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !7, metadata !"bar", metadata !"bar", metadata !"bar", metadata !7, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 ()* @bar} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786473, metadata !"bug.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] !8 = metadata !{i32 53, i32 13, metadata !9, null} -!9 = metadata !{i32 524299, metadata !0, i32 53, i32 11, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!9 = metadata !{i32 786443, metadata !0, i32 53, i32 11, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !10 = metadata !{i32 4, i32 13, metadata !11, null} -!11 = metadata !{i32 524299, metadata !12, i32 4, i32 13, metadata !7, i32 2} ; [ DW_TAG_lexical_block ] -!12 = metadata !{i32 524299, metadata !6, i32 4, i32 11, metadata !7, i32 1} ; [ DW_TAG_lexical_block ] +!11 = metadata !{i32 786443, metadata !12, i32 4, i32 13, metadata !7, i32 2} ; [ DW_TAG_lexical_block ] +!12 = metadata !{i32 786443, metadata !6, i32 4, i32 11, metadata !7, i32 1} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/2010-11-02-DbgParameter.ll b/test/CodeGen/X86/2010-11-02-DbgParameter.ll index 79c0cf35c6..9cf2747b77 100644 --- a/test/CodeGen/X86/2010-11-02-DbgParameter.ll +++ b/test/CodeGen/X86/2010-11-02-DbgParameter.ll @@ -15,21 +15,22 @@ entry: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0} -!llvm.dbg.lv.foo = !{!6} +!llvm.dbg.cu = !{!2} +!15 = metadata !{metadata !0} +!16 = metadata !{metadata !6} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (%struct.bar*)* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"one.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"one.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 117922)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i32 (%struct.bar*)* @foo, null, null, metadata !16, i32 3} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"one.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"one.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 117922)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !15, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 3, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!7 = metadata !{i32 589839, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] -!8 = metadata !{i32 589843, metadata !1, metadata !"bar", metadata !1, i32 2, i64 64, i64 32, i64 0, i32 0, null, metadata !9, i32 0, null} ; [ DW_TAG_structure_type ] +!5 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786689, metadata !0, metadata !"i", metadata !1, i32 3, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] +!8 = metadata !{i32 786451, metadata !1, metadata !"bar", metadata !1, i32 2, i64 64, i64 32, i64 0, i32 0, null, metadata !9, i32 0, null} ; [ DW_TAG_structure_type ] !9 = metadata !{metadata !10, metadata !11} -!10 = metadata !{i32 589837, metadata !1, metadata !"x", metadata !1, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] -!11 = metadata !{i32 589837, metadata !1, metadata !"y", metadata !1, i32 2, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ] +!10 = metadata !{i32 786445, metadata !1, metadata !"x", metadata !1, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] +!11 = metadata !{i32 786445, metadata !1, metadata !"y", metadata !1, i32 2, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ] !12 = metadata !{i32 3, i32 47, metadata !0, null} !13 = metadata !{i32 4, i32 2, metadata !14, null} -!14 = metadata !{i32 589835, metadata !0, i32 3, i32 50, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!14 = metadata !{i32 786443, metadata !0, i32 3, i32 50, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/2010-12-02-MC-Set.ll b/test/CodeGen/X86/2010-12-02-MC-Set.ll index 31446786ec..628e5ba606 100644 --- a/test/CodeGen/X86/2010-12-02-MC-Set.ll +++ b/test/CodeGen/X86/2010-12-02-MC-Set.ll @@ -6,17 +6,18 @@ entry: ret void, !dbg !5 } -!llvm.dbg.sp = !{!0} +!llvm.dbg.cu = !{!2} +!7 = metadata !{metadata !0} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void ()* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"e.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"e.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 120563)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void ()* @foo, null, null, null, i32 0} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"e.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"e.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 120563)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !7, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{null} !5 = metadata !{i32 5, i32 1, metadata !6, null} -!6 = metadata !{i32 589835, metadata !0, i32 3, i32 16, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!6 = metadata !{i32 786443, metadata !0, i32 3, i32 16, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] ; CHECK: .subsections_via_symbols ; CHECK-NEXT: __debug_line -; CHECK-NEXT: Ltmp +; CHECK-NEXT: Lline_table_start0 ; CHECK-NEXT: Ltmp{{[0-9]}} = (Ltmp diff --git a/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll b/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll index 166dcf2599..3d3fff9604 100644 --- a/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll +++ b/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll @@ -4,7 +4,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 target triple = "x86_64-apple-darwin10.0.0" ; Check debug info for variable z_s -;CHECK: .long Lset13 +;CHECK: .long Lset14 ;CHECK-NEXT: ## DW_AT_decl_file ;CHECK-NEXT: ## DW_AT_decl_line ;CHECK-NEXT: ## DW_AT_type @@ -69,33 +69,34 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone declare i32 @puts(i8* nocapture) nounwind -!llvm.dbg.sp = !{!0, !6} -!llvm.dbg.lv.gcd = !{!10, !11, !12} -!llvm.dbg.lv.main = !{!14, !17} +!llvm.dbg.cu = !{!2} +!28 = metadata !{metadata !0, metadata !6} +!29 = metadata !{metadata !10, metadata !11, metadata !12} +!30 = metadata !{metadata !14, metadata !17} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"gcd", metadata !"gcd", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i64 (i64, i64)* @gcd} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"rem_small.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"rem_small.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 124117)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"gcd", metadata !"gcd", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i64 (i64, i64)* @gcd, null, null, metadata !29, i32 0} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"rem_small.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"rem_small.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 124117)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !28, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"long int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 25, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 true, i32 ()* @main} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786468, metadata !2, metadata !"long int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 25, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 true, i32 ()* @main, null, null, metadata !30, i32 0} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !8 = metadata !{metadata !9} -!9 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!10 = metadata !{i32 590081, metadata !0, metadata !"a", metadata !1, i32 5, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!11 = metadata !{i32 590081, metadata !0, metadata !"b", metadata !1, i32 5, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!12 = metadata !{i32 590080, metadata !13, metadata !"c", metadata !1, i32 6, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!13 = metadata !{i32 589835, metadata !0, i32 5, i32 52, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!14 = metadata !{i32 590080, metadata !15, metadata !"m", metadata !1, i32 26, metadata !16, i32 0} ; [ DW_TAG_auto_variable ] -!15 = metadata !{i32 589835, metadata !6, i32 25, i32 12, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] -!16 = metadata !{i32 589860, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!17 = metadata !{i32 590080, metadata !15, metadata !"z_s", metadata !1, i32 27, metadata !9, i32 0} ; [ DW_TAG_auto_variable ] +!9 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!10 = metadata !{i32 786689, metadata !0, metadata !"a", metadata !1, i32 5, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 786689, metadata !0, metadata !"b", metadata !1, i32 5, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 786688, metadata !13, metadata !"c", metadata !1, i32 6, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!13 = metadata !{i32 786443, metadata !0, i32 5, i32 52, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!14 = metadata !{i32 786688, metadata !15, metadata !"m", metadata !1, i32 26, metadata !16, i32 0, null} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 786443, metadata !6, i32 25, i32 12, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 786468, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!17 = metadata !{i32 786688, metadata !15, metadata !"z_s", metadata !1, i32 27, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] !18 = metadata !{i32 5, i32 41, metadata !0, null} !19 = metadata !{i32 5, i32 49, metadata !0, null} !20 = metadata !{i32 7, i32 5, metadata !13, null} !21 = metadata !{i32 8, i32 9, metadata !22, null} -!22 = metadata !{i32 589835, metadata !13, i32 7, i32 14, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!22 = metadata !{i32 786443, metadata !13, i32 7, i32 14, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] !23 = metadata !{i32 9, i32 9, metadata !22, null} !24 = metadata !{i32 26, i32 38, metadata !15, null} !25 = metadata !{i32 27, i32 38, metadata !15, null} diff --git a/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll b/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll index a7207537de..da734d4b64 100644 --- a/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll +++ b/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll @@ -16,8 +16,8 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK: main define i32 @main() nounwind uwtable { entry: -; CHECK: movsbq j(%rip), % -; CHECK: movsbq i(%rip), % +; CHECK: pmovsxbq j(%rip), % +; CHECK: pmovsxbq i(%rip), % %0 = load <2 x i8>* @i, align 8 %1 = load <2 x i8>* @j, align 8 %div = sdiv <2 x i8> %1, %0 diff --git a/test/CodeGen/X86/2011-11-30-or.ll b/test/CodeGen/X86/2011-11-30-or.ll index f66248bc5a..8ac4632329 100644 --- a/test/CodeGen/X86/2011-11-30-or.ll +++ b/test/CodeGen/X86/2011-11-30-or.ll @@ -8,9 +8,9 @@ target triple = "x86_64-apple-macosx10.6.6" ; CHECK: pblendvb %xmm1, %xmm2 ; CHECK: ret -define void @select_func() { +define void @select_func(<8 x i16> %in) { entry: - %c.lobit.i.i.i = ashr <8 x i16> <i16 17, i16 5, i16 1, i16 15, i16 19, i16 15, i16 4, i16 1> , <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> + %c.lobit.i.i.i = ashr <8 x i16> %in, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> %and.i56.i.i.i = and <8 x i16> %c.lobit.i.i.i, <i16 25, i16 8, i16 65, i16 25, i16 8, i16 95, i16 15, i16 45> %and.i5.i.i.i = bitcast <8 x i16> %and.i56.i.i.i to <2 x i64> %neg.i.i.i.i = xor <8 x i16> %c.lobit.i.i.i, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> diff --git a/test/CodeGen/X86/2011-12-28-vselecti8.ll b/test/CodeGen/X86/2011-12-28-vselecti8.ll index 1a9d46d1e2..dbc122ac6e 100644 --- a/test/CodeGen/X86/2011-12-28-vselecti8.ll +++ b/test/CodeGen/X86/2011-12-28-vselecti8.ll @@ -5,7 +5,7 @@ target triple = "x86_64-apple-darwin11.2.0" ; CHECK: @foo8 ; CHECK: psll -; CHECK-NOT: psraw +; CHECK: psraw ; CHECK: pblendvb ; CHECK: ret define void @foo8(float* nocapture %RET) nounwind { diff --git a/test/CodeGen/X86/2012-01-11-split-cv.ll b/test/CodeGen/X86/2012-01-11-split-cv.ll index 6b90072919..7e914984fe 100644 --- a/test/CodeGen/X86/2012-01-11-split-cv.ll +++ b/test/CodeGen/X86/2012-01-11-split-cv.ll @@ -2,7 +2,7 @@ ;CHECK: add18i16 define void @add18i16(<18 x i16>* nocapture sret %ret, <18 x i16>* %bp) nounwind { -;CHECK: vmovups +;CHECK: vmovaps %b = load <18 x i16>* %bp, align 16 %x = add <18 x i16> zeroinitializer, %b store <18 x i16> %x, <18 x i16>* %ret, align 16 diff --git a/test/CodeGen/X86/2012-12-12-DAGCombineCrash.ll b/test/CodeGen/X86/2012-12-12-DAGCombineCrash.ll new file mode 100644 index 0000000000..8cef2c8201 --- /dev/null +++ b/test/CodeGen/X86/2012-12-12-DAGCombineCrash.ll @@ -0,0 +1,46 @@ +; RUN: llc -march=x86 -mtriple=i686-apple-ios -mcpu=yonah < %s +; rdar://12868039 + +define void @t() nounwind ssp { + %1 = alloca i32 + %2 = ptrtoint i32* %1 to i32 + br label %3 + +; <label>:3 ; preds = %5, %3, %0 + switch i32 undef, label %3 [ + i32 611946160, label %5 + i32 954117870, label %4 + ] + +; <label>:4 ; preds = %3 + ret void + +; <label>:5 ; preds = %5, %3 + %6 = add i32 0, 148 + %7 = and i32 %6, 48 + %8 = add i32 %7, 0 + %9 = or i32 %2, %8 + %10 = xor i32 -1, %2 + %11 = or i32 %8, %10 + %12 = or i32 %9, %11 + %13 = xor i32 %9, %11 + %14 = sub i32 %12, %13 + %15 = xor i32 2044674005, %14 + %16 = xor i32 %15, 0 + %17 = shl nuw nsw i32 %16, 1 + %18 = sub i32 0, %17 + %19 = and i32 %18, 2051242402 + %20 = sub i32 0, %19 + %21 = xor i32 %20, 0 + %22 = xor i32 %21, 0 + %23 = add i32 0, %22 + %24 = shl i32 %23, 1 + %25 = or i32 1, %24 + %26 = add i32 0, %25 + %27 = trunc i32 %26 to i8 + %28 = xor i8 %27, 125 + %29 = add i8 %28, -16 + %30 = add i8 0, %29 + store i8 %30, i8* null + br i1 undef, label %5, label %3 +} diff --git a/test/CodeGen/X86/2012-12-14-v8fp80-crash.ll b/test/CodeGen/X86/2012-12-14-v8fp80-crash.ll new file mode 100644 index 0000000000..c465527bd8 --- /dev/null +++ b/test/CodeGen/X86/2012-12-14-v8fp80-crash.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7 -mtriple=i686-pc-win32 + +; Make sure we don't crash on this testcase. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +define void @_ZN6VectorIfE3equIeEEvfRKS_IT_E() nounwind uwtable ssp align 2 { +entry: + br i1 undef, label %while.end, label %while.body.lr.ph + +while.body.lr.ph: ; preds = %entry + br label %vector.body + +vector.body: ; preds = %vector.body, %while.body.lr.ph + %0 = fptrunc <8 x x86_fp80> undef to <8 x float> + store <8 x float> %0, <8 x float>* undef, align 4 + br label %vector.body + +while.end: ; preds = %entry + ret void +} diff --git a/test/CodeGen/X86/2012-12-19-NoImplicitFloat.ll b/test/CodeGen/X86/2012-12-19-NoImplicitFloat.ll new file mode 100644 index 0000000000..3025665206 --- /dev/null +++ b/test/CodeGen/X86/2012-12-19-NoImplicitFloat.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 < %s | FileCheck %s +; Test that we do not introduce vector operations with noimplicitfloat. +; rdar://12879313 + +%struct1 = type { i32*, i32* } + +define void @test() nounwind noimplicitfloat { +entry: +; CHECK-NOT: xmm +; CHECK: ret + %0 = load %struct1** undef, align 8 + %1 = getelementptr inbounds %struct1* %0, i64 0, i32 0 + store i32* null, i32** %1, align 8 + %2 = getelementptr inbounds %struct1* %0, i64 0, i32 1 + store i32* null, i32** %2, align 8 + ret void +} diff --git a/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll b/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll new file mode 100644 index 0000000000..db7ec8ae26 --- /dev/null +++ b/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll @@ -0,0 +1,41 @@ +; RUN: llc -mtriple=x86_64-apple-macosx10.5.0 < %s + +; rdar://12968664 + +define void @t() nounwind uwtable ssp { + br label %4 + +; <label>:1 ; preds = %4, %2 + ret void + +; <label>:2 ; preds = %6, %5, %3, %2 + switch i32 undef, label %2 [ + i32 1090573978, label %1 + i32 1090573938, label %3 + i32 1090573957, label %5 + ] + +; <label>:3 ; preds = %4, %2 + br i1 undef, label %2, label %4 + +; <label>:4 ; preds = %6, %5, %3, %0 + switch i32 undef, label %11 [ + i32 1090573938, label %3 + i32 1090573957, label %5 + i32 1090573978, label %1 + i32 165205179, label %6 + ] + +; <label>:5 ; preds = %4, %2 + br i1 undef, label %2, label %4 + +; <label>:6 ; preds = %4 + %7 = icmp eq i32 undef, 590901838 + %8 = or i1 false, %7 + %9 = or i1 true, %8 + %10 = xor i1 %8, %9 + br i1 %10, label %4, label %2 + +; <label>:11 ; preds = %11, %4 + br label %11 +} diff --git a/test/CodeGen/X86/2013-02-12-ShuffleToZext.ll b/test/CodeGen/X86/2013-02-12-ShuffleToZext.ll new file mode 100644 index 0000000000..614ccda5e2 --- /dev/null +++ b/test/CodeGen/X86/2013-02-12-ShuffleToZext.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7-avx -mtriple=x86_64-pc-win32 | FileCheck %s + +; CHECK: test +; CHECK: vpmovzxwd +; CHECK: vpmovzxwd +define void @test(<4 x i64> %a, <4 x i16>* %buf) { + %ex1 = extractelement <4 x i64> %a, i32 0 + %ex2 = extractelement <4 x i64> %a, i32 1 + %x1 = bitcast i64 %ex1 to <4 x i16> + %x2 = bitcast i64 %ex2 to <4 x i16> + %Sh = shufflevector <4 x i16> %x1, <4 x i16> %x2, <4 x i32> <i32 0, i32 1, i32 4, i32 5> + store <4 x i16> %Sh, <4 x i16>* %buf, align 1 + ret void +} diff --git a/test/CodeGen/X86/Atomics-64.ll b/test/CodeGen/X86/Atomics-64.ll index 8e93762cec..8b0a349a8b 100644 --- a/test/CodeGen/X86/Atomics-64.ll +++ b/test/CodeGen/X86/Atomics-64.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86-64 > %t -; RUN: llc < %s -march=x86 > %t +; RUN: llc < %s -march=x86-64 > %t.x86-64 +; RUN: llc < %s -march=x86 > %t.x86 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-apple-darwin8" diff --git a/test/CodeGen/X86/DbgValueOtherTargets.test b/test/CodeGen/X86/DbgValueOtherTargets.test new file mode 100644 index 0000000000..c95e8c6abd --- /dev/null +++ b/test/CodeGen/X86/DbgValueOtherTargets.test @@ -0,0 +1,2 @@ +; RUN: llc -O0 -march=x86 -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll +; RUN: llc -O0 -march=x86-64 -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll diff --git a/test/CodeGen/X86/GC/ocaml-gc.ll b/test/CodeGen/X86/GC/ocaml-gc.ll new file mode 100644 index 0000000000..44241a90d0 --- /dev/null +++ b/test/CodeGen/X86/GC/ocaml-gc.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s + +define i32 @main(i32 %x) nounwind gc "ocaml" { +; CHECK: .text +; CHECK-NEXT: .globl caml_3C_stdin_3E___code_begin +; CHECK-NEXT: caml_3C_stdin_3E___code_begin: +; CHECK-NEXT: .data +; CHECK-NEXT: .globl caml_3C_stdin_3E___data_begin +; CHECK-NEXT: caml_3C_stdin_3E___data_begin: + + %puts = tail call i32 @foo(i32 %x) + ret i32 0 + +; CHECK: .globl caml_3C_stdin_3E___code_end +; CHECK-NEXT: caml_3C_stdin_3E___code_end: +; CHECK-NEXT: .data +; CHECK-NEXT: .globl caml_3C_stdin_3E___data_end +; CHECK-NEXT: caml_3C_stdin_3E___data_end: +; CHECK-NEXT: .quad 0 +; CHECK-NEXT: .globl caml_3C_stdin_3E___frametable +; CHECK-NEXT: caml_3C_stdin_3E___frametable: +; CHECK-NEXT: .short 1 +; CHECK-NEXT: .align 8 +; CHECK-NEXT: # live roots for main +; CHECK-NEXT: .quad .Ltmp0 +; CHECK-NEXT: .short 8 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .align 8 +} + +declare i32 @foo(i32) diff --git a/test/CodeGen/X86/MachineSink-DbgValue.ll b/test/CodeGen/X86/MachineSink-DbgValue.ll index ea791a3c08..cf5d520073 100644 --- a/test/CodeGen/X86/MachineSink-DbgValue.ll +++ b/test/CodeGen/X86/MachineSink-DbgValue.ll @@ -26,21 +26,21 @@ bb2: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1} -!llvm.dbg.lv.foo = !{!6, !7, !10} +!18 = metadata !{metadata !1} +!19 = metadata !{metadata !6, metadata !7, metadata !10} -!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i32*)* @foo, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !18, null, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i32*)* @foo, null, null, metadata !19, i32 0} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 590081, metadata !1, metadata !"i", metadata !2, i32 16777218, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!7 = metadata !{i32 590081, metadata !1, metadata !"c", metadata !2, i32 33554434, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] -!8 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] -!9 = metadata !{i32 589860, metadata !0, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!10 = metadata !{i32 590080, metadata !11, metadata !"a", metadata !2, i32 3, metadata !9, i32 0} ; [ DW_TAG_auto_variable ] -!11 = metadata !{i32 589835, metadata !1, i32 2, i32 25, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786689, metadata !1, metadata !"i", metadata !2, i32 16777218, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 786689, metadata !1, metadata !"c", metadata !2, i32 33554434, metadata !8, i32 0, null} ; [ DW_TAG_arg_variable ] +!8 = metadata !{i32 786447, metadata !0, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] +!9 = metadata !{i32 786468, metadata !0, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!10 = metadata !{i32 786688, metadata !11, metadata !"a", metadata !2, i32 3, metadata !9, i32 0, null} ; [ DW_TAG_auto_variable ] +!11 = metadata !{i32 786443, metadata !1, i32 2, i32 25, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] !12 = metadata !{i32 2, i32 13, metadata !1, null} !13 = metadata !{i32 2, i32 22, metadata !1, null} !14 = metadata !{i32 3, i32 14, metadata !11, null} diff --git a/test/CodeGen/X86/MergeConsecutiveStores.ll b/test/CodeGen/X86/MergeConsecutiveStores.ll index 64825bac97..fbe8879ad6 100644 --- a/test/CodeGen/X86/MergeConsecutiveStores.ll +++ b/test/CodeGen/X86/MergeConsecutiveStores.ll @@ -40,9 +40,43 @@ define void @merge_const_store(i32 %count, %struct.A* nocapture %p) nounwind uwt ret void } +; No vectors because we use noimplicitfloat +; CHECK: merge_const_store_no_vec +; CHECK-NOT: vmovups +; CHECK: ret +define void @merge_const_store_no_vec(i32 %count, %struct.B* nocapture %p) noimplicitfloat{ + %1 = icmp sgt i32 %count, 0 + br i1 %1, label %.lr.ph, label %._crit_edge +.lr.ph: + %i.02 = phi i32 [ %10, %.lr.ph ], [ 0, %0 ] + %.01 = phi %struct.B* [ %11, %.lr.ph ], [ %p, %0 ] + %2 = getelementptr inbounds %struct.B* %.01, i64 0, i32 0 + store i32 0, i32* %2, align 4 + %3 = getelementptr inbounds %struct.B* %.01, i64 0, i32 1 + store i32 0, i32* %3, align 4 + %4 = getelementptr inbounds %struct.B* %.01, i64 0, i32 2 + store i32 0, i32* %4, align 4 + %5 = getelementptr inbounds %struct.B* %.01, i64 0, i32 3 + store i32 0, i32* %5, align 4 + %6 = getelementptr inbounds %struct.B* %.01, i64 0, i32 4 + store i32 0, i32* %6, align 4 + %7 = getelementptr inbounds %struct.B* %.01, i64 0, i32 5 + store i32 0, i32* %7, align 4 + %8 = getelementptr inbounds %struct.B* %.01, i64 0, i32 6 + store i32 0, i32* %8, align 4 + %9 = getelementptr inbounds %struct.B* %.01, i64 0, i32 7 + store i32 0, i32* %9, align 4 + %10 = add nsw i32 %i.02, 1 + %11 = getelementptr inbounds %struct.B* %.01, i64 1 + %exitcond = icmp eq i32 %10, %count + br i1 %exitcond, label %._crit_edge, label %.lr.ph +._crit_edge: + ret void +} + ; Move the constants using a single vector store. ; CHECK: merge_const_store_vec -; CHECK: vmovups %ymm0, (%rsi) +; CHECK: vmovups ; CHECK: ret define void @merge_const_store_vec(i32 %count, %struct.B* nocapture %p) nounwind uwtable noinline ssp { %1 = icmp sgt i32 %count, 0 diff --git a/test/CodeGen/X86/2003-08-03-CallArgLiveRanges.ll b/test/CodeGen/X86/Stats/2003-08-03-CallArgLiveRanges.ll index 0af2445d7f..0af2445d7f 100644 --- a/test/CodeGen/X86/2003-08-03-CallArgLiveRanges.ll +++ b/test/CodeGen/X86/Stats/2003-08-03-CallArgLiveRanges.ll diff --git a/test/CodeGen/X86/2006-03-02-InstrSchedBug.ll b/test/CodeGen/X86/Stats/2006-03-02-InstrSchedBug.ll index 1a3d74918d..1a3d74918d 100644 --- a/test/CodeGen/X86/2006-03-02-InstrSchedBug.ll +++ b/test/CodeGen/X86/Stats/2006-03-02-InstrSchedBug.ll diff --git a/test/CodeGen/X86/2006-05-01-SchedCausingSpills.ll b/test/CodeGen/X86/Stats/2006-05-01-SchedCausingSpills.ll index 5cba3efeef..5cba3efeef 100644 --- a/test/CodeGen/X86/2006-05-01-SchedCausingSpills.ll +++ b/test/CodeGen/X86/Stats/2006-05-01-SchedCausingSpills.ll diff --git a/test/CodeGen/X86/2006-05-02-InstrSched1.ll b/test/CodeGen/X86/Stats/2006-05-02-InstrSched1.ll index 1c75f93915..1c75f93915 100644 --- a/test/CodeGen/X86/2006-05-02-InstrSched1.ll +++ b/test/CodeGen/X86/Stats/2006-05-02-InstrSched1.ll diff --git a/test/CodeGen/X86/2006-05-02-InstrSched2.ll b/test/CodeGen/X86/Stats/2006-05-02-InstrSched2.ll index 95eefa1e71..95eefa1e71 100644 --- a/test/CodeGen/X86/2006-05-02-InstrSched2.ll +++ b/test/CodeGen/X86/Stats/2006-05-02-InstrSched2.ll diff --git a/test/CodeGen/X86/2006-05-11-InstrSched.ll b/test/CodeGen/X86/Stats/2006-05-11-InstrSched.ll index 37c510786a..37c510786a 100644 --- a/test/CodeGen/X86/2006-05-11-InstrSched.ll +++ b/test/CodeGen/X86/Stats/2006-05-11-InstrSched.ll diff --git a/test/CodeGen/X86/2008-02-18-TailMergingBug.ll b/test/CodeGen/X86/Stats/2008-02-18-TailMergingBug.ll index a1b973d7cc..a1b973d7cc 100644 --- a/test/CodeGen/X86/2008-02-18-TailMergingBug.ll +++ b/test/CodeGen/X86/Stats/2008-02-18-TailMergingBug.ll diff --git a/test/CodeGen/X86/2008-10-27-CoalescerBug.ll b/test/CodeGen/X86/Stats/2008-10-27-CoalescerBug.ll index b2cf34cd20..b2cf34cd20 100644 --- a/test/CodeGen/X86/2008-10-27-CoalescerBug.ll +++ b/test/CodeGen/X86/Stats/2008-10-27-CoalescerBug.ll diff --git a/test/CodeGen/X86/2009-02-25-CommuteBug.ll b/test/CodeGen/X86/Stats/2009-02-25-CommuteBug.ll index 9cbf350940..9cbf350940 100644 --- a/test/CodeGen/X86/2009-02-25-CommuteBug.ll +++ b/test/CodeGen/X86/Stats/2009-02-25-CommuteBug.ll diff --git a/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll b/test/CodeGen/X86/Stats/2009-02-26-MachineLICMBug.ll index d50fe6f73a..d50fe6f73a 100644 --- a/test/CodeGen/X86/2009-02-26-MachineLICMBug.ll +++ b/test/CodeGen/X86/Stats/2009-02-26-MachineLICMBug.ll diff --git a/test/CodeGen/X86/2009-03-23-MultiUseSched.ll b/test/CodeGen/X86/Stats/2009-03-23-MultiUseSched.ll index d934ec9a88..d934ec9a88 100644 --- a/test/CodeGen/X86/2009-03-23-MultiUseSched.ll +++ b/test/CodeGen/X86/Stats/2009-03-23-MultiUseSched.ll diff --git a/test/CodeGen/X86/2009-04-16-SpillerUnfold.ll b/test/CodeGen/X86/Stats/2009-04-16-SpillerUnfold.ll index ad18a0c5b9..ad18a0c5b9 100644 --- a/test/CodeGen/X86/2009-04-16-SpillerUnfold.ll +++ b/test/CodeGen/X86/Stats/2009-04-16-SpillerUnfold.ll diff --git a/test/CodeGen/X86/2010-01-19-OptExtBug.ll b/test/CodeGen/X86/Stats/2010-01-19-OptExtBug.ll index eb4a5c04a2..eb4a5c04a2 100644 --- a/test/CodeGen/X86/2010-01-19-OptExtBug.ll +++ b/test/CodeGen/X86/Stats/2010-01-19-OptExtBug.ll diff --git a/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll b/test/CodeGen/X86/Stats/2011-06-12-FastAllocSpill.ll index 47ef693cc2..47ef693cc2 100644 --- a/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll +++ b/test/CodeGen/X86/Stats/2011-06-12-FastAllocSpill.ll diff --git a/test/CodeGen/X86/2012-03-26-PostRALICMBug.ll b/test/CodeGen/X86/Stats/2012-03-26-PostRALICMBug.ll index 18a3313773..18a3313773 100644 --- a/test/CodeGen/X86/2012-03-26-PostRALICMBug.ll +++ b/test/CodeGen/X86/Stats/2012-03-26-PostRALICMBug.ll diff --git a/test/CodeGen/X86/MachineSink-PHIUse.ll b/test/CodeGen/X86/Stats/MachineSink-PHIUse.ll index 33141680aa..33141680aa 100644 --- a/test/CodeGen/X86/MachineSink-PHIUse.ll +++ b/test/CodeGen/X86/Stats/MachineSink-PHIUse.ll diff --git a/test/CodeGen/X86/constant-pool-remat-0.ll b/test/CodeGen/X86/Stats/constant-pool-remat-0.ll index 4be14d2128..4be14d2128 100644 --- a/test/CodeGen/X86/constant-pool-remat-0.ll +++ b/test/CodeGen/X86/Stats/constant-pool-remat-0.ll diff --git a/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll b/test/CodeGen/X86/Stats/convert-2-addr-3-addr-inc64.ll index 064ee364d1..064ee364d1 100644 --- a/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll +++ b/test/CodeGen/X86/Stats/convert-2-addr-3-addr-inc64.ll diff --git a/test/CodeGen/X86/dagcombine-cse.ll b/test/CodeGen/X86/Stats/dagcombine-cse.ll index af69531246..af69531246 100644 --- a/test/CodeGen/X86/dagcombine-cse.ll +++ b/test/CodeGen/X86/Stats/dagcombine-cse.ll diff --git a/test/CodeGen/X86/hoist-invariant-load.ll b/test/CodeGen/X86/Stats/hoist-invariant-load.ll index 74ecd045b3..74ecd045b3 100644 --- a/test/CodeGen/X86/hoist-invariant-load.ll +++ b/test/CodeGen/X86/Stats/hoist-invariant-load.ll diff --git a/test/CodeGen/X86/licm-nested.ll b/test/CodeGen/X86/Stats/licm-nested.ll index c3f991d7a9..c3f991d7a9 100644 --- a/test/CodeGen/X86/licm-nested.ll +++ b/test/CodeGen/X86/Stats/licm-nested.ll diff --git a/test/CodeGen/X86/Stats/lit.local.cfg b/test/CodeGen/X86/Stats/lit.local.cfg new file mode 100644 index 0000000000..1a5fd5ec86 --- /dev/null +++ b/test/CodeGen/X86/Stats/lit.local.cfg @@ -0,0 +1,8 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'X86' in targets: + config.unsupported = True + +if not config.root.enable_assertions: + config.unsupported = True diff --git a/test/CodeGen/X86/phi-immediate-factoring.ll b/test/CodeGen/X86/Stats/phi-immediate-factoring.ll index 476bb10998..476bb10998 100644 --- a/test/CodeGen/X86/phi-immediate-factoring.ll +++ b/test/CodeGen/X86/Stats/phi-immediate-factoring.ll diff --git a/test/CodeGen/X86/pr3522.ll b/test/CodeGen/X86/Stats/pr3522.ll index d8f37781fc..d8f37781fc 100644 --- a/test/CodeGen/X86/pr3522.ll +++ b/test/CodeGen/X86/Stats/pr3522.ll diff --git a/test/CodeGen/X86/regpressure.ll b/test/CodeGen/X86/Stats/regpressure.ll index 52d7b56f18..52d7b56f18 100644 --- a/test/CodeGen/X86/regpressure.ll +++ b/test/CodeGen/X86/Stats/regpressure.ll diff --git a/test/CodeGen/X86/twoaddr-coalesce-2.ll b/test/CodeGen/X86/Stats/twoaddr-coalesce-2.ll index af6d47af7a..af6d47af7a 100644 --- a/test/CodeGen/X86/twoaddr-coalesce-2.ll +++ b/test/CodeGen/X86/Stats/twoaddr-coalesce-2.ll diff --git a/test/CodeGen/X86/twoaddr-pass-sink.ll b/test/CodeGen/X86/Stats/twoaddr-pass-sink.ll index 513c304e3b..513c304e3b 100644 --- a/test/CodeGen/X86/twoaddr-pass-sink.ll +++ b/test/CodeGen/X86/Stats/twoaddr-pass-sink.ll diff --git a/test/CodeGen/X86/vec_insert-6.ll b/test/CodeGen/X86/Stats/vec_insert-6.ll index 2a4864a48a..2a4864a48a 100644 --- a/test/CodeGen/X86/vec_insert-6.ll +++ b/test/CodeGen/X86/Stats/vec_insert-6.ll diff --git a/test/CodeGen/X86/vec_shuffle-19.ll b/test/CodeGen/X86/Stats/vec_shuffle-19.ll index b26f920e5e..b26f920e5e 100644 --- a/test/CodeGen/X86/vec_shuffle-19.ll +++ b/test/CodeGen/X86/Stats/vec_shuffle-19.ll diff --git a/test/CodeGen/X86/vec_shuffle-20.ll b/test/CodeGen/X86/Stats/vec_shuffle-20.ll index b6b8ba6f84..b6b8ba6f84 100644 --- a/test/CodeGen/X86/vec_shuffle-20.ll +++ b/test/CodeGen/X86/Stats/vec_shuffle-20.ll diff --git a/test/CodeGen/X86/zero-remat.ll b/test/CodeGen/X86/Stats/zero-remat.ll index 4242530f77..4242530f77 100644 --- a/test/CodeGen/X86/zero-remat.ll +++ b/test/CodeGen/X86/Stats/zero-remat.ll diff --git a/test/CodeGen/X86/WidenArith.ll b/test/CodeGen/X86/WidenArith.ll new file mode 100644 index 0000000000..0383bd665b --- /dev/null +++ b/test/CodeGen/X86/WidenArith.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck %s + +;CHECK: test +;CHECK: vaddps +;CHECK: vmulps +;CHECK: vsubps +;CHECK: vcmpltps +;CHECK: vcmpltps +;CHECK: vandps +;CHECK: vandps +;CHECK: ret +define <8 x i32> @test(<8 x float> %a, <8 x float> %b) { + %c1 = fadd <8 x float> %a, %b + %b1 = fmul <8 x float> %b, %a + %d = fsub <8 x float> %b1, %c1 + %res1 = fcmp olt <8 x float> %a, %b1 + %res2 = fcmp olt <8 x float> %c1, %d + %andr = and <8 x i1>%res1, %res2 + %ex = zext <8 x i1> %andr to <8 x i32> + ret <8 x i32>%ex +} + + diff --git a/test/CodeGen/X86/atom-bypass-slow-division-64.ll b/test/CodeGen/X86/atom-bypass-slow-division-64.ll new file mode 100644 index 0000000000..a3bbea3c99 --- /dev/null +++ b/test/CodeGen/X86/atom-bypass-slow-division-64.ll @@ -0,0 +1,46 @@ +; RUN: llc < %s -mcpu=atom -mtriple=i686-linux -march=x86-64 | FileCheck %s + +; Additional tests for 64-bit divide bypass + +define i64 @Test_get_quotient(i64 %a, i64 %b) nounwind { +; CHECK: Test_get_quotient: +; CHECK: orq %rsi, %rcx +; CHECK-NEXT: testq $-65536, %rcx +; CHECK-NEXT: je +; CHECK: idivq +; CHECK: ret +; CHECK: divw +; CHECK: ret + %result = sdiv i64 %a, %b + ret i64 %result +} + +define i64 @Test_get_remainder(i64 %a, i64 %b) nounwind { +; CHECK: Test_get_remainder: +; CHECK: orq %rsi, %rcx +; CHECK-NEXT: testq $-65536, %rcx +; CHECK-NEXT: je +; CHECK: idivq +; CHECK: ret +; CHECK: divw +; CHECK: ret + %result = srem i64 %a, %b + ret i64 %result +} + +define i64 @Test_get_quotient_and_remainder(i64 %a, i64 %b) nounwind { +; CHECK: Test_get_quotient_and_remainder: +; CHECK: orq %rsi, %rcx +; CHECK-NEXT: testq $-65536, %rcx +; CHECK-NEXT: je +; CHECK: idivq +; CHECK: divw +; CHECK: addq +; CHECK: ret +; CHECK-NOT: idivq +; CHECK-NOT: divw + %resultdiv = sdiv i64 %a, %b + %resultrem = srem i64 %a, %b + %result = add i64 %resultdiv, %resultrem + ret i64 %result +} diff --git a/test/CodeGen/X86/atom-bypass-slow-division.ll b/test/CodeGen/X86/atom-bypass-slow-division.ll index e7c9605d3e..4612940445 100644 --- a/test/CodeGen/X86/atom-bypass-slow-division.ll +++ b/test/CodeGen/X86/atom-bypass-slow-division.ll @@ -1,7 +1,7 @@ -; RUN: llc < %s -mcpu=atom -mtriple=i686-linux | FileCheck %s +; RUN: llc < %s -mcpu=atom -mtriple=i686-linux | FileCheck %s -define i32 @test_get_quotient(i32 %a, i32 %b) nounwind { -; CHECK: test_get_quotient +define i32 @Test_get_quotient(i32 %a, i32 %b) nounwind { +; CHECK: Test_get_quotient: ; CHECK: orl %ecx, %edx ; CHECK-NEXT: testl $-256, %edx ; CHECK-NEXT: je @@ -13,8 +13,8 @@ define i32 @test_get_quotient(i32 %a, i32 %b) nounwind { ret i32 %result } -define i32 @test_get_remainder(i32 %a, i32 %b) nounwind { -; CHECK: test_get_remainder +define i32 @Test_get_remainder(i32 %a, i32 %b) nounwind { +; CHECK: Test_get_remainder: ; CHECK: orl %ecx, %edx ; CHECK-NEXT: testl $-256, %edx ; CHECK-NEXT: je @@ -26,8 +26,8 @@ define i32 @test_get_remainder(i32 %a, i32 %b) nounwind { ret i32 %result } -define i32 @test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind { -; CHECK: test_get_quotient_and_remainder +define i32 @Test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind { +; CHECK: Test_get_quotient_and_remainder: ; CHECK: orl %ecx, %edx ; CHECK-NEXT: testl $-256, %edx ; CHECK-NEXT: je @@ -35,7 +35,7 @@ define i32 @test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind { ; CHECK: divb ; CHECK: addl ; CHECK: ret -; CEECK-NOT: idivl +; CHECK-NOT: idivl ; CHECK-NOT: divb %resultdiv = sdiv i32 %a, %b %resultrem = srem i32 %a, %b @@ -43,8 +43,8 @@ define i32 @test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind { ret i32 %result } -define i32 @test_use_div_and_idiv(i32 %a, i32 %b) nounwind { -; CHECK: test_use_div_and_idiv +define i32 @Test_use_div_and_idiv(i32 %a, i32 %b) nounwind { +; CHECK: Test_use_div_and_idiv: ; CHECK: idivl ; CHECK: divb ; CHECK: divl @@ -57,34 +57,34 @@ define i32 @test_use_div_and_idiv(i32 %a, i32 %b) nounwind { ret i32 %result } -define i32 @test_use_div_imm_imm() nounwind { -; CHECK: test_use_div_imm_imm +define i32 @Test_use_div_imm_imm() nounwind { +; CHECK: Test_use_div_imm_imm: ; CHECK: movl $64 %resultdiv = sdiv i32 256, 4 ret i32 %resultdiv } -define i32 @test_use_div_reg_imm(i32 %a) nounwind { -; CHECK: test_use_div_reg_imm -; CEHCK-NOT: test +define i32 @Test_use_div_reg_imm(i32 %a) nounwind { +; CHECK: Test_use_div_reg_imm: +; CHECK-NOT: test ; CHECK-NOT: idiv ; CHECK-NOT: divb %resultdiv = sdiv i32 %a, 33 ret i32 %resultdiv } -define i32 @test_use_rem_reg_imm(i32 %a) nounwind { -; CHECK: test_use_rem_reg_imm -; CEHCK-NOT: test +define i32 @Test_use_rem_reg_imm(i32 %a) nounwind { +; CHECK: Test_use_rem_reg_imm: +; CHECK-NOT: test ; CHECK-NOT: idiv ; CHECK-NOT: divb %resultrem = srem i32 %a, 33 ret i32 %resultrem } -define i32 @test_use_divrem_reg_imm(i32 %a) nounwind { -; CHECK: test_use_divrem_reg_imm -; CEHCK-NOT: test +define i32 @Test_use_divrem_reg_imm(i32 %a) nounwind { +; CHECK: Test_use_divrem_reg_imm: +; CHECK-NOT: test ; CHECK-NOT: idiv ; CHECK-NOT: divb %resultdiv = sdiv i32 %a, 33 @@ -93,8 +93,8 @@ define i32 @test_use_divrem_reg_imm(i32 %a) nounwind { ret i32 %result } -define i32 @test_use_div_imm_reg(i32 %a) nounwind { -; CHECK: test_use_div_imm_reg +define i32 @Test_use_div_imm_reg(i32 %a) nounwind { +; CHECK: Test_use_div_imm_reg: ; CHECK: test ; CHECK: idiv ; CHECK: divb @@ -102,8 +102,8 @@ define i32 @test_use_div_imm_reg(i32 %a) nounwind { ret i32 %resultdiv } -define i32 @test_use_rem_imm_reg(i32 %a) nounwind { -; CHECK: test_use_rem_imm_reg +define i32 @Test_use_rem_imm_reg(i32 %a) nounwind { +; CHECK: Test_use_rem_imm_reg: ; CHECK: test ; CHECK: idiv ; CHECK: divb diff --git a/test/CodeGen/X86/atom-pad-short-functions.ll b/test/CodeGen/X86/atom-pad-short-functions.ll new file mode 100644 index 0000000000..b9a39e08cb --- /dev/null +++ b/test/CodeGen/X86/atom-pad-short-functions.ll @@ -0,0 +1,103 @@ +; RUN: llc < %s -O1 -mcpu=atom -mtriple=i686-linux | FileCheck %s + +declare void @external_function(...) + +define i32 @test_return_val(i32 %a) nounwind { +; CHECK: test_return_val +; CHECK: movl +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: ret + ret i32 %a +} + +define i32 @test_optsize(i32 %a) nounwind optsize { +; CHECK: test_optsize +; CHECK: movl +; CHECK-NEXT: ret + ret i32 %a +} + +define i32 @test_minsize(i32 %a) nounwind minsize { +; CHECK: test_minsize +; CHECK: movl +; CHECK-NEXT: ret + ret i32 %a +} + +define i32 @test_add(i32 %a, i32 %b) nounwind { +; CHECK: test_add +; CHECK: addl +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: ret + %result = add i32 %a, %b + ret i32 %result +} + +define i32 @test_multiple_ret(i32 %a, i32 %b, i1 %c) nounwind { +; CHECK: @test_multiple_ret +; CHECK: je + +; CHECK: nop +; CHECK: nop +; CHECK: ret + +; CHECK: nop +; CHECK: nop +; CHECK: ret + + br i1 %c, label %bb1, label %bb2 + +bb1: + ret i32 %a + +bb2: + ret i32 %b +} + +define void @test_call_others(i32 %x) nounwind +{ +; CHECK: test_call_others +; CHECK: je + %tobool = icmp eq i32 %x, 0 + br i1 %tobool, label %if.end, label %true.case + +; CHECK: jmp external_function +true.case: + tail call void bitcast (void (...)* @external_function to void ()*)() nounwind + br label %if.end + +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: ret +if.end: + ret void + +} + +define void @test_branch_to_same_bb(i32 %x, i32 %y) nounwind { +; CHECK: @test_branch_to_same_bb + %cmp = icmp sgt i32 %x, 0 + br i1 %cmp, label %while.cond, label %while.end + +while.cond: + br label %while.cond + +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: nop +; CHECK: ret +while.end: + ret void +} + diff --git a/test/CodeGen/X86/atomic-dagsched.ll b/test/CodeGen/X86/atomic-dagsched.ll new file mode 100644 index 0000000000..0e7cf8c096 --- /dev/null +++ b/test/CodeGen/X86/atomic-dagsched.ll @@ -0,0 +1,110 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s + +define void @test(i8** %a, i64* %b, i64 %c, i64 %d) nounwind { +entry: + %ptrtoarg4 = load i8** %a, align 8 + %brglist1 = getelementptr i8** %a, i64 1 + %ptrtoarg25 = load i8** %brglist1, align 8 + %0 = load i64* %b, align 8 + %1 = mul i64 %0, 4 + %scevgep = getelementptr i8* %ptrtoarg25, i64 %1 + %2 = mul i64 %d, 4 + br label %loop.cond + +loop.cond: ; preds = %test.exit, %entry + %asr.iv6 = phi i8* [ %29, %test.exit ], [ %scevgep, %entry ] + %iv = phi i64 [ %0, %entry ], [ %28, %test.exit ] + %3 = icmp eq i64 %iv, %c + br i1 %3, label %return, label %loop + +loop: ; preds = %loop.cond + %4 = load i64* addrspace(256)* inttoptr (i64 264 to i64* addrspace(256)*), align 8, !tbaa !0 + %5 = load i64* %4, align 8, !tbaa !3 + %vector.size.i = ashr i64 %5, 3 + %num.vector.wi.i = shl i64 %vector.size.i, 3 + %6 = icmp eq i64 %vector.size.i, 0 + br i1 %6, label %scalarIf.i, label %dim_0_vector_pre_head.i + +dim_0_vector_pre_head.i: ; preds = %loop + %7 = trunc i64 %5 to i32 + %tempvector_func.i = insertelement <8 x i32> undef, i32 %7, i32 0 + %vectorvector_func.i = shufflevector <8 x i32> %tempvector_func.i, <8 x i32> undef, <8 x i32> zeroinitializer + br label %vector_kernel_entry.i + +vector_kernel_entry.i: ; preds = %vector_kernel_entry.i, %dim_0_vector_pre_head.i + %asr.iv9 = phi i8* [ %scevgep10, %vector_kernel_entry.i ], [ %asr.iv6, %dim_0_vector_pre_head.i ] + %asr.iv = phi i64 [ %asr.iv.next, %vector_kernel_entry.i ], [ %vector.size.i, %dim_0_vector_pre_head.i ] + %8 = bitcast i8* %ptrtoarg4 to i32 addrspace(1)* + %asr.iv911 = bitcast i8* %asr.iv9 to <8 x i32> addrspace(1)* + %9 = load <8 x i32> addrspace(1)* %asr.iv911, align 4 + %extract8vector_func.i = extractelement <8 x i32> %9, i32 0 + %extract9vector_func.i = extractelement <8 x i32> %9, i32 1 + %extract10vector_func.i = extractelement <8 x i32> %9, i32 2 + %extract11vector_func.i = extractelement <8 x i32> %9, i32 3 + %extract12vector_func.i = extractelement <8 x i32> %9, i32 4 + %extract13vector_func.i = extractelement <8 x i32> %9, i32 5 + %extract14vector_func.i = extractelement <8 x i32> %9, i32 6 + %extract15vector_func.i = extractelement <8 x i32> %9, i32 7 + %10 = atomicrmw min i32 addrspace(1)* %8, i32 %extract8vector_func.i seq_cst + %11 = atomicrmw min i32 addrspace(1)* %8, i32 %extract9vector_func.i seq_cst + %12 = atomicrmw min i32 addrspace(1)* %8, i32 %extract10vector_func.i seq_cst + %13 = atomicrmw min i32 addrspace(1)* %8, i32 %extract11vector_func.i seq_cst + %14 = atomicrmw min i32 addrspace(1)* %8, i32 %extract12vector_func.i seq_cst + %15 = atomicrmw min i32 addrspace(1)* %8, i32 %extract13vector_func.i seq_cst + %16 = atomicrmw min i32 addrspace(1)* %8, i32 %extract14vector_func.i seq_cst + %17 = atomicrmw min i32 addrspace(1)* %8, i32 %extract15vector_func.i seq_cst + store <8 x i32> %vectorvector_func.i, <8 x i32> addrspace(1)* %asr.iv911, align 4 + %asr.iv.next = add i64 %asr.iv, -1 + %scevgep10 = getelementptr i8* %asr.iv9, i64 32 + %dim_0_vector_cmp.to.max.i = icmp eq i64 %asr.iv.next, 0 + br i1 %dim_0_vector_cmp.to.max.i, label %scalarIf.i, label %vector_kernel_entry.i + +scalarIf.i: ; preds = %vector_kernel_entry.i, %loop + %exec_wi.i = phi i64 [ 0, %loop ], [ %num.vector.wi.i, %vector_kernel_entry.i ] + %18 = icmp eq i64 %exec_wi.i, %5 + br i1 %18, label %test.exit, label %dim_0_pre_head.i + +dim_0_pre_head.i: ; preds = %scalarIf.i + %19 = load i64* addrspace(256)* inttoptr (i64 264 to i64* addrspace(256)*), align 8, !tbaa !0 + %20 = load i64* %19, align 8, !tbaa !3 + %21 = trunc i64 %20 to i32 + %22 = mul i64 %vector.size.i, 8 + br label %scalar_kernel_entry.i + +scalar_kernel_entry.i: ; preds = %scalar_kernel_entry.i, %dim_0_pre_head.i + %asr.iv12 = phi i64 [ %asr.iv.next13, %scalar_kernel_entry.i ], [ %22, %dim_0_pre_head.i ] + %23 = bitcast i8* %asr.iv6 to i32 addrspace(1)* + %24 = bitcast i8* %ptrtoarg4 to i32 addrspace(1)* + %scevgep16 = getelementptr i32 addrspace(1)* %23, i64 %asr.iv12 + %25 = load i32 addrspace(1)* %scevgep16, align 4, !tbaa !4 + %26 = atomicrmw min i32 addrspace(1)* %24, i32 %25 seq_cst + %scevgep15 = getelementptr i32 addrspace(1)* %23, i64 %asr.iv12 + store i32 %21, i32 addrspace(1)* %scevgep15, align 4, !tbaa !4 + %asr.iv.next13 = add i64 %asr.iv12, 1 + %dim_0_cmp.to.max.i = icmp eq i64 %5, %asr.iv.next13 + br i1 %dim_0_cmp.to.max.i, label %test.exit, label %scalar_kernel_entry.i + +test.exit: ; preds = %scalar_kernel_entry.i, %scalarIf.i + %27 = bitcast i8* %asr.iv6 to i1* + %28 = add i64 %iv, %d + store i64 %28, i64* %b, align 8 + %scevgep8 = getelementptr i1* %27, i64 %2 + %29 = bitcast i1* %scevgep8 to i8* + br label %loop.cond + +return: ; preds = %loop.cond + store i64 %0, i64* %b, align 8 + ret void +} + +!0 = metadata !{metadata !"any pointer", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} +!3 = metadata !{metadata !"long", metadata !1} +!4 = metadata !{metadata !"int", metadata !1} + +; CHECK: test +; CHECK: decq +; CHECK-NOT: cmpxchgl +; CHECK: jne +; CHECK: ret diff --git a/test/CodeGen/X86/atomic-load-store-wide.ll b/test/CodeGen/X86/atomic-load-store-wide.ll index a9ebfef2eb..17e04f0590 100644 --- a/test/CodeGen/X86/atomic-load-store-wide.ll +++ b/test/CodeGen/X86/atomic-load-store-wide.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -march=x86 -verify-machineinstrs | FileCheck %s ; 64-bit load/store on x86-32 ; FIXME: The generated code can be substantially improved. diff --git a/test/CodeGen/X86/atomic-load-store.ll b/test/CodeGen/X86/atomic-load-store.ll index fee45859c1..86a744ed00 100644 --- a/test/CodeGen/X86/atomic-load-store.ll +++ b/test/CodeGen/X86/atomic-load-store.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7.0 -verify-machineinstrs -O0 | FileCheck %s define void @test1(i32* %ptr, i32 %val1) { ; CHECK: test1 diff --git a/test/CodeGen/X86/atomic-minmax-i6432.ll b/test/CodeGen/X86/atomic-minmax-i6432.ll index e3ef605f7f..62f784f696 100644 --- a/test/CodeGen/X86/atomic-minmax-i6432.ll +++ b/test/CodeGen/X86/atomic-minmax-i6432.ll @@ -1,5 +1,6 @@ -; RUN: llc -march=x86 -mattr=+cmov -mtriple=i386-pc-linux < %s | FileCheck %s -check-prefix=LINUX -; RUN: llc -march=x86 -mtriple=i386-macosx -relocation-model=pic < %s | FileCheck %s -check-prefix=PIC +; RUN: llc -march=x86 -mattr=+cmov -mtriple=i386-pc-linux -verify-machineinstrs < %s | FileCheck %s -check-prefix=LINUX +; RUN: llc -march=x86 -mattr=-cmov -mtriple=i386-pc-linux -verify-machineinstrs < %s | FileCheck %s -check-prefix=NOCMOV +; RUN: llc -march=x86 -mtriple=i386-macosx -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s -check-prefix=PIC @sc64 = external global i64 @@ -16,6 +17,16 @@ define void @atomic_maxmin_i6432() { ; LINUX: lock ; LINUX-NEXT: cmpxchg8b ; LINUX: jne [[LABEL]] +; NOCMOV: [[LABEL:.LBB[0-9]+_[0-9]+]] +; NOCMOV: cmpl +; NOCMOV: setl +; NOCMOV: cmpl +; NOCMOV: setl +; NOCMOV: jne +; NOCMOV: jne +; NOCMOV: lock +; NOCMOV-NEXT: cmpxchg8b +; NOCMOV: jne [[LABEL]] %2 = atomicrmw min i64* @sc64, i64 6 acquire ; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]] ; LINUX: cmpl @@ -27,6 +38,16 @@ define void @atomic_maxmin_i6432() { ; LINUX: lock ; LINUX-NEXT: cmpxchg8b ; LINUX: jne [[LABEL]] +; NOCMOV: [[LABEL:.LBB[0-9]+_[0-9]+]] +; NOCMOV: cmpl +; NOCMOV: setg +; NOCMOV: cmpl +; NOCMOV: setg +; NOCMOV: jne +; NOCMOV: jne +; NOCMOV: lock +; NOCMOV-NEXT: cmpxchg8b +; NOCMOV: jne [[LABEL]] %3 = atomicrmw umax i64* @sc64, i64 7 acquire ; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]] ; LINUX: cmpl @@ -38,6 +59,16 @@ define void @atomic_maxmin_i6432() { ; LINUX: lock ; LINUX-NEXT: cmpxchg8b ; LINUX: jne [[LABEL]] +; NOCMOV: [[LABEL:.LBB[0-9]+_[0-9]+]] +; NOCMOV: cmpl +; NOCMOV: setb +; NOCMOV: cmpl +; NOCMOV: setb +; NOCMOV: jne +; NOCMOV: jne +; NOCMOV: lock +; NOCMOV-NEXT: cmpxchg8b +; NOCMOV: jne [[LABEL]] %4 = atomicrmw umin i64* @sc64, i64 8 acquire ; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]] ; LINUX: cmpl @@ -49,6 +80,16 @@ define void @atomic_maxmin_i6432() { ; LINUX: lock ; LINUX-NEXT: cmpxchg8b ; LINUX: jne [[LABEL]] +; NOCMOV: [[LABEL:.LBB[0-9]+_[0-9]+]] +; NOCMOV: cmpl +; NOCMOV: seta +; NOCMOV: cmpl +; NOCMOV: seta +; NOCMOV: jne +; NOCMOV: jne +; NOCMOV: lock +; NOCMOV-NEXT: cmpxchg8b +; NOCMOV: jne [[LABEL]] ret void } diff --git a/test/CodeGen/X86/atomic-or.ll b/test/CodeGen/X86/atomic-or.ll index 3f02eafb44..d759beb2ca 100644 --- a/test/CodeGen/X86/atomic-or.ll +++ b/test/CodeGen/X86/atomic-or.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -march=x86-64 -verify-machineinstrs | FileCheck %s ; rdar://9692967 diff --git a/test/CodeGen/X86/atomic-pointer.ll b/test/CodeGen/X86/atomic-pointer.ll index a455277be4..ec3e6c3a8c 100644 --- a/test/CodeGen/X86/atomic-pointer.ll +++ b/test/CodeGen/X86/atomic-pointer.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i686-none-linux | FileCheck %s +; RUN: llc < %s -mtriple=i686-none-linux -verify-machineinstrs | FileCheck %s define i32* @test_atomic_ptr_load(i32** %a0) { ; CHECK: test_atomic_ptr_load diff --git a/test/CodeGen/X86/atomic16.ll b/test/CodeGen/X86/atomic16.ll index 824995d6cb..ec2887e29f 100644 --- a/test/CodeGen/X86/atomic16.ll +++ b/test/CodeGen/X86/atomic16.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -O0 -mtriple=x86_64-unknown-unknown -mcpu=corei7 -show-mc-encoding | FileCheck %s --check-prefix X64 -; RUN: llc < %s -O0 -mtriple=i386-unknown-unknown -mcpu=corei7 | FileCheck %s --check-prefix X32 +; RUN: llc < %s -O0 -mtriple=x86_64-unknown-unknown -mcpu=corei7 -verify-machineinstrs -show-mc-encoding | FileCheck %s --check-prefix X64 +; RUN: llc < %s -O0 -mtriple=i386-unknown-unknown -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X32 @sc16 = external global i16 diff --git a/test/CodeGen/X86/atomic32.ll b/test/CodeGen/X86/atomic32.ll index dc927d8cb6..3ea96bf169 100644 --- a/test/CodeGen/X86/atomic32.ll +++ b/test/CodeGen/X86/atomic32.ll @@ -1,5 +1,8 @@ -; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 | FileCheck %s --check-prefix X64 -; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 | FileCheck %s --check-prefix X32 +; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X64 +; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X32 +; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -mattr=-cmov -verify-machineinstrs | FileCheck %s --check-prefix NOCMOV + +; XFAIL: cygwin,mingw32,win32 @sc32 = external global i32 @@ -164,9 +167,15 @@ define void @atomic_fetch_max32(i32 %x) nounwind { ; X32: cmov ; X32: lock ; X32: cmpxchgl + +; NOCMOV: cmpl +; NOCMOV: jl +; NOCMOV: lock +; NOCMOV: cmpxchgl ret void ; X64: ret ; X32: ret +; NOCMOV: ret } define void @atomic_fetch_min32(i32 %x) nounwind { @@ -180,9 +189,15 @@ define void @atomic_fetch_min32(i32 %x) nounwind { ; X32: cmov ; X32: lock ; X32: cmpxchgl + +; NOCMOV: cmpl +; NOCMOV: jg +; NOCMOV: lock +; NOCMOV: cmpxchgl ret void ; X64: ret ; X32: ret +; NOCMOV: ret } define void @atomic_fetch_umax32(i32 %x) nounwind { @@ -196,9 +211,15 @@ define void @atomic_fetch_umax32(i32 %x) nounwind { ; X32: cmov ; X32: lock ; X32: cmpxchgl + +; NOCMOV: cmpl +; NOCMOV: jb +; NOCMOV: lock +; NOCMOV: cmpxchgl ret void ; X64: ret ; X32: ret +; NOCMOV: ret } define void @atomic_fetch_umin32(i32 %x) nounwind { @@ -207,13 +228,20 @@ define void @atomic_fetch_umin32(i32 %x) nounwind { ; X64: cmov ; X64: lock ; X64: cmpxchgl + ; X32: cmpl ; X32: cmov ; X32: lock ; X32: cmpxchgl + +; NOCMOV: cmpl +; NOCMOV: ja +; NOCMOV: lock +; NOCMOV: cmpxchgl ret void ; X64: ret ; X32: ret +; NOCMOV: ret } define void @atomic_fetch_cmpxchg32() nounwind { diff --git a/test/CodeGen/X86/atomic64.ll b/test/CodeGen/X86/atomic64.ll index 45785cc8fe..d362c31e6d 100644 --- a/test/CodeGen/X86/atomic64.ll +++ b/test/CodeGen/X86/atomic64.ll @@ -1,4 +1,6 @@ -; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 | FileCheck %s --check-prefix X64 +; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X64 + +; XFAIL: cygwin,mingw32,win32 @sc64 = external global i64 diff --git a/test/CodeGen/X86/atomic6432.ll b/test/CodeGen/X86/atomic6432.ll index f9b21c5bc7..31e66c876e 100644 --- a/test/CodeGen/X86/atomic6432.ll +++ b/test/CodeGen/X86/atomic6432.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 | FileCheck %s --check-prefix X32 +; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X32 @sc64 = external global i64 diff --git a/test/CodeGen/X86/atomic8.ll b/test/CodeGen/X86/atomic8.ll index 412428406d..3278ed1f50 100644 --- a/test/CodeGen/X86/atomic8.ll +++ b/test/CodeGen/X86/atomic8.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 | FileCheck %s --check-prefix X64 -; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 | FileCheck %s --check-prefix X32 +; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X64 +; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -verify-machineinstrs | FileCheck %s --check-prefix X32 @sc8 = external global i8 diff --git a/test/CodeGen/X86/atomic_add.ll b/test/CodeGen/X86/atomic_add.ll index d94499889d..6b3a6b224d 100644 --- a/test/CodeGen/X86/atomic_add.ll +++ b/test/CodeGen/X86/atomic_add.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -march=x86-64 -verify-machineinstrs | FileCheck %s ; rdar://7103704 diff --git a/test/CodeGen/X86/atomic_op.ll b/test/CodeGen/X86/atomic_op.ll index c5fa07d07d..a378d6e8d6 100644 --- a/test/CodeGen/X86/atomic_op.ll +++ b/test/CodeGen/X86/atomic_op.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+cmov | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+cmov -verify-machineinstrs | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" diff --git a/test/CodeGen/X86/avx-cvt.ll b/test/CodeGen/X86/avx-cvt.ll index d0a7fe0100..62bdea2b49 100644 --- a/test/CodeGen/X86/avx-cvt.ll +++ b/test/CodeGen/X86/avx-cvt.ll @@ -46,7 +46,7 @@ entry: ret double %conv } -; CHECK: vcvtsi2sd (% +; CHECK: vcvtsi2sdl (% define double @funcB(i32* nocapture %e) nounwind uwtable readonly ssp { entry: %tmp1 = load i32* %e, align 4 @@ -54,7 +54,7 @@ entry: ret double %conv } -; CHECK: vcvtsi2ss (% +; CHECK: vcvtsi2ssl (% define float @funcC(i32* nocapture %e) nounwind uwtable readonly ssp { entry: %tmp1 = load i32* %e, align 4 diff --git a/test/CodeGen/X86/avx-intel-ocl.ll b/test/CodeGen/X86/avx-intel-ocl.ll index 0fec9658d6..055072098a 100644 --- a/test/CodeGen/X86/avx-intel-ocl.ll +++ b/test/CodeGen/X86/avx-intel-ocl.ll @@ -127,3 +127,43 @@ define i32 @test_int(i32 %a, i32 %b) nounwind { %c = add i32 %c2, %b ret i32 %c } + +; WIN64: test_float4 +; WIN64-NOT: vzeroupper +; WIN64: call +; WIN64-NOT: vzeroupper +; WIN64: call +; WIN64: ret + +; X64: test_float4 +; X64-NOT: vzeroupper +; X64: call +; X64-NOT: vzeroupper +; X64: call +; X64: ret + +; X32: test_float4 +; X32: vzeroupper +; X32: call +; X32: vzeroupper +; X32: call +; X32: ret + +declare <4 x float> @func_float4(<4 x float>, <4 x float>, <4 x float>) + +define <8 x float> @test_float4(<8 x float> %a, <8 x float> %b, <8 x float> %c) nounwind readnone { +entry: + %0 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> + %1 = shufflevector <8 x float> %b, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> + %2 = shufflevector <8 x float> %c, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> + %call.i = tail call intel_ocl_bicc <4 x float> @func_float4(<4 x float> %0, <4 x float> %1, <4 x float> %2) nounwind + %3 = shufflevector <4 x float> %call.i, <4 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef> + %4 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> + %5 = shufflevector <8 x float> %b, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> + %6 = shufflevector <8 x float> %c, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> + %call.i2 = tail call intel_ocl_bicc <4 x float> @func_float4(<4 x float> %4, <4 x float> %5, <4 x float> %6) nounwind + %7 = shufflevector <4 x float> %call.i2, <4 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef> + %8 = shufflevector <8 x float> %3, <8 x float> %7, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> + ret <8 x float> %8 +} + diff --git a/test/CodeGen/X86/avx-load-store.ll b/test/CodeGen/X86/avx-load-store.ll index c9fc66a8a7..77a7c4f945 100644 --- a/test/CodeGen/X86/avx-load-store.ll +++ b/test/CodeGen/X86/avx-load-store.ll @@ -53,19 +53,24 @@ define void @storev16i16(<16 x i16> %a) nounwind { unreachable } -; CHECK: vmovups %ymm +; CHECK: storev16i16_01 +; CHECK: vextractf128 +; CHECK: vmovaps %xmm define void @storev16i16_01(<16 x i16> %a) nounwind { store <16 x i16> %a, <16 x i16>* undef, align 4 unreachable } +; CHECK: storev32i8 ; CHECK: vmovaps %ymm define void @storev32i8(<32 x i8> %a) nounwind { store <32 x i8> %a, <32 x i8>* undef, align 32 unreachable } -; CHECK: vmovups %ymm +; CHECK: storev32i8_01 +; CHECK: vextractf128 +; CHECK: vmovups %xmm define void @storev32i8_01(<32 x i8> %a) nounwind { store <32 x i8> %a, <32 x i8>* undef, align 4 unreachable @@ -76,7 +81,7 @@ define void @storev32i8_01(<32 x i8> %a) nounwind { ; CHECK: _double_save ; CHECK-NOT: vinsertf128 $1 ; CHECK-NOT: vinsertf128 $0 -; CHECK: vmovaps %xmm +; CHECK: vmovups %xmm ; CHECK: vmovaps %xmm define void @double_save(<4 x i32> %A, <4 x i32> %B, <8 x i32>* %P) nounwind ssp { entry: diff --git a/test/CodeGen/X86/avx-sext.ll b/test/CodeGen/X86/avx-sext.ll index 3713a8c377..7ae0d36c08 100755 --- a/test/CodeGen/X86/avx-sext.ll +++ b/test/CodeGen/X86/avx-sext.ll @@ -1,17 +1,167 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck %s -check-prefix=AVX +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSSE3 +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=pentium4 | FileCheck %s -check-prefix=SSE2 define <8 x i32> @sext_8i16_to_8i32(<8 x i16> %A) nounwind uwtable readnone ssp { -;CHECK: sext_8i16_to_8i32 -;CHECK: vpmovsxwd +; AVX: sext_8i16_to_8i32 +; AVX: vpmovsxwd %B = sext <8 x i16> %A to <8 x i32> ret <8 x i32>%B } define <4 x i64> @sext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp { -;CHECK: sext_4i32_to_4i64 -;CHECK: vpmovsxdq +; AVX: sext_4i32_to_4i64 +; AVX: vpmovsxdq %B = sext <4 x i32> %A to <4 x i64> ret <4 x i64>%B } + +; AVX: load_sext_test1 +; AVX: vpmovsxwd (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test1 +; SSSE3: movq +; SSSE3: punpcklwd %xmm{{.*}}, %xmm{{.*}} +; SSSE3: psrad $16 +; SSSE3: ret + +; SSE2: load_sext_test1 +; SSE2: movq +; SSE2: punpcklwd %xmm{{.*}}, %xmm{{.*}} +; SSE2: psrad $16 +; SSE2: ret +define <4 x i32> @load_sext_test1(<4 x i16> *%ptr) { + %X = load <4 x i16>* %ptr + %Y = sext <4 x i16> %X to <4 x i32> + ret <4 x i32>%Y +} + +; AVX: load_sext_test2 +; AVX: vpmovsxbd (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test2 +; SSSE3: movd +; SSSE3: pshufb +; SSSE3: psrad $24 +; SSSE3: ret + +; SSE2: load_sext_test2 +; SSE2: movl +; SSE2: psrad $24 +; SSE2: ret +define <4 x i32> @load_sext_test2(<4 x i8> *%ptr) { + %X = load <4 x i8>* %ptr + %Y = sext <4 x i8> %X to <4 x i32> + ret <4 x i32>%Y +} + +; AVX: load_sext_test3 +; AVX: vpmovsxbq (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test3 +; SSSE3: movsbq +; SSSE3: movsbq +; SSSE3: punpcklqdq +; SSSE3: ret + +; SSE2: load_sext_test3 +; SSE2: movsbq +; SSE2: movsbq +; SSE2: punpcklqdq +; SSE2: ret +define <2 x i64> @load_sext_test3(<2 x i8> *%ptr) { + %X = load <2 x i8>* %ptr + %Y = sext <2 x i8> %X to <2 x i64> + ret <2 x i64>%Y +} + +; AVX: load_sext_test4 +; AVX: vpmovsxwq (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test4 +; SSSE3: movswq +; SSSE3: movswq +; SSSE3: punpcklqdq +; SSSE3: ret + +; SSE2: load_sext_test4 +; SSE2: movswq +; SSE2: movswq +; SSE2: punpcklqdq +; SSE2: ret +define <2 x i64> @load_sext_test4(<2 x i16> *%ptr) { + %X = load <2 x i16>* %ptr + %Y = sext <2 x i16> %X to <2 x i64> + ret <2 x i64>%Y +} + +; AVX: load_sext_test5 +; AVX: vpmovsxdq (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test5 +; SSSE3: movslq +; SSSE3: movslq +; SSSE3: punpcklqdq +; SSSE3: ret + +; SSE2: load_sext_test5 +; SSE2: movslq +; SSE2: movslq +; SSE2: punpcklqdq +; SSE2: ret +define <2 x i64> @load_sext_test5(<2 x i32> *%ptr) { + %X = load <2 x i32>* %ptr + %Y = sext <2 x i32> %X to <2 x i64> + ret <2 x i64>%Y +} + +; AVX: load_sext_test6 +; AVX: vpmovsxbw (%r{{[^,]*}}), %xmm{{.*}} +; AVX: ret + +; SSSE3: load_sext_test6 +; SSSE3: movq +; SSSE3: punpcklbw +; SSSE3: psraw $8 +; SSSE3: ret + +; SSE2: load_sext_test6 +; SSE2: movq +; SSE2: punpcklbw +; SSE2: psraw $8 +; SSE2: ret +define <8 x i16> @load_sext_test6(<8 x i8> *%ptr) { + %X = load <8 x i8>* %ptr + %Y = sext <8 x i8> %X to <8 x i16> + ret <8 x i16>%Y +} + +; AVX: sext_4i1_to_4i64 +; AVX: vpslld $31 +; AVX: vpsrad $31 +; AVX: vpmovsxdq +; AVX: vpmovsxdq +; AVX: ret +define <4 x i64> @sext_4i1_to_4i64(<4 x i1> %mask) { + %extmask = sext <4 x i1> %mask to <4 x i64> + ret <4 x i64> %extmask +} + +; AVX: sext_4i8_to_4i64 +; AVX: vpslld $24 +; AVX: vpsrad $24 +; AVX: vpmovsxdq +; AVX: vpmovsxdq +; AVX: ret +define <4 x i64> @sext_4i8_to_4i64(<4 x i8> %mask) { + %extmask = sext <4 x i8> %mask to <4 x i64> + ret <4 x i64> %extmask +} + diff --git a/test/CodeGen/X86/avx-shift.ll b/test/CodeGen/X86/avx-shift.ll index 681747b844..01eb7361e2 100644 --- a/test/CodeGen/X86/avx-shift.ll +++ b/test/CodeGen/X86/avx-shift.ll @@ -105,13 +105,22 @@ define <32 x i8> @vshift12(<32 x i8> %a) nounwind readnone { ; CHECK: _vshift08 ; CHECK: vextractf128 $1 ; CHECK: vpslld $23 -; CHECK: vextractf128 $1 ; CHECK: vpslld $23 define <8 x i32> @vshift08(<8 x i32> %a) nounwind { %bitop = shl <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, %a ret <8 x i32> %bitop } +; PR15141 +; CHECK: _vshift13: +; CHECK-NOT: vpsll +; CHECK: vcvttps2dq +; CHECK-NEXT: vpmulld +define <4 x i32> @vshift13(<4 x i32> %in) { + %T = shl <4 x i32> %in, <i32 0, i32 1, i32 2, i32 4> + ret <4 x i32> %T +} + ;;; Uses shifts for sign extension ; CHECK: _sext_v16i16 ; CHECK: vpsllw diff --git a/test/CodeGen/X86/avx-shuffle.ll b/test/CodeGen/X86/avx-shuffle.ll index 65685a3224..73faa1fe0d 100644 --- a/test/CodeGen/X86/avx-shuffle.ll +++ b/test/CodeGen/X86/avx-shuffle.ll @@ -98,8 +98,8 @@ define i32 @test10(<4 x i32> %a) nounwind { } define <4 x float> @test11(<4 x float> %a) nounwind { -; check: test11 -; check: vpermilps $27 +; CHECK: test11 +; CHECK: vpshufd $27 %tmp1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> ret <4 x float> %tmp1 } @@ -113,8 +113,8 @@ define <4 x float> @test12(<4 x float>* %a) nounwind { } define <4 x i32> @test13(<4 x i32> %a) nounwind { -; check: test13 -; check: vpshufd $27 +; CHECK: test13 +; CHECK: vpshufd $27 %tmp1 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> ret <4 x i32> %tmp1 } diff --git a/test/CodeGen/X86/avx-splat.ll b/test/CodeGen/X86/avx-splat.ll index 67e4b40810..5c01c2cc5b 100644 --- a/test/CodeGen/X86/avx-splat.ll +++ b/test/CodeGen/X86/avx-splat.ll @@ -3,8 +3,8 @@ ; CHECK: vpunpcklbw %xmm ; CHECK-NEXT: vpunpckhbw %xmm +; CHECK-NEXT: vpshufd $85 ; CHECK-NEXT: vinsertf128 $1 -; CHECK-NEXT: vpermilps $85 define <32 x i8> @funcA(<32 x i8> %a) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <32 x i8> %a, <32 x i8> undef, <32 x i32> <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5> @@ -12,8 +12,8 @@ entry: } ; CHECK: vpunpckhwd %xmm +; CHECK-NEXT: vpshufd $85 ; CHECK-NEXT: vinsertf128 $1 -; CHECK-NEXT: vpermilps $85 define <16 x i16> @funcB(<16 x i16> %a) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5> diff --git a/test/CodeGen/X86/avx-vextractf128.ll b/test/CodeGen/X86/avx-vextractf128.ll index ff56a45499..ad8365bb59 100644 --- a/test/CodeGen/X86/avx-vextractf128.ll +++ b/test/CodeGen/X86/avx-vextractf128.ll @@ -102,3 +102,21 @@ entry: store <2 x i64> %2, <2 x i64>* %addr, align 1 ret void } + +; PR15462 +define void @t9(i64* %p) { + store i64 0, i64* %p + %q = getelementptr i64* %p, i64 1 + store i64 0, i64* %q + %r = getelementptr i64* %p, i64 2 + store i64 0, i64* %r + %s = getelementptr i64* %p, i64 3 + store i64 0, i64* %s + ret void + +; CHECK: t9: +; CHECK: vxorps %xmm +; CHECK-NOT: vextractf +; CHECK: vmovups +; CHECK: vmovups +} diff --git a/test/CodeGen/X86/avx-vpermil.ll b/test/CodeGen/X86/avx-vpermil.ll index cb904b9331..7f2f9d821d 100644 --- a/test/CodeGen/X86/avx-vpermil.ll +++ b/test/CodeGen/X86/avx-vpermil.ll @@ -45,8 +45,8 @@ entry: ret <8 x float> %shuffle } -; CHECK: palignr -; CHECK: palignr +; CHECK: palignr $8 +; CHECK: psrldq $8 define <8 x float> @funcF(<8 x float> %a) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <8 x float> %a, <8 x float> zeroinitializer, <8 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9> diff --git a/test/CodeGen/X86/avx-zext.ll b/test/CodeGen/X86/avx-zext.ll index b630e9d146..582537ea90 100755 --- a/test/CodeGen/X86/avx-zext.ll +++ b/test/CodeGen/X86/avx-zext.ll @@ -18,11 +18,10 @@ define <4 x i64> @zext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp ret <4 x i64>%B } - define <8 x i32> @zext_8i8_to_8i32(<8 x i8> %z) { ;CHECK: zext_8i8_to_8i32 ;CHECK: vpunpckhwd -;CHECK: vpunpcklwd +;CHECK: vpmovzxwd ;CHECK: vinsertf128 ;CHECK: ret %t = zext <8 x i8> %z to <8 x i32> diff --git a/test/CodeGen/X86/avx2-conversions.ll b/test/CodeGen/X86/avx2-conversions.ll index b47491335a..3ce08dcc73 100755 --- a/test/CodeGen/X86/avx2-conversions.ll +++ b/test/CodeGen/X86/avx2-conversions.ll @@ -63,6 +63,47 @@ define <8 x i32> @zext_8i8_8i32(<8 x i8> %A) nounwind { ret <8 x i32>%B } +; CHECK: load_sext_test1 +; CHECK: vpmovsxdq (%r{{[^,]*}}), %ymm{{.*}} +; CHECK: ret +define <4 x i64> @load_sext_test1(<4 x i32> *%ptr) { + %X = load <4 x i32>* %ptr + %Y = sext <4 x i32> %X to <4 x i64> + ret <4 x i64>%Y +} + +; CHECK: load_sext_test2 +; CHECK: vpmovsxbq (%r{{[^,]*}}), %ymm{{.*}} +; CHECK: ret +define <4 x i64> @load_sext_test2(<4 x i8> *%ptr) { + %X = load <4 x i8>* %ptr + %Y = sext <4 x i8> %X to <4 x i64> + ret <4 x i64>%Y +} +; CHECK: load_sext_test3 +; CHECK: vpmovsxwq (%r{{[^,]*}}), %ymm{{.*}} +; CHECK: ret +define <4 x i64> @load_sext_test3(<4 x i16> *%ptr) { + %X = load <4 x i16>* %ptr + %Y = sext <4 x i16> %X to <4 x i64> + ret <4 x i64>%Y +} +; CHECK: load_sext_test4 +; CHECK: vpmovsxwd (%r{{[^,]*}}), %ymm{{.*}} +; CHECK: ret +define <8 x i32> @load_sext_test4(<8 x i16> *%ptr) { + %X = load <8 x i16>* %ptr + %Y = sext <8 x i16> %X to <8 x i32> + ret <8 x i32>%Y +} +; CHECK: load_sext_test5 +; CHECK: vpmovsxbd (%r{{[^,]*}}), %ymm{{.*}} +; CHECK: ret +define <8 x i32> @load_sext_test5(<8 x i8> *%ptr) { + %X = load <8 x i8>* %ptr + %Y = sext <8 x i8> %X to <8 x i32> + ret <8 x i32>%Y +} diff --git a/test/CodeGen/X86/avx2-logic.ll b/test/CodeGen/X86/avx2-logic.ll index 13ebaa6f87..a5bb1a8f8e 100644 --- a/test/CodeGen/X86/avx2-logic.ll +++ b/test/CodeGen/X86/avx2-logic.ll @@ -48,9 +48,8 @@ entry: ; CHECK: vpblendvb ; CHECK: vpblendvb %ymm ; CHECK: ret -define <32 x i8> @vpblendvb(<32 x i8> %x, <32 x i8> %y) { - %min_is_x = icmp ult <32 x i8> %x, %y - %min = select <32 x i1> %min_is_x, <32 x i8> %x, <32 x i8> %y +define <32 x i8> @vpblendvb(<32 x i1> %cond, <32 x i8> %x, <32 x i8> %y) { + %min = select <32 x i1> %cond, <32 x i8> %x, <32 x i8> %y ret <32 x i8> %min } diff --git a/test/CodeGen/X86/blend-msb.ll b/test/CodeGen/X86/blend-msb.ll index 34445428ea..e565da74a0 100644 --- a/test/CodeGen/X86/blend-msb.ll +++ b/test/CodeGen/X86/blend-msb.ll @@ -5,7 +5,8 @@ ; shifting the needed bit to the MSB, and not using shl+sra. ;CHECK: vsel_float -;CHECK: pslld +;CHECK: movl $-2147483648 +;CHECK-NEXT: movd ;CHECK-NEXT: blendvps ;CHECK: ret define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) { @@ -14,7 +15,8 @@ define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) { } ;CHECK: vsel_4xi8 -;CHECK: pslld +;CHECK: movl $-2147483648 +;CHECK-NEXT: movd ;CHECK-NEXT: blendvps ;CHECK: ret define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) { @@ -28,7 +30,7 @@ define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) { ; reduce the mask in this case. ;CHECK: vsel_8xi16 ;CHECK: psllw -;CHECK-NOT: psraw +;CHECK: psraw ;CHECK: pblendvb ;CHECK: ret define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) { diff --git a/test/CodeGen/X86/bmi.ll b/test/CodeGen/X86/bmi.ll index 43c47c0fa8..b89e648c52 100644 --- a/test/CodeGen/X86/bmi.ll +++ b/test/CodeGen/X86/bmi.ll @@ -26,6 +26,14 @@ define i32 @t3(i32 %x) nounwind { ; CHECK: tzcntl } +define i32 @tzcnt32_load(i32* %x) nounwind { + %x1 = load i32* %x + %tmp = tail call i32 @llvm.cttz.i32(i32 %x1, i1 false ) + ret i32 %tmp +; CHECK: tzcnt32_load: +; CHECK: tzcntl ({{.*}}) +} + define i64 @t4(i64 %x) nounwind { %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false ) ret i64 %tmp @@ -69,6 +77,15 @@ define i32 @andn32(i32 %x, i32 %y) nounwind readnone { ; CHECK: andnl } +define i32 @andn32_load(i32 %x, i32* %y) nounwind readnone { + %y1 = load i32* %y + %tmp1 = xor i32 %x, -1 + %tmp2 = and i32 %y1, %tmp1 + ret i32 %tmp2 +; CHECK: andn32_load: +; CHECK: andnl ({{.*}}) +} + define i64 @andn64(i64 %x, i64 %y) nounwind readnone { %tmp1 = xor i64 %x, -1 %tmp2 = and i64 %tmp1, %y @@ -84,6 +101,14 @@ define i32 @bextr32(i32 %x, i32 %y) nounwind readnone { ; CHECK: bextrl } +define i32 @bextr32_load(i32* %x, i32 %y) nounwind readnone { + %x1 = load i32* %x + %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x1, i32 %y) + ret i32 %tmp +; CHECK: bextr32_load: +; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}} +} + declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone define i64 @bextr64(i64 %x, i64 %y) nounwind readnone { @@ -102,6 +127,14 @@ define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone { ; CHECK: bzhil } +define i32 @bzhi32_load(i32* %x, i32 %y) nounwind readnone { + %x1 = load i32* %x + %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x1, i32 %y) + ret i32 %tmp +; CHECK: bzhi32_load: +; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}} +} + declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone { @@ -121,6 +154,15 @@ define i32 @blsi32(i32 %x) nounwind readnone { ; CHECK: blsil } +define i32 @blsi32_load(i32* %x) nounwind readnone { + %x1 = load i32* %x + %tmp = sub i32 0, %x1 + %tmp2 = and i32 %x1, %tmp + ret i32 %tmp2 +; CHECK: blsi32_load: +; CHECK: blsil ({{.*}}) +} + define i64 @blsi64(i64 %x) nounwind readnone { %tmp = sub i64 0, %x %tmp2 = and i64 %tmp, %x @@ -137,6 +179,15 @@ define i32 @blsmsk32(i32 %x) nounwind readnone { ; CHECK: blsmskl } +define i32 @blsmsk32_load(i32* %x) nounwind readnone { + %x1 = load i32* %x + %tmp = sub i32 %x1, 1 + %tmp2 = xor i32 %x1, %tmp + ret i32 %tmp2 +; CHECK: blsmsk32_load: +; CHECK: blsmskl ({{.*}}) +} + define i64 @blsmsk64(i64 %x) nounwind readnone { %tmp = sub i64 %x, 1 %tmp2 = xor i64 %tmp, %x @@ -153,6 +204,15 @@ define i32 @blsr32(i32 %x) nounwind readnone { ; CHECK: blsrl } +define i32 @blsr32_load(i32* %x) nounwind readnone { + %x1 = load i32* %x + %tmp = sub i32 %x1, 1 + %tmp2 = and i32 %x1, %tmp + ret i32 %tmp2 +; CHECK: blsr32_load: +; CHECK: blsrl ({{.*}}) +} + define i64 @blsr64(i64 %x) nounwind readnone { %tmp = sub i64 %x, 1 %tmp2 = and i64 %tmp, %x @@ -168,6 +228,14 @@ define i32 @pdep32(i32 %x, i32 %y) nounwind readnone { ; CHECK: pdepl } +define i32 @pdep32_load(i32 %x, i32* %y) nounwind readnone { + %y1 = load i32* %y + %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y1) + ret i32 %tmp +; CHECK: pdep32_load: +; CHECK: pdepl ({{.*}}) +} + declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone define i64 @pdep64(i64 %x, i64 %y) nounwind readnone { @@ -186,6 +254,14 @@ define i32 @pext32(i32 %x, i32 %y) nounwind readnone { ; CHECK: pextl } +define i32 @pext32_load(i32 %x, i32* %y) nounwind readnone { + %y1 = load i32* %y + %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y1) + ret i32 %tmp +; CHECK: pext32_load: +; CHECK: pextl ({{.*}}) +} + declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone define i64 @pext64(i64 %x, i64 %y) nounwind readnone { diff --git a/test/CodeGen/X86/cas.ll b/test/CodeGen/X86/cas.ll new file mode 100644 index 0000000000..c2dd05ef73 --- /dev/null +++ b/test/CodeGen/X86/cas.ll @@ -0,0 +1,73 @@ +; RUN: llc -mtriple=x86_64-pc-linux-gnu %s -o - | FileCheck %s + +; C code this came from +;bool cas(float volatile *p, float *expected, float desired) { +; bool success; +; __asm__ __volatile__("lock; cmpxchg %[desired], %[mem]; " +; "mov %[expected], %[expected_out]; " +; "sete %[success]" +; : [success] "=a" (success), +; [expected_out] "=rm" (*expected) +; : [expected] "a" (*expected), +; [desired] "q" (desired), +; [mem] "m" (*p) +; : "memory", "cc"); +; return success; +;} + +define zeroext i1 @cas(float* %p, float* %expected, float %desired) nounwind { +entry: + %p.addr = alloca float*, align 8 + %expected.addr = alloca float*, align 8 + %desired.addr = alloca float, align 4 + %success = alloca i8, align 1 + store float* %p, float** %p.addr, align 8 + store float* %expected, float** %expected.addr, align 8 + store float %desired, float* %desired.addr, align 4 + %0 = load float** %expected.addr, align 8 + %1 = load float** %expected.addr, align 8 + %2 = load float* %1, align 4 + %3 = load float* %desired.addr, align 4 + %4 = load float** %p.addr, align 8 + %5 = call i8 asm sideeffect "lock; cmpxchg $3, $4; mov $2, $1; sete $0", "={ax},=*rm,{ax},q,*m,~{memory},~{cc},~{dirflag},~{fpsr},~{flags}"(float* %0, float %2, float %3, float* %4) nounwind + store i8 %5, i8* %success, align 1 + %6 = load i8* %success, align 1 + %tobool = trunc i8 %6 to i1 + ret i1 %tobool +} + +; CHECK: @cas +; Make sure we're emitting a move from eax. +; CHECK: #APP +; CHECK-NEXT: lock;{{.*}}mov %eax,{{.*}} +; CHECK-NEXT: #NO_APP + +define zeroext i1 @cas2(i8* %p, i8* %expected, i1 zeroext %desired) nounwind { +entry: + %p.addr = alloca i8*, align 8 + %expected.addr = alloca i8*, align 8 + %desired.addr = alloca i8, align 1 + %success = alloca i8, align 1 + store i8* %p, i8** %p.addr, align 8 + store i8* %expected, i8** %expected.addr, align 8 + %frombool = zext i1 %desired to i8 + store i8 %frombool, i8* %desired.addr, align 1 + %0 = load i8** %expected.addr, align 8 + %1 = load i8** %expected.addr, align 8 + %2 = load i8* %1, align 1 + %tobool = trunc i8 %2 to i1 + %3 = load i8* %desired.addr, align 1 + %tobool1 = trunc i8 %3 to i1 + %4 = load i8** %p.addr, align 8 + %5 = call i8 asm sideeffect "lock; cmpxchg $3, $4; mov $2, $1; sete $0", "={ax},=*rm,{ax},q,*m,~{memory},~{cc},~{dirflag},~{fpsr},~{flags}"(i8* %0, i1 %tobool, i1 %tobool1, i8* %4) nounwind + store i8 %5, i8* %success, align 1 + %6 = load i8* %success, align 1 + %tobool2 = trunc i8 %6 to i1 + ret i1 %tobool2 +} + +; CHECK: @cas2 +; Make sure we're emitting a move from %al here. +; CHECK: #APP +; CHECK-NEXT: lock;{{.*}}mov %al,{{.*}} +; CHECK-NEXT: #NO_APP diff --git a/test/CodeGen/X86/clobber-fi0.ll b/test/CodeGen/X86/clobber-fi0.ll new file mode 100644 index 0000000000..38a42dbf1a --- /dev/null +++ b/test/CodeGen/X86/clobber-fi0.ll @@ -0,0 +1,37 @@ +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.0" + +; In the code below we need to copy the EFLAGS because of scheduling constraints. +; When copying the EFLAGS we need to write to the stack with push/pop. This forces +; us to emit the prolog. + +; CHECK: main +; CHECK: subq{{.*}}rsp +; CHECK: ret +define i32 @main(i32 %arg, i8** %arg1) nounwind { +bb: + %tmp = alloca i32, align 4 ; [#uses=3 type=i32*] + %tmp2 = alloca i32, align 4 ; [#uses=3 type=i32*] + %tmp3 = alloca i32 ; [#uses=1 type=i32*] + store i32 1, i32* %tmp, align 4 + store i32 1, i32* %tmp2, align 4 + br label %bb4 + +bb4: ; preds = %bb4, %bb + %tmp6 = load i32* %tmp2, align 4 ; [#uses=1 type=i32] + %tmp7 = add i32 %tmp6, -1 ; [#uses=2 type=i32] + store i32 %tmp7, i32* %tmp2, align 4 + %tmp8 = icmp eq i32 %tmp7, 0 ; [#uses=1 type=i1] + %tmp9 = load i32* %tmp ; [#uses=1 type=i32] + %tmp10 = add i32 %tmp9, -1 ; [#uses=1 type=i32] + store i32 %tmp10, i32* %tmp3 + br i1 %tmp8, label %bb11, label %bb4 + +bb11: ; preds = %bb4 + %tmp12 = load i32* %tmp, align 4 ; [#uses=1 type=i32] + ret i32 %tmp12 +} + + diff --git a/test/CodeGen/X86/cmp.ll b/test/CodeGen/X86/cmp.ll index eb06327f55..1855fe2fb8 100644 --- a/test/CodeGen/X86/cmp.ll +++ b/test/CodeGen/X86/cmp.ll @@ -151,3 +151,18 @@ entry: %conv = zext i1 %cmp to i32 ret i32 %conv } + +define i32 @test12() uwtable ssp { +; CHECK: test12: +; CHECK: testb + %1 = call zeroext i1 @test12b() + br i1 %1, label %2, label %3 + +; <label>:2 ; preds = %0 + ret i32 1 + +; <label>:3 ; preds = %0 + ret i32 2 +} + +declare zeroext i1 @test12b() diff --git a/test/CodeGen/X86/coalesce-implicitdef.ll b/test/CodeGen/X86/coalesce-implicitdef.ll new file mode 100644 index 0000000000..19cd08cf37 --- /dev/null +++ b/test/CodeGen/X86/coalesce-implicitdef.ll @@ -0,0 +1,130 @@ +; RUN: llc < %s -verify-coalescing +; PR14732 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10" + +@c = common global i32 0, align 4 +@b = common global i32 0, align 4 +@a = common global i32 0, align 4 +@d = common global i32 0, align 4 + +; This function creates an IMPLICIT_DEF with a long live range, even after +; ProcessImplicitDefs. +; +; The coalescer should be able to deal with all kinds of IMPLICIT_DEF live +; ranges, even if they are not common. + +define void @f() nounwind uwtable ssp { +entry: + %i = alloca i32, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc34, %entry + %i.0.load44 = phi i32 [ %inc35, %for.inc34 ], [ undef, %entry ] + %pi.0 = phi i32* [ %pi.4, %for.inc34 ], [ undef, %entry ] + %tobool = icmp eq i32 %i.0.load44, 0 + br i1 %tobool, label %for.end36, label %for.body + +for.body: ; preds = %for.cond + store i32 0, i32* @c, align 4, !tbaa !0 + br label %for.body2 + +for.body2: ; preds = %for.body, %for.inc + %i.0.load45 = phi i32 [ %i.0.load44, %for.body ], [ 0, %for.inc ] + %tobool3 = icmp eq i32 %i.0.load45, 0 + br i1 %tobool3, label %if.then10, label %if.then + +if.then: ; preds = %for.body2 + store i32 0, i32* %i, align 4, !tbaa !0 + br label %for.body6 + +for.body6: ; preds = %if.then, %for.body6 + store i32 0, i32* %i, align 4 + br i1 true, label %for.body6, label %for.inc + +if.then10: ; preds = %for.body2 + store i32 1, i32* @b, align 4, !tbaa !0 + ret void + +for.inc: ; preds = %for.body6 + br i1 undef, label %for.body2, label %if.end30 + +while.condthread-pre-split: ; preds = %label.loopexit, %while.condthread-pre-split.lr.ph.lr.ph, %for.inc27.backedge + %0 = phi i32 [ %inc28, %for.inc27.backedge ], [ %inc285863, %while.condthread-pre-split.lr.ph.lr.ph ], [ %inc2858, %label.loopexit ] + %inc2060 = phi i32 [ %inc20, %for.inc27.backedge ], [ %a.promoted.pre, %while.condthread-pre-split.lr.ph.lr.ph ], [ %inc20, %label.loopexit ] + br label %while.cond + +while.cond: ; preds = %while.condthread-pre-split, %while.cond + %p2.1.in = phi i32* [ %pi.3.ph, %while.cond ], [ %i, %while.condthread-pre-split ] + %p2.1 = bitcast i32* %p2.1.in to i16* + br i1 %tobool19, label %while.end, label %while.cond + +while.end: ; preds = %while.cond + %inc20 = add nsw i32 %inc2060, 1 + %tobool21 = icmp eq i32 %inc2060, 0 + br i1 %tobool21, label %for.inc27.backedge, label %if.then22 + +for.inc27.backedge: ; preds = %while.end, %if.then22 + %inc28 = add nsw i32 %0, 1 + store i32 %inc28, i32* @b, align 4, !tbaa !0 + %tobool17 = icmp eq i32 %inc28, 0 + br i1 %tobool17, label %for.inc27.if.end30.loopexit56_crit_edge, label %while.condthread-pre-split + +if.then22: ; preds = %while.end + %1 = load i16* %p2.1, align 2, !tbaa !3 + %tobool23 = icmp eq i16 %1, 0 + br i1 %tobool23, label %for.inc27.backedge, label %label.loopexit + +label.loopexit: ; preds = %if.then22 + store i32 %inc20, i32* @a, align 4, !tbaa !0 + %inc2858 = add nsw i32 %0, 1 + store i32 %inc2858, i32* @b, align 4, !tbaa !0 + %tobool1759 = icmp eq i32 %inc2858, 0 + br i1 %tobool1759, label %if.end30, label %while.condthread-pre-split + +for.inc27.if.end30.loopexit56_crit_edge: ; preds = %for.inc27.backedge + store i32 %inc20, i32* @a, align 4, !tbaa !0 + br label %if.end30 + +if.end30: ; preds = %for.inc27.if.end30.loopexit56_crit_edge, %label.loopexit, %label.preheader, %for.inc + %i.0.load46 = phi i32 [ 0, %for.inc ], [ %i.0.load4669, %label.preheader ], [ %i.0.load4669, %label.loopexit ], [ %i.0.load4669, %for.inc27.if.end30.loopexit56_crit_edge ] + %pi.4 = phi i32* [ %i, %for.inc ], [ %pi.3.ph, %label.preheader ], [ %pi.3.ph, %label.loopexit ], [ %pi.3.ph, %for.inc27.if.end30.loopexit56_crit_edge ] + %2 = load i32* %pi.4, align 4, !tbaa !0 + %tobool31 = icmp eq i32 %2, 0 + br i1 %tobool31, label %for.inc34, label %label.preheader + +for.inc34: ; preds = %if.end30 + %inc35 = add nsw i32 %i.0.load46, 1 + store i32 %inc35, i32* %i, align 4 + br label %for.cond + +for.end36: ; preds = %for.cond + store i32 1, i32* %i, align 4 + %3 = load i32* @c, align 4, !tbaa !0 + %tobool37 = icmp eq i32 %3, 0 + br i1 %tobool37, label %label.preheader, label %land.rhs + +land.rhs: ; preds = %for.end36 + store i32 0, i32* @a, align 4, !tbaa !0 + br label %label.preheader + +label.preheader: ; preds = %for.end36, %if.end30, %land.rhs + %i.0.load4669 = phi i32 [ 1, %land.rhs ], [ %i.0.load46, %if.end30 ], [ 1, %for.end36 ] + %pi.3.ph = phi i32* [ %pi.0, %land.rhs ], [ %pi.4, %if.end30 ], [ %pi.0, %for.end36 ] + %4 = load i32* @b, align 4, !tbaa !0 + %inc285863 = add nsw i32 %4, 1 + store i32 %inc285863, i32* @b, align 4, !tbaa !0 + %tobool175964 = icmp eq i32 %inc285863, 0 + br i1 %tobool175964, label %if.end30, label %while.condthread-pre-split.lr.ph.lr.ph + +while.condthread-pre-split.lr.ph.lr.ph: ; preds = %label.preheader + %.pr50 = load i32* @d, align 4, !tbaa !0 + %tobool19 = icmp eq i32 %.pr50, 0 + %a.promoted.pre = load i32* @a, align 4, !tbaa !0 + br label %while.condthread-pre-split +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} +!3 = metadata !{metadata !"short", metadata !1} diff --git a/test/CodeGen/X86/coldcc64.ll b/test/CodeGen/X86/coldcc64.ll new file mode 100644 index 0000000000..4db56bbaea --- /dev/null +++ b/test/CodeGen/X86/coldcc64.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s | FileCheck %s + +target triple = "x86_64-linux-gnu" + +define coldcc void @foo() { +; CHECK: pushq %rbp +; CHECK: pushq %r15 +; CHECK: pushq %r14 +; CHECK: pushq %r13 +; CHECK: pushq %r12 +; CHECK: pushq %r11 +; CHECK: pushq %r10 +; CHECK: pushq %r9 +; CHECK: pushq %r8 +; CHECK: pushq %rdi +; CHECK: pushq %rsi +; CHECK: pushq %rdx +; CHECK: pushq %rcx +; CHECK: pushq %rbx +; CHECK: movaps %xmm15 +; CHECK: movaps %xmm0 + call void asm sideeffect "", "~{xmm15},~{xmm0},~{rbp},~{r15},~{r14},~{r13},~{r12},~{r11},~{r10},~{r9},~{r8},~{rdi},~{rsi},~{rdx},~{rcx},~{rbx}"() + ret void +} diff --git a/test/CodeGen/X86/crash.ll b/test/CodeGen/X86/crash.ll index 276d0db9a4..6d2196206e 100644 --- a/test/CodeGen/X86/crash.ll +++ b/test/CodeGen/X86/crash.ll @@ -431,7 +431,7 @@ return: ; preds = %entry ; uitofp expands to an FCMOV instruction which splits the basic block. ; Make sure the live range of %AL isn't split. @.str = private unnamed_addr constant { [1 x i8], [63 x i8] } zeroinitializer, align 32 -define void @pr13188(i64* nocapture %this) uwtable ssp address_safety align 2 { +define void @pr13188(i64* nocapture %this) uwtable ssp sanitize_address align 2 { entry: %x7 = load i64* %this, align 8 %sub = add i64 %x7, -1 diff --git a/test/CodeGen/X86/cvtv2f32.ll b/test/CodeGen/X86/cvtv2f32.ll index 466b096067..d11bb9ee3e 100644 --- a/test/CodeGen/X86/cvtv2f32.ll +++ b/test/CodeGen/X86/cvtv2f32.ll @@ -1,3 +1,7 @@ +; A bug fix in the DAGCombiner made this test fail, so marking as xfail +; until this can be investigated further. +; XFAIL: * + ; RUN: llc < %s -mtriple=i686-linux-pc -mcpu=corei7 | FileCheck %s define <2 x float> @foo(i32 %x, i32 %y, <2 x float> %v) { diff --git a/test/CodeGen/X86/dagcombine_unsafe_math.ll b/test/CodeGen/X86/dagcombine_unsafe_math.ll new file mode 100644 index 0000000000..a3221dea5b --- /dev/null +++ b/test/CodeGen/X86/dagcombine_unsafe_math.ll @@ -0,0 +1,42 @@ +; RUN: llc < %s -enable-unsafe-fp-math -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck %s + + +; rdar://13126763 +; Expression "x + x*x" was mistakenly transformed into "x * 3.0f". + +define float @test1(float %x) { + %t1 = fmul fast float %x, %x + %t2 = fadd fast float %t1, %x + ret float %t2 +; CHECK: test1 +; CHECK: vaddss +} + +; (x + x) + x => x * 3.0 +define float @test2(float %x) { + %t1 = fadd fast float %x, %x + %t2 = fadd fast float %t1, %x + ret float %t2 +; CHECK: .long 1077936128 +; CHECK: test2 +; CHECK: vmulss LCPI1_0(%rip), %xmm0, %xmm0 +} + +; x + (x + x) => x * 3.0 +define float @test3(float %x) { + %t1 = fadd fast float %x, %x + %t2 = fadd fast float %t1, %x + ret float %t2 +; CHECK: .long 1077936128 +; CHECK: test3 +; CHECK: vmulss LCPI2_0(%rip), %xmm0, %xmm0 +} + +; (y + x) + x != x * 3.0 +define float @test4(float %x, float %y) { + %t1 = fadd fast float %x, %y + %t2 = fadd fast float %t1, %x + ret float %t2 +; CHECK: test4 +; CHECK: vaddss +} diff --git a/test/CodeGen/X86/dbg-byval-parameter.ll b/test/CodeGen/X86/dbg-byval-parameter.ll index 5e5577620d..25c946bbb6 100644 --- a/test/CodeGen/X86/dbg-byval-parameter.ll +++ b/test/CodeGen/X86/dbg-byval-parameter.ll @@ -25,21 +25,24 @@ return: ; preds = %entry declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone -!0 = metadata !{i32 524545, metadata !1, metadata !"my_r0", metadata !2, i32 11, metadata !7} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 11, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524329, metadata !"b2.c", metadata !"/tmp/", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"b2.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!llvm.dbg.cu = !{!3} +!18 = metadata !{metadata !1} + +!0 = metadata !{i32 786689, metadata !1, metadata !"my_r0", metadata !2, i32 11, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 11, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, double (%struct.Rect*)* @foo, null, null, null, i32 0} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"b2.c", metadata !"/tmp/", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 1, metadata !"b2.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !18, null} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] !5 = metadata !{metadata !6, metadata !7} -!6 = metadata !{i32 524324, metadata !2, metadata !"double", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 524307, metadata !2, metadata !"Rect", metadata !2, i32 6, i64 256, i64 64, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_structure_type ] +!6 = metadata !{i32 786468, metadata !2, metadata !"double", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786451, metadata !2, metadata !"Rect", metadata !2, i32 6, i64 256, i64 64, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_structure_type ] !8 = metadata !{metadata !9, metadata !14} -!9 = metadata !{i32 524301, metadata !7, metadata !"P1", metadata !2, i32 7, i64 128, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] -!10 = metadata !{i32 524307, metadata !2, metadata !"Pt", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_structure_type ] +!9 = metadata !{i32 786445, metadata !7, metadata !"P1", metadata !2, i32 7, i64 128, i64 64, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] +!10 = metadata !{i32 786451, metadata !2, metadata !"Pt", metadata !2, i32 1, i64 128, i64 64, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_structure_type ] !11 = metadata !{metadata !12, metadata !13} -!12 = metadata !{i32 524301, metadata !10, metadata !"x", metadata !2, i32 2, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!13 = metadata !{i32 524301, metadata !10, metadata !"y", metadata !2, i32 3, i64 64, i64 64, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] -!14 = metadata !{i32 524301, metadata !7, metadata !"P2", metadata !2, i32 8, i64 128, i64 64, i64 128, i32 0, metadata !10} ; [ DW_TAG_member ] +!12 = metadata !{i32 786445, metadata !10, metadata !"x", metadata !2, i32 2, i64 64, i64 64, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] +!13 = metadata !{i32 786445, metadata !10, metadata !"y", metadata !2, i32 3, i64 64, i64 64, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] +!14 = metadata !{i32 786445, metadata !7, metadata !"P2", metadata !2, i32 8, i64 128, i64 64, i64 128, i32 0, metadata !10} ; [ DW_TAG_member ] !15 = metadata !{i32 11, i32 0, metadata !1, null} !16 = metadata !{i32 12, i32 0, metadata !17, null} -!17 = metadata !{i32 524299, metadata !1, i32 11, i32 0} ; [ DW_TAG_lexical_block ] +!17 = metadata !{i32 786443, metadata !1, i32 11, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/dbg-const-int.ll b/test/CodeGen/X86/dbg-const-int.ll index bfc96f17ec..1f9c43ad9a 100644 --- a/test/CodeGen/X86/dbg-const-int.ll +++ b/test/CodeGen/X86/dbg-const-int.ll @@ -13,17 +13,17 @@ entry: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1} -!llvm.dbg.lv.foo = !{!6} +!11 = metadata !{metadata !1} +!12 = metadata !{metadata !6} -!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 132191)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 true, i32 ()* @foo, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 132191)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !11, null, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 true, i32 ()* @foo, null, null, metadata !12, i32 0} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 590080, metadata !7, metadata !"i", metadata !2, i32 2, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!7 = metadata !{i32 589835, metadata !1, i32 1, i32 11, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!5 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786688, metadata !7, metadata !"i", metadata !2, i32 2, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!7 = metadata !{i32 786443, metadata !1, i32 1, i32 11, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] !8 = metadata !{i32 42} !9 = metadata !{i32 2, i32 12, metadata !7, null} !10 = metadata !{i32 3, i32 2, metadata !7, null} diff --git a/test/CodeGen/X86/dbg-const.ll b/test/CodeGen/X86/dbg-const.ll index 5a51eb88b8..cd60e533cc 100644 --- a/test/CodeGen/X86/dbg-const.ll +++ b/test/CodeGen/X86/dbg-const.ll @@ -16,17 +16,18 @@ entry: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone declare i32 @bar() nounwind readnone -!llvm.dbg.sp = !{!0} -!llvm.dbg.lv.foobar = !{!6} +!llvm.dbg.cu = !{!2} +!13 = metadata !{metadata !0} +!14 = metadata !{metadata !6} -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foobar", metadata !"foobar", metadata !"foobar", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 ()* @foobar} -!1 = metadata !{i32 524329, metadata !"mu.c", metadata !"/private/tmp", metadata !2} -!2 = metadata !{i32 524305, i32 0, i32 12, metadata !"mu.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 114183)", i1 true, i1 true, metadata !"", i32 0} -!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foobar", metadata !"foobar", metadata !"foobar", metadata !1, i32 12, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 ()* @foobar, null, null, metadata !14, i32 0} +!1 = metadata !{i32 786473, metadata !"mu.c", metadata !"/private/tmp", metadata !2} +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"mu.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 114183)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !13, null} +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} !4 = metadata !{metadata !5} -!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} -!6 = metadata !{i32 524544, metadata !7, metadata !"j", metadata !1, i32 15, metadata !5} -!7 = metadata !{i32 524299, metadata !0, i32 12, i32 52, metadata !1, i32 0} +!5 = metadata !{i32 786468, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} +!6 = metadata !{i32 786688, metadata !7, metadata !"j", metadata !1, i32 15, metadata !5, i32 0, null} +!7 = metadata !{i32 786443, metadata !0, i32 12, i32 52, metadata !1, i32 0} !8 = metadata !{i32 42} !9 = metadata !{i32 15, i32 12, metadata !7, null} !10 = metadata !{i32 23, i32 3, metadata !7, null} diff --git a/test/CodeGen/X86/dbg-declare-arg.ll b/test/CodeGen/X86/dbg-declare-arg.ll index 367c1ef36c..957f37bd87 100644 --- a/test/CodeGen/X86/dbg-declare-arg.ll +++ b/test/CodeGen/X86/dbg-declare-arg.ll @@ -69,55 +69,56 @@ entry: ret void, !dbg !48 } -!llvm.dbg.sp = !{!0, !10, !14, !19, !22, !25} +!llvm.dbg.cu = !{!2} +!50 = metadata !{metadata !0, metadata !10, metadata !14, metadata !19, metadata !22, metadata !25} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"~A", metadata !"~A", metadata !"", metadata !3, i32 2, metadata !11, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"~A", metadata !"~A", metadata !"", metadata !3, i32 2, metadata !11, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ] !1 = metadata !{i32 589826, metadata !2, metadata !"A", metadata !3, i32 2, i64 128, i64 32, i32 0, i32 0, null, metadata !4, i32 0, null, null} ; [ DW_TAG_class_type ] -!2 = metadata !{i32 589841, i32 0, i32 4, metadata !"a.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 130127)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589865, metadata !"a.cc", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 4, metadata !"a.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 130127)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !50, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786473, metadata !"a.cc", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] !4 = metadata !{metadata !5, metadata !7, metadata !8, metadata !9, metadata !0, metadata !10, metadata !14} -!5 = metadata !{i32 589837, metadata !3, metadata !"x", metadata !3, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!6 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 589837, metadata !3, metadata !"y", metadata !3, i32 2, i64 32, i64 32, i64 32, i32 0, metadata !6} ; [ DW_TAG_member ] -!8 = metadata !{i32 589837, metadata !3, metadata !"z", metadata !3, i32 2, i64 32, i64 32, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] -!9 = metadata !{i32 589837, metadata !3, metadata !"o", metadata !3, i32 2, i64 32, i64 32, i64 96, i32 0, metadata !6} ; [ DW_TAG_member ] -!10 = metadata !{i32 589870, i32 0, metadata !1, metadata !"A", metadata !"A", metadata !"", metadata !3, i32 2, metadata !11, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ] -!11 = metadata !{i32 589845, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786445, metadata !3, metadata !"x", metadata !3, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] +!6 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786445, metadata !3, metadata !"y", metadata !3, i32 2, i64 32, i64 32, i64 32, i32 0, metadata !6} ; [ DW_TAG_member ] +!8 = metadata !{i32 786445, metadata !3, metadata !"z", metadata !3, i32 2, i64 32, i64 32, i64 64, i32 0, metadata !6} ; [ DW_TAG_member ] +!9 = metadata !{i32 786445, metadata !3, metadata !"o", metadata !3, i32 2, i64 32, i64 32, i64 96, i32 0, metadata !6} ; [ DW_TAG_member ] +!10 = metadata !{i32 786478, i32 0, metadata !1, metadata !"A", metadata !"A", metadata !"", metadata !3, i32 2, metadata !11, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !12 = metadata !{null, metadata !13} -!13 = metadata !{i32 589839, metadata !2, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] -!14 = metadata !{i32 589870, i32 0, metadata !1, metadata !"A", metadata !"A", metadata !"", metadata !3, i32 2, metadata !15, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ] -!15 = metadata !{i32 589845, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !16, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!13 = metadata !{i32 786447, metadata !2, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !1} ; [ DW_TAG_pointer_type ] +!14 = metadata !{i32 786478, i32 0, metadata !1, metadata !"A", metadata !"A", metadata !"", metadata !3, i32 2, metadata !15, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ] +!15 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !16, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !16 = metadata !{null, metadata !13, metadata !17} !17 = metadata !{i32 589840, metadata !2, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !18} ; [ DW_TAG_reference_type ] -!18 = metadata !{i32 589862, metadata !2, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !1} ; [ DW_TAG_const_type ] -!19 = metadata !{i32 589870, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"_Z3fooi", metadata !3, i32 4, metadata !20, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*, i32)* @_Z3fooi, null, null} ; [ DW_TAG_subprogram ] -!20 = metadata !{i32 589845, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !21, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!18 = metadata !{i32 786470, metadata !2, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !1} ; [ DW_TAG_const_type ] +!19 = metadata !{i32 786478, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"_Z3fooi", metadata !3, i32 4, metadata !20, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*, i32)* @_Z3fooi, null, null} ; [ DW_TAG_subprogram ] +!20 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !21, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !21 = metadata !{metadata !1} -!22 = metadata !{i32 589870, i32 0, metadata !3, metadata !"~A", metadata !"~A", metadata !"_ZN1AD1Ev", metadata !3, i32 2, metadata !23, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*)* @_ZN1AD1Ev, null, null} ; [ DW_TAG_subprogram ] -!23 = metadata !{i32 589845, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !24, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!22 = metadata !{i32 786478, i32 0, metadata !3, metadata !"~A", metadata !"~A", metadata !"_ZN1AD1Ev", metadata !3, i32 2, metadata !23, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*)* @_ZN1AD1Ev, null, null} ; [ DW_TAG_subprogram ] +!23 = metadata !{i32 786453, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !24, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !24 = metadata !{null} -!25 = metadata !{i32 589870, i32 0, metadata !3, metadata !"~A", metadata !"~A", metadata !"_ZN1AD2Ev", metadata !3, i32 2, metadata !23, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*)* @_ZN1AD2Ev, null, null} ; [ DW_TAG_subprogram ] -!26 = metadata !{i32 590081, metadata !19, metadata !"i", metadata !3, i32 16777220, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!25 = metadata !{i32 786478, i32 0, metadata !3, metadata !"~A", metadata !"~A", metadata !"_ZN1AD2Ev", metadata !3, i32 2, metadata !23, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (%class.A*)* @_ZN1AD2Ev, null, null} ; [ DW_TAG_subprogram ] +!26 = metadata !{i32 786689, metadata !19, metadata !"i", metadata !3, i32 16777220, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ] !27 = metadata !{i32 4, i32 11, metadata !19, null} -!28 = metadata !{i32 590080, metadata !29, metadata !"j", metadata !3, i32 5, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] -!29 = metadata !{i32 589835, metadata !19, i32 4, i32 14, metadata !3, i32 0} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 786688, metadata !29, metadata !"j", metadata !3, i32 5, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 786443, metadata !19, i32 4, i32 14, metadata !3, i32 0} ; [ DW_TAG_lexical_block ] !30 = metadata !{i32 5, i32 7, metadata !29, null} !31 = metadata !{i32 5, i32 12, metadata !29, null} !32 = metadata !{i32 6, i32 3, metadata !29, null} !33 = metadata !{i32 7, i32 5, metadata !34, null} -!34 = metadata !{i32 589835, metadata !29, i32 6, i32 16, metadata !3, i32 1} ; [ DW_TAG_lexical_block ] +!34 = metadata !{i32 786443, metadata !29, i32 6, i32 16, metadata !3, i32 1} ; [ DW_TAG_lexical_block ] !35 = metadata !{i32 8, i32 3, metadata !34, null} !36 = metadata !{i32 9, i32 9, metadata !29, null} -!37 = metadata !{i32 590080, metadata !29, metadata !"my_a", metadata !3, i32 9, metadata !38, i32 0} ; [ DW_TAG_auto_variable ] +!37 = metadata !{i32 786688, metadata !29, metadata !"my_a", metadata !3, i32 9, metadata !38, i32 0, null} ; [ DW_TAG_auto_variable ] !38 = metadata !{i32 589840, metadata !2, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !1} ; [ DW_TAG_reference_type ] !39 = metadata !{i32 9, i32 5, metadata !29, null} !40 = metadata !{i32 10, i32 3, metadata !29, null} !41 = metadata !{i32 11, i32 3, metadata !29, null} !42 = metadata !{i32 12, i32 1, metadata !29, null} -!43 = metadata !{i32 590081, metadata !22, metadata !"this", metadata !3, i32 16777218, metadata !13, i32 64} ; [ DW_TAG_arg_variable ] +!43 = metadata !{i32 786689, metadata !22, metadata !"this", metadata !3, i32 16777218, metadata !13, i32 64, null} ; [ DW_TAG_arg_variable ] !44 = metadata !{i32 2, i32 47, metadata !22, null} !45 = metadata !{i32 2, i32 61, metadata !22, null} -!46 = metadata !{i32 590081, metadata !25, metadata !"this", metadata !3, i32 16777218, metadata !13, i32 64} ; [ DW_TAG_arg_variable ] +!46 = metadata !{i32 786689, metadata !25, metadata !"this", metadata !3, i32 16777218, metadata !13, i32 64, null} ; [ DW_TAG_arg_variable ] !47 = metadata !{i32 2, i32 47, metadata !25, null} !48 = metadata !{i32 2, i32 54, metadata !49, null} -!49 = metadata !{i32 589835, metadata !25, i32 2, i32 52, metadata !3, i32 2} ; [ DW_TAG_lexical_block ] +!49 = metadata !{i32 786443, metadata !25, i32 2, i32 52, metadata !3, i32 2} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/dbg-declare.ll b/test/CodeGen/X86/dbg-declare.ll index b73e310cc5..9d13de16da 100644 --- a/test/CodeGen/X86/dbg-declare.ll +++ b/test/CodeGen/X86/dbg-declare.ll @@ -30,10 +30,8 @@ declare void @llvm.stackrestore(i8*) nounwind !llvm.dbg.cu = !{!0} !0 = metadata !{i32 786449, i32 0, i32 12, metadata !"20020104-2.c", metadata !"/Volumes/Sandbox/llvm", metadata !"clang version 3.1 (trunk 153698)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] -!1 = metadata !{metadata !2} -!2 = metadata !{i32 0} -!3 = metadata !{metadata !4} -!4 = metadata !{metadata !5} +!1 = metadata !{i32 0} +!3 = metadata !{metadata !5} !5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"foo", metadata !"foo", metadata !"", metadata !6, i32 6, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32*)* @foo, null, null, metadata !12} ; [ DW_TAG_subprogram ] !6 = metadata !{i32 786473, metadata !"20020104-2.c", metadata !"/Volumes/Sandbox/llvm", null} ; [ DW_TAG_file_type ] !7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] diff --git a/test/CodeGen/X86/dbg-file-name.ll b/test/CodeGen/X86/dbg-file-name.ll index adf9854610..0a526100e6 100644 --- a/test/CodeGen/X86/dbg-file-name.ll +++ b/test/CodeGen/X86/dbg-file-name.ll @@ -9,11 +9,12 @@ define i32 @main() nounwind { ret i32 0 } -!llvm.dbg.sp = !{ !6} +!llvm.dbg.cu = !{!2} +!9 = metadata !{metadata !6} -!1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!5 = metadata !{i32 589860, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_subroutine_type ] +!1 = metadata !{i32 786473, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"simple.c", metadata !"/Users/manav/one/two", metadata !"LLVM build 00", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !9, null} ; [ DW_TAG_compile_unit ] +!5 = metadata !{i32 786468, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 9, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, null, i32 0} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_subroutine_type ] !8 = metadata !{metadata !5} diff --git a/test/CodeGen/X86/dbg-i128-const.ll b/test/CodeGen/X86/dbg-i128-const.ll index bd96d9195d..725b5b73d5 100644 --- a/test/CodeGen/X86/dbg-i128-const.ll +++ b/test/CodeGen/X86/dbg-i128-const.ll @@ -12,15 +12,18 @@ entry: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone +!llvm.dbg.cu = !{!5} +!12 = metadata !{metadata !3} + !0 = metadata !{i128 42 } -!1 = metadata !{i32 524544, metadata !2, metadata !"MAX", metadata !4, i32 29, metadata !8} ; [ DW_TAG_auto_variable ] -!2 = metadata !{i32 524299, metadata !3, i32 26, i32 0} ; [ DW_TAG_lexical_block ] -!3 = metadata !{i32 524334, i32 0, metadata !4, metadata !"__foo", metadata !"__foo", metadata !"__foo", metadata !4, i32 26, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] -!4 = metadata !{i32 524329, metadata !"foo.c", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ] -!5 = metadata !{i32 524305, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!6 = metadata !{i32 524309, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] +!1 = metadata !{i32 786688, metadata !2, metadata !"MAX", metadata !4, i32 29, metadata !8, i32 0, null} ; [ DW_TAG_auto_variable ] +!2 = metadata !{i32 786443, metadata !3, i32 26, i32 0, metadata !4, i32 0} ; [ DW_TAG_lexical_block ] +!3 = metadata !{i32 786478, i32 0, metadata !4, metadata !"__foo", metadata !"__foo", metadata !"__foo", metadata !4, i32 26, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false, i128 (i128, i128)* @__foo, null, null, null, i32 26} ; [ DW_TAG_subprogram ] +!4 = metadata !{i32 786473, metadata !"foo.c", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ] +!5 = metadata !{i32 786449, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !12, null} ; [ DW_TAG_compile_unit ] +!6 = metadata !{i32 786453, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] !7 = metadata !{metadata !8, metadata !8, metadata !8} -!8 = metadata !{i32 524310, metadata !4, metadata !"ti_int", metadata !9, i32 78, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ] -!9 = metadata !{i32 524329, metadata !"myint.h", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ] -!10 = metadata !{i32 524324, metadata !4, metadata !"", metadata !4, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786454, metadata !4, metadata !"ti_int", metadata !9, i32 78, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ] +!9 = metadata !{i32 786473, metadata !"myint.h", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ] +!10 = metadata !{i32 786468, metadata !4, metadata !"", metadata !4, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] !11 = metadata !{i32 29, i32 0, metadata !2, null} diff --git a/test/CodeGen/X86/dbg-large-unsigned-const.ll b/test/CodeGen/X86/dbg-large-unsigned-const.ll index fc295c6794..9a767621d9 100644 --- a/test/CodeGen/X86/dbg-large-unsigned-const.ll +++ b/test/CodeGen/X86/dbg-large-unsigned-const.ll @@ -26,36 +26,36 @@ entry: declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1, !6} -!llvm.dbg.lv._Z3iseRKxS0_ = !{!7, !11} -!llvm.dbg.lv._Z2fnx = !{!12} +!29 = metadata !{metadata !1, metadata !6} +!30 = metadata !{metadata !7, metadata !11} +!31 = metadata !{metadata !12} -!0 = metadata !{i32 655377, i32 0, i32 4, metadata !"lli.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 135593)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 655406, i32 0, metadata !2, metadata !"ise", metadata !"ise", metadata !"_Z3iseRKxS0_", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i1 (i64*, i64*)* @_Z3iseRKxS0_, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 655401, metadata !"lli.cc", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 655381, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"lli.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 135593)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !29, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"ise", metadata !"ise", metadata !"_Z3iseRKxS0_", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i1 (i64*, i64*)* @_Z3iseRKxS0_, null, null, metadata !30, i32 2} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"lli.cc", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 655396, metadata !0, metadata !"bool", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 655406, i32 0, metadata !2, metadata !"fn", metadata !"fn", metadata !"_Z2fnx", metadata !2, i32 6, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i1 (i64)* @_Z2fnx, null, null} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 655617, metadata !1, metadata !"LHS", metadata !2, i32 16777218, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] -!8 = metadata !{i32 655376, metadata !0, null, null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !9} ; [ DW_TAG_reference_type ] -!9 = metadata !{i32 655398, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_const_type ] -!10 = metadata !{i32 655396, metadata !0, metadata !"long long int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!11 = metadata !{i32 655617, metadata !1, metadata !"RHS", metadata !2, i32 33554434, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] -!12 = metadata !{i32 655617, metadata !6, metadata !"a", metadata !2, i32 16777222, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!5 = metadata !{i32 786468, metadata !0, metadata !"bool", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !2, metadata !"fn", metadata !"fn", metadata !"_Z2fnx", metadata !2, i32 6, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i1 (i64)* @_Z2fnx, null, null, metadata !31, i32 6} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786689, metadata !1, metadata !"LHS", metadata !2, i32 16777218, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!8 = metadata !{i32 786448, metadata !0, null, null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !9} ; [ DW_TAG_reference_type ] +!9 = metadata !{i32 786470, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_const_type ] +!10 = metadata !{i32 786468, metadata !0, metadata !"long long int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!11 = metadata !{i32 786689, metadata !1, metadata !"RHS", metadata !2, i32 33554434, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 786689, metadata !6, metadata !"a", metadata !2, i32 16777222, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] !13 = metadata !{i32 2, i32 27, metadata !1, null} !14 = metadata !{i32 2, i32 49, metadata !1, null} !15 = metadata !{i32 3, i32 3, metadata !16, null} -!16 = metadata !{i32 655371, metadata !1, i32 2, i32 54, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 786443, metadata !1, i32 2, i32 54, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] !17 = metadata !{metadata !"long long", metadata !18} !18 = metadata !{metadata !"omnipotent char", metadata !19} !19 = metadata !{metadata !"Simple C/C++ TBAA", null} !20 = metadata !{i32 6, i32 19, metadata !6, null} -!21 = metadata !{i32 655617, metadata !1, metadata !"LHS", metadata !2, i32 16777218, metadata !8, i32 0, metadata !22} ; [ DW_TAG_arg_variable ] +!21 = metadata !{i32 786689, metadata !1, metadata !"LHS", metadata !2, i32 16777218, metadata !8, i32 0, metadata !22} ; [ DW_TAG_arg_variable ] !22 = metadata !{i32 7, i32 10, metadata !23, null} -!23 = metadata !{i32 655371, metadata !6, i32 6, i32 22, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!23 = metadata !{i32 786443, metadata !6, i32 6, i32 22, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] !24 = metadata !{i32 2, i32 27, metadata !1, metadata !22} !25 = metadata !{i64 9223372036854775807} -!26 = metadata !{i32 655617, metadata !1, metadata !"RHS", metadata !2, i32 33554434, metadata !8, i32 0, metadata !22} ; [ DW_TAG_arg_variable ] +!26 = metadata !{i32 786689, metadata !1, metadata !"RHS", metadata !2, i32 33554434, metadata !8, i32 0, metadata !22} ; [ DW_TAG_arg_variable ] !27 = metadata !{i32 2, i32 49, metadata !1, metadata !22} !28 = metadata !{i32 3, i32 3, metadata !16, metadata !22} diff --git a/test/CodeGen/X86/dbg-merge-loc-entry.ll b/test/CodeGen/X86/dbg-merge-loc-entry.ll index d1e349f79d..4e5078a31b 100644 --- a/test/CodeGen/X86/dbg-merge-loc-entry.ll +++ b/test/CodeGen/X86/dbg-merge-loc-entry.ll @@ -43,33 +43,34 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone declare %0 @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone -!llvm.dbg.sp = !{!0, !9} +!llvm.dbg.cu = !{!2} +!28 = metadata !{metadata !0, metadata !9} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"__udivmodti4", metadata !"__udivmodti4", metadata !"", metadata !1, i32 879, metadata !3, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 true, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"foobar.c", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"foobar.c", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"__udivmodti4", metadata !"__udivmodti4", metadata !"", metadata !1, i32 879, metadata !3, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 true, null, null, null, null, i32 879} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"foobar.c", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"foobar.c", metadata !"/tmp", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !28, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5, metadata !5, metadata !5, metadata !8} -!5 = metadata !{i32 589846, metadata !6, metadata !"UTItype", metadata !6, i32 166, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_typedef ] -!6 = metadata !{i32 589865, metadata !"foobar.h", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] -!7 = metadata !{i32 589860, metadata !1, metadata !"", metadata !1, i32 0, i64 128, i64 128, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 589839, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ] -!9 = metadata !{i32 589870, i32 0, metadata !1, metadata !"__divti3", metadata !"__divti3", metadata !"__divti3", metadata !1, i32 1094, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i128 (i128, i128)* @__divti3} ; [ DW_TAG_subprogram ] -!10 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786454, metadata !6, metadata !"UTItype", metadata !6, i32 166, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_typedef ] +!6 = metadata !{i32 786473, metadata !"foobar.h", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 786468, metadata !1, metadata !"", metadata !1, i32 0, i64 128, i64 128, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786447, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ] +!9 = metadata !{i32 786478, i32 0, metadata !1, metadata !"__divti3", metadata !"__divti3", metadata !"__divti3", metadata !1, i32 1094, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i128 (i128, i128)* @__divti3, null, null, null, i32 1094} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] !11 = metadata !{metadata !12, metadata !12, metadata !12} -!12 = metadata !{i32 589846, metadata !6, metadata !"TItype", metadata !6, i32 160, i64 0, i64 0, i64 0, i32 0, metadata !13} ; [ DW_TAG_typedef ] -!13 = metadata !{i32 589860, metadata !1, metadata !"", metadata !1, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!14 = metadata !{i32 590081, metadata !9, metadata !"u", metadata !1, i32 1093, metadata !12, i32 0} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 786454, metadata !6, metadata !"TItype", metadata !6, i32 160, i64 0, i64 0, i64 0, i32 0, metadata !13} ; [ DW_TAG_typedef ] +!13 = metadata !{i32 786468, metadata !1, metadata !"", metadata !1, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 786689, metadata !9, metadata !"u", metadata !1, i32 1093, metadata !12, i32 0, null} ; [ DW_TAG_arg_variable ] !15 = metadata !{i32 1093, i32 0, metadata !9, null} !16 = metadata !{i64 0} -!17 = metadata !{i32 590080, metadata !18, metadata !"c", metadata !1, i32 1095, metadata !19, i32 0} ; [ DW_TAG_auto_variable ] -!18 = metadata !{i32 589835, metadata !9, i32 1094, i32 0, metadata !1, i32 13} ; [ DW_TAG_lexical_block ] -!19 = metadata !{i32 589846, metadata !6, metadata !"word_type", metadata !6, i32 424, i64 0, i64 0, i64 0, i32 0, metadata !20} ; [ DW_TAG_typedef ] -!20 = metadata !{i32 589860, metadata !1, metadata !"long int", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!17 = metadata !{i32 786688, metadata !18, metadata !"c", metadata !1, i32 1095, metadata !19, i32 0, null} ; [ DW_TAG_auto_variable ] +!18 = metadata !{i32 786443, metadata !9, i32 1094, i32 0, metadata !1, i32 13} ; [ DW_TAG_lexical_block ] +!19 = metadata !{i32 786454, metadata !6, metadata !"word_type", metadata !6, i32 424, i64 0, i64 0, i64 0, i32 0, metadata !20} ; [ DW_TAG_typedef ] +!20 = metadata !{i32 786468, metadata !1, metadata !"long int", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] !21 = metadata !{i32 1095, i32 0, metadata !18, null} !22 = metadata !{i32 1103, i32 0, metadata !18, null} !23 = metadata !{i32 1104, i32 0, metadata !18, null} !24 = metadata !{i32 1003, i32 0, metadata !25, metadata !26} -!25 = metadata !{i32 589835, metadata !0, i32 879, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!25 = metadata !{i32 786443, metadata !0, i32 879, i32 0, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !26 = metadata !{i32 1107, i32 0, metadata !18, null} !27 = metadata !{i32 1111, i32 0, metadata !18, null} diff --git a/test/CodeGen/X86/dbg-prolog-end.ll b/test/CodeGen/X86/dbg-prolog-end.ll index 81303bb3d2..868017cd21 100644 --- a/test/CodeGen/X86/dbg-prolog-end.ll +++ b/test/CodeGen/X86/dbg-prolog-end.ll @@ -33,23 +33,23 @@ entry: } !llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1, !6} +!18 = metadata !{metadata !1, metadata !6} -!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 131100)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 (i32)* @foo, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 589865, metadata !"/tmp/a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"/tmp/a.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 131100)", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !18, null} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 (i32)* @foo, null, null, null, i32 1} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"/tmp/a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"", metadata !2, i32 7, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @main, null, null} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 590081, metadata !1, metadata !"i", metadata !2, i32 16777217, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!5 = metadata !{i32 786468, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !2, metadata !"main", metadata !"main", metadata !"", metadata !2, i32 7, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @main, null, null, null, i32 7} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786689, metadata !1, metadata !"i", metadata !2, i32 16777217, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] !8 = metadata !{i32 1, i32 13, metadata !1, null} -!9 = metadata !{i32 590080, metadata !10, metadata !"j", metadata !2, i32 2, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!10 = metadata !{i32 589835, metadata !1, i32 1, i32 16, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!9 = metadata !{i32 786688, metadata !10, metadata !"j", metadata !2, i32 2, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!10 = metadata !{i32 786443, metadata !1, i32 1, i32 16, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] !11 = metadata !{i32 2, i32 6, metadata !10, null} !12 = metadata !{i32 2, i32 11, metadata !10, null} !13 = metadata !{i32 3, i32 2, metadata !10, null} !14 = metadata !{i32 4, i32 2, metadata !10, null} !15 = metadata !{i32 5, i32 2, metadata !10, null} !16 = metadata !{i32 8, i32 2, metadata !17, null} -!17 = metadata !{i32 589835, metadata !6, i32 7, i32 12, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!17 = metadata !{i32 786443, metadata !6, i32 7, i32 12, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] diff --git a/test/CodeGen/X86/dbg-subrange.ll b/test/CodeGen/X86/dbg-subrange.ll index 0efb50e9a9..2f590ee8cc 100644 --- a/test/CodeGen/X86/dbg-subrange.ll +++ b/test/CodeGen/X86/dbg-subrange.ll @@ -14,24 +14,21 @@ entry: !llvm.dbg.cu = !{!0} -!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"small.c", metadata !"/private/tmp", metadata !"clang version 3.1 (trunk 144833)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !11} ; [ DW_TAG_compile_unit ] -!1 = metadata !{metadata !2} -!2 = metadata !{i32 0} -!3 = metadata !{metadata !4} -!4 = metadata !{metadata !5} +!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"small.c", metadata !"/private/tmp", metadata !"clang version 3.1 (trunk 144833)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !11} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 0} +!3 = metadata !{metadata !5} !5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"bar", metadata !"bar", metadata !"", metadata !6, i32 4, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void ()* @bar, null, null, metadata !9} ; [ DW_TAG_subprogram ] !6 = metadata !{i32 720937, metadata !"small.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] !7 = metadata !{i32 720917, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !8 = metadata !{null} !9 = metadata !{metadata !10} !10 = metadata !{i32 720932} ; [ DW_TAG_base_type ] -!11 = metadata !{metadata !12} -!12 = metadata !{metadata !13} -!13 = metadata !{i32 720948, i32 0, null, metadata !"s", metadata !"s", metadata !"", metadata !6, i32 2, metadata !14, i32 0, i32 1, [4294967296 x i8]* @s} ; [ DW_TAG_variable ] +!11 = metadata !{metadata !13} +!13 = metadata !{i32 720948, i32 0, null, metadata !"s", metadata !"s", metadata !"", metadata !6, i32 2, metadata !14, i32 0, i32 1, [4294967296 x i8]* @s, null} ; [ DW_TAG_variable ] !14 = metadata !{i32 720897, null, metadata !"", null, i32 0, i64 34359738368, i64 8, i32 0, i32 0, metadata !15, metadata !16, i32 0, i32 0} ; [ DW_TAG_array_type ] !15 = metadata !{i32 720932, null, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] !16 = metadata !{metadata !17} !17 = metadata !{i32 720929, i64 0, i64 4294967296} ; [ DW_TAG_subrange_type ] !18 = metadata !{i32 5, i32 3, metadata !19, null} -!19 = metadata !{i32 720907, metadata !5, i32 4, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] +!19 = metadata !{i32 786443, metadata !5, i32 4, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] !20 = metadata !{i32 6, i32 1, metadata !19, null} diff --git a/test/CodeGen/X86/dbg-value-dag-combine.ll b/test/CodeGen/X86/dbg-value-dag-combine.ll index b115bf475c..0066cd0498 100644 --- a/test/CodeGen/X86/dbg-value-dag-combine.ll +++ b/test/CodeGen/X86/dbg-value-dag-combine.ll @@ -23,24 +23,25 @@ entry: store i32 %tmp3, i32 addrspace(1)* %arrayidx, align 4, !dbg !16 ret void, !dbg !17 } -!llvm.dbg.sp = !{!0} +!llvm.dbg.cu = !{!2} +!18 = metadata !{metadata !0} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"__OpenCL_test_kernel", metadata !"__OpenCL_test_kernel", metadata !"__OpenCL_test_kernel", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"OCL6368.tmp.cl", metadata !"E:\5CUsers\5Cmvillmow.AMD\5CAppData\5CLocal\5CTemp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"OCL6368.tmp.cl", metadata !"E:\5CUsers\5Cmvillmow.AMD\5CAppData\5CLocal\5CTemp", metadata !"clc", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!1 = metadata !{i32 786473, metadata !"OCL6368.tmp.cl", metadata !"E:\5CUsers\5Cmvillmow.AMD\5CAppData\5CLocal\5CTemp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"OCL6368.tmp.cl", metadata !"E:\5CUsers\5Cmvillmow.AMD\5CAppData\5CLocal\5CTemp", metadata !"clc", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !18, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{null, metadata !5} -!5 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_pointer_type ] -!6 = metadata !{i32 589860, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 590081, metadata !0, metadata !"ip", metadata !1, i32 1, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!5 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_pointer_type ] +!6 = metadata !{i32 786468, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786689, metadata !0, metadata !"ip", metadata !1, i32 1, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] !8 = metadata !{i32 1, i32 42, metadata !0, null} -!9 = metadata !{i32 590080, metadata !10, metadata !"gid", metadata !1, i32 3, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] -!10 = metadata !{i32 589835, metadata !0, i32 2, i32 1, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!9 = metadata !{i32 786688, metadata !10, metadata !"gid", metadata !1, i32 3, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] +!10 = metadata !{i32 786443, metadata !0, i32 2, i32 1, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !11 = metadata !{i32 3, i32 41, metadata !10, null} !12 = metadata !{i32 0} -!13 = metadata !{i32 590080, metadata !10, metadata !"idx", metadata !1, i32 4, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] +!13 = metadata !{i32 786688, metadata !10, metadata !"idx", metadata !1, i32 4, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] !14 = metadata !{i32 4, i32 20, metadata !10, null} !15 = metadata !{i32 5, i32 15, metadata !10, null} !16 = metadata !{i32 6, i32 18, metadata !10, null} diff --git a/test/CodeGen/X86/dbg-value-inlined-parameter.ll b/test/CodeGen/X86/dbg-value-inlined-parameter.ll deleted file mode 100644 index d248a41303..0000000000 --- a/test/CodeGen/X86/dbg-value-inlined-parameter.ll +++ /dev/null @@ -1,87 +0,0 @@ -; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s -; RUN: llc -mtriple=x86_64-apple-darwin -regalloc=basic < %s | FileCheck %s - -;CHECK: DW_TAG_inlined_subroutine -;CHECK-NEXT: DW_AT_abstract_origin -;CHECK-NEXT: DW_AT_low_pc -;CHECK-NEXT: DW_AT_high_pc -;CHECK-NEXT: DW_AT_call_file -;CHECK-NEXT: DW_AT_call_line -;CHECK-NEXT: DW_TAG_formal_parameter -;CHECK-NEXT: Lstring11-Lsection_str ## DW_AT_name - -%struct.S1 = type { float*, i32 } - -@p = common global %struct.S1 zeroinitializer, align 8 - -define i32 @foo(%struct.S1* nocapture %sp, i32 %nums) nounwind optsize ssp { -entry: - tail call void @llvm.dbg.value(metadata !{%struct.S1* %sp}, i64 0, metadata !9), !dbg !20 - tail call void @llvm.dbg.value(metadata !{i32 %nums}, i64 0, metadata !18), !dbg !21 - %tmp2 = getelementptr inbounds %struct.S1* %sp, i64 0, i32 1, !dbg !22 - store i32 %nums, i32* %tmp2, align 4, !dbg !22, !tbaa !24 - %call = tail call float* @bar(i32 %nums) nounwind optsize, !dbg !27 - %tmp5 = getelementptr inbounds %struct.S1* %sp, i64 0, i32 0, !dbg !27 - store float* %call, float** %tmp5, align 8, !dbg !27, !tbaa !28 - %cmp = icmp ne float* %call, null, !dbg !29 - %cond = zext i1 %cmp to i32, !dbg !29 - ret i32 %cond, !dbg !29 -} - -declare float* @bar(i32) optsize - -define void @foobar() nounwind optsize ssp { -entry: - tail call void @llvm.dbg.value(metadata !30, i64 0, metadata !9) nounwind, !dbg !31 - tail call void @llvm.dbg.value(metadata !34, i64 0, metadata !18) nounwind, !dbg !35 - store i32 1, i32* getelementptr inbounds (%struct.S1* @p, i64 0, i32 1), align 8, !dbg !36, !tbaa !24 - %call.i = tail call float* @bar(i32 1) nounwind optsize, !dbg !37 - store float* %call.i, float** getelementptr inbounds (%struct.S1* @p, i64 0, i32 0), align 8, !dbg !37, !tbaa !28 - ret void, !dbg !38 -} - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0, !6} -!llvm.dbg.lv.foo = !{!9, !18} -!llvm.dbg.gv = !{!19} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (%struct.S1*, i32)* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"nm2.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"nm2.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 125693)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foobar", metadata !"foobar", metadata !"", metadata !1, i32 15, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 true, void ()* @foobar} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!8 = metadata !{null} -!9 = metadata !{i32 590081, metadata !0, metadata !"sp", metadata !1, i32 7, metadata !10, i32 0} ; [ DW_TAG_arg_variable ] -!10 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !11} ; [ DW_TAG_pointer_type ] -!11 = metadata !{i32 589846, metadata !2, metadata !"S1", metadata !1, i32 4, i64 0, i64 0, i64 0, i32 0, metadata !12} ; [ DW_TAG_typedef ] -!12 = metadata !{i32 589843, metadata !2, metadata !"S1", metadata !1, i32 1, i64 128, i64 64, i32 0, i32 0, i32 0, metadata !13, i32 0, i32 0} ; [ DW_TAG_structure_type ] -!13 = metadata !{metadata !14, metadata !17} -!14 = metadata !{i32 589837, metadata !1, metadata !"m", metadata !1, i32 2, i64 64, i64 64, i64 0, i32 0, metadata !15} ; [ DW_TAG_member ] -!15 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !16} ; [ DW_TAG_pointer_type ] -!16 = metadata !{i32 589860, metadata !2, metadata !"float", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] -!17 = metadata !{i32 589837, metadata !1, metadata !"nums", metadata !1, i32 3, i64 32, i64 32, i64 64, i32 0, metadata !5} ; [ DW_TAG_member ] -!18 = metadata !{i32 590081, metadata !0, metadata !"nums", metadata !1, i32 7, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] -!19 = metadata !{i32 589876, i32 0, metadata !2, metadata !"p", metadata !"p", metadata !"", metadata !1, i32 14, metadata !11, i32 0, i32 1, %struct.S1* @p} ; [ DW_TAG_variable ] -!20 = metadata !{i32 7, i32 13, metadata !0, null} -!21 = metadata !{i32 7, i32 21, metadata !0, null} -!22 = metadata !{i32 9, i32 3, metadata !23, null} -!23 = metadata !{i32 589835, metadata !0, i32 8, i32 1, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!24 = metadata !{metadata !"int", metadata !25} -!25 = metadata !{metadata !"omnipotent char", metadata !26} -!26 = metadata !{metadata !"Simple C/C++ TBAA", null} -!27 = metadata !{i32 10, i32 3, metadata !23, null} -!28 = metadata !{metadata !"any pointer", metadata !25} -!29 = metadata !{i32 11, i32 3, metadata !23, null} -!30 = metadata !{%struct.S1* @p} -!31 = metadata !{i32 7, i32 13, metadata !0, metadata !32} -!32 = metadata !{i32 16, i32 3, metadata !33, null} -!33 = metadata !{i32 589835, metadata !6, i32 15, i32 15, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] -!34 = metadata !{i32 1} -!35 = metadata !{i32 7, i32 21, metadata !0, metadata !32} -!36 = metadata !{i32 9, i32 3, metadata !23, metadata !32} -!37 = metadata !{i32 10, i32 3, metadata !23, metadata !32} -!38 = metadata !{i32 17, i32 1, metadata !33, null} diff --git a/test/CodeGen/X86/dbg-value-isel.ll b/test/CodeGen/X86/dbg-value-isel.ll index f1101e61f0..e0dc9a4798 100644 --- a/test/CodeGen/X86/dbg-value-isel.ll +++ b/test/CodeGen/X86/dbg-value-isel.ll @@ -78,24 +78,25 @@ declare <4 x i32> @__amdil_get_global_id_int() nounwind declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0} +!llvm.dbg.cu = !{!2} +!19 = metadata !{metadata !0} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"__OpenCL_nbt02_kernel", metadata !"__OpenCL_nbt02_kernel", metadata !"__OpenCL_nbt02_kernel", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, null} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"OCLlLwTXZ.cl", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 1, metadata !"OCLlLwTXZ.cl", metadata !"/tmp", metadata !"clc", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"__OpenCL_nbt02_kernel", metadata !"__OpenCL_nbt02_kernel", metadata !"__OpenCL_nbt02_kernel", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, null} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"OCLlLwTXZ.cl", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 1, metadata !"OCLlLwTXZ.cl", metadata !"/tmp", metadata !"clc", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !19, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{null, metadata !5} -!5 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_pointer_type ] +!5 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_pointer_type ] !6 = metadata !{i32 589846, metadata !2, metadata !"uint", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_typedef ] -!7 = metadata !{i32 589860, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 590081, metadata !0, metadata !"ip", metadata !1, i32 1, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 786468, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 786689, metadata !0, metadata !"ip", metadata !1, i32 1, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] !9 = metadata !{i32 1, i32 32, metadata !0, null} -!10 = metadata !{i32 590080, metadata !11, metadata !"tid", metadata !1, i32 3, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] -!11 = metadata !{i32 589835, metadata !0, i32 2, i32 1, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 786688, metadata !11, metadata !"tid", metadata !1, i32 3, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] +!11 = metadata !{i32 786443, metadata !0, i32 2, i32 1, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] !12 = metadata !{i32 5, i32 24, metadata !11, null} -!13 = metadata !{i32 590080, metadata !11, metadata !"gid", metadata !1, i32 3, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] +!13 = metadata !{i32 786688, metadata !11, metadata !"gid", metadata !1, i32 3, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] !14 = metadata !{i32 6, i32 25, metadata !11, null} -!15 = metadata !{i32 590080, metadata !11, metadata !"lsz", metadata !1, i32 3, metadata !6, i32 0} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 786688, metadata !11, metadata !"lsz", metadata !1, i32 3, metadata !6, i32 0, null} ; [ DW_TAG_auto_variable ] !16 = metadata !{i32 7, i32 26, metadata !11, null} !17 = metadata !{i32 9, i32 24, metadata !11, null} !18 = metadata !{i32 10, i32 1, metadata !0, null} diff --git a/test/CodeGen/X86/dbg-value-location.ll b/test/CodeGen/X86/dbg-value-location.ll index 05e29ecff0..5ad8370618 100644 --- a/test/CodeGen/X86/dbg-value-location.ll +++ b/test/CodeGen/X86/dbg-value-location.ll @@ -45,26 +45,27 @@ declare hidden fastcc i32 @bar2(i32) nounwind optsize ssp declare hidden fastcc i32 @bar3(i32) nounwind optsize ssp declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0, !6, !7, !8} +!llvm.dbg.cu = !{!2} +!24 = metadata !{metadata !0, metadata !6, metadata !7, metadata !8} -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 19510, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i64, i8*, i32)* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/f.c", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"f.i", metadata !"/tmp", metadata !"clang version 2.9 (trunk 124753)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 19510, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i64, i8*, i32)* @foo, null, null, null, i32 19510} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"/tmp/f.c", metadata !"/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"f.i", metadata !"/tmp", metadata !"clang version 2.9 (trunk 124753)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !24, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"bar3", metadata !"bar3", metadata !"", metadata !1, i32 14827, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @bar3} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 589870, i32 0, metadata !1, metadata !"bar2", metadata !"bar2", metadata !"", metadata !1, i32 15397, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @bar2} ; [ DW_TAG_subprogram ] -!8 = metadata !{i32 589870, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 12382, metadata !9, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i32*)* @bar} ; [ DW_TAG_subprogram ] -!9 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !10, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786478, i32 0, metadata !1, metadata !"bar3", metadata !"bar3", metadata !"", metadata !1, i32 14827, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @bar3} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 786478, i32 0, metadata !1, metadata !"bar2", metadata !"bar2", metadata !"", metadata !1, i32 15397, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @bar2} ; [ DW_TAG_subprogram ] +!8 = metadata !{i32 786478, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 12382, metadata !9, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32, i32*)* @bar} ; [ DW_TAG_subprogram ] +!9 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !10, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !10 = metadata !{metadata !11} -!11 = metadata !{i32 589860, metadata !2, metadata !"unsigned char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] -!12 = metadata !{i32 590081, metadata !0, metadata !"var", metadata !1, i32 19509, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 786468, metadata !2, metadata !"unsigned char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] +!12 = metadata !{i32 786689, metadata !0, metadata !"var", metadata !1, i32 19509, metadata !5, i32 0, null} ; [ DW_TAG_arg_variable ] !13 = metadata !{i32 19509, i32 20, metadata !0, null} !14 = metadata !{i32 18091, i32 2, metadata !15, metadata !17} -!15 = metadata !{i32 589835, metadata !16, i32 18086, i32 1, metadata !1, i32 748} ; [ DW_TAG_lexical_block ] -!16 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo_bar", metadata !"foo_bar", metadata !"", metadata !1, i32 18086, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null} ; [ DW_TAG_subprogram ] +!15 = metadata !{i32 786443, metadata !16, i32 18086, i32 1, metadata !1, i32 748} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 786478, i32 0, metadata !1, metadata !"foo_bar", metadata !"foo_bar", metadata !"", metadata !1, i32 18086, metadata !3, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null} ; [ DW_TAG_subprogram ] !17 = metadata !{i32 19514, i32 2, metadata !18, null} -!18 = metadata !{i32 589835, metadata !0, i32 19510, i32 1, metadata !1, i32 99} ; [ DW_TAG_lexical_block ] +!18 = metadata !{i32 786443, metadata !0, i32 19510, i32 1, metadata !1, i32 99} ; [ DW_TAG_lexical_block ] !22 = metadata !{i32 18094, i32 2, metadata !15, metadata !17} !23 = metadata !{i32 19524, i32 1, metadata !18, null} diff --git a/test/CodeGen/X86/dbg-value-range.ll b/test/CodeGen/X86/dbg-value-range.ll index 6b16865ba9..2b26af93b6 100644 --- a/test/CodeGen/X86/dbg-value-range.ll +++ b/test/CodeGen/X86/dbg-value-range.ll @@ -17,22 +17,23 @@ declare i32 @foo(...) declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone -!llvm.dbg.sp = !{!0} -!llvm.dbg.lv.bar = !{!6, !11} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (%struct.a*)* @bar} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"bar.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"bar.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 122997)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!llvm.dbg.cu = !{!2} +!20 = metadata !{metadata !0} +!21 = metadata !{metadata !6, metadata !11} + +!0 = metadata !{i32 786478, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (%struct.a*)* @bar, null, null, metadata !21, i32 0} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 786473, metadata !"bar.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 786449, i32 0, i32 12, metadata !"bar.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 122997)", i1 true, i1 true, metadata !"", i32 0, null, null, metadata !20, null, null} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 786453, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] !4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 590081, metadata !0, metadata !"b", metadata !1, i32 5, metadata !7, i32 0} ; [ DW_TAG_arg_variable ] -!7 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] -!8 = metadata !{i32 589843, metadata !2, metadata !"a", metadata !1, i32 1, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !9, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!5 = metadata !{i32 786468, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 786689, metadata !0, metadata !"b", metadata !1, i32 5, metadata !7, i32 0, null} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 786447, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] +!8 = metadata !{i32 786451, metadata !2, metadata !"a", metadata !1, i32 1, i64 32, i64 32, i32 0, i32 0, i32 0, metadata !9, i32 0, i32 0} ; [ DW_TAG_structure_type ] !9 = metadata !{metadata !10} -!10 = metadata !{i32 589837, metadata !1, metadata !"c", metadata !1, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] -!11 = metadata !{i32 590080, metadata !12, metadata !"x", metadata !1, i32 6, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!12 = metadata !{i32 589835, metadata !0, i32 5, i32 22, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 786445, metadata !1, metadata !"c", metadata !1, i32 2, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] +!11 = metadata !{i32 786688, metadata !12, metadata !"x", metadata !1, i32 6, metadata !5, i32 0, null} ; [ DW_TAG_auto_variable ] +!12 = metadata !{i32 786443, metadata !0, i32 5, i32 22, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] !13 = metadata !{i32 5, i32 19, metadata !0, null} !14 = metadata !{i32 6, i32 14, metadata !12, null} !15 = metadata !{metadata !"int", metadata !16} diff --git a/test/CodeGen/X86/divide-by-constant.ll b/test/CodeGen/X86/divide-by-constant.ll index 8e7c13d8ef..9669d97cb7 100644 --- a/test/CodeGen/X86/divide-by-constant.ll +++ b/test/CodeGen/X86/divide-by-constant.ll @@ -56,9 +56,9 @@ entry: %div = sdiv i16 %x, 10 ret i16 %div ; CHECK: test6: -; CHECK: imull $26215, %eax, %eax -; CHECK: shrl $31, %ecx -; CHECK: sarl $18, %eax +; CHECK: imull $26215, %eax, %ecx +; CHECK: sarl $18, %ecx +; CHECK: shrl $15, %eax } define i32 @test7(i32 %x) nounwind { diff --git a/test/CodeGen/X86/dwarf-comp-dir.ll b/test/CodeGen/X86/dwarf-comp-dir.ll index c64752c952..63e6167bcb 100644 --- a/test/CodeGen/X86/dwarf-comp-dir.ll +++ b/test/CodeGen/X86/dwarf-comp-dir.ll @@ -1,5 +1,5 @@ ; RUN: llc %s -o %t -filetype=obj -; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llvm-dwarfdump -debug-dump=line %t | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/CodeGen/X86/early-ifcvt.ll b/test/CodeGen/X86/early-ifcvt.ll index 2e1852d3e3..2606bd28d5 100644 --- a/test/CodeGen/X86/early-ifcvt.ll +++ b/test/CodeGen/X86/early-ifcvt.ll @@ -142,3 +142,34 @@ save_state_and_return: } declare void @BZ2_bz__AssertH__fail() + +; Make sure we don't speculate on div/idiv instructions +; CHECK: test_idiv +; CHECK-NOT: cmov +define i32 @test_idiv(i32 %a, i32 %b) nounwind uwtable readnone ssp { + %1 = icmp eq i32 %b, 0 + br i1 %1, label %4, label %2 + +; <label>:2 ; preds = %0 + %3 = sdiv i32 %a, %b + br label %4 + +; <label>:4 ; preds = %0, %2 + %5 = phi i32 [ %3, %2 ], [ %a, %0 ] + ret i32 %5 +} + +; CHECK: test_div +; CHECK-NOT: cmov +define i32 @test_div(i32 %a, i32 %b) nounwind uwtable readnone ssp { + %1 = icmp eq i32 %b, 0 + br i1 %1, label %4, label %2 + +; <label>:2 ; preds = %0 + %3 = udiv i32 %a, %b + br label %4 + +; <label>:4 ; preds = %0, %2 + %5 = phi i32 [ %3, %2 ], [ %a, %0 ] + ret i32 %5 +} diff --git a/test/CodeGen/X86/fast-isel-args-fail.ll b/test/CodeGen/X86/fast-isel-args-fail.ll new file mode 100644 index 0000000000..4995baa3e5 --- /dev/null +++ b/test/CodeGen/X86/fast-isel-args-fail.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -fast-isel -verify-machineinstrs -mtriple=x86_64-apple-darwin10 +; Requires: Asserts + +; Previously, this would cause an assert. +define i31 @t1(i31 %a, i31 %b, i31 %c) { +entry: + %add = add nsw i31 %b, %a + %add1 = add nsw i31 %add, %c + ret i31 %add1 +} diff --git a/test/CodeGen/X86/fast-isel-args.ll b/test/CodeGen/X86/fast-isel-args.ll new file mode 100644 index 0000000000..0f3626565e --- /dev/null +++ b/test/CodeGen/X86/fast-isel-args.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -fast-isel -fast-isel-abort -fast-isel-abort-args -verify-machineinstrs -mtriple=x86_64-apple-darwin10 + +; Just make sure these don't abort when lowering the arguments. +define i32 @t1(i32 %a, i32 %b, i32 %c) { +entry: + %add = add nsw i32 %b, %a + %add1 = add nsw i32 %add, %c + ret i32 %add1 +} + +define i64 @t2(i64 %a, i64 %b, i64 %c) { +entry: + %add = add nsw i64 %b, %a + %add1 = add nsw i64 %add, %c + ret i64 %add1 +} + +define i64 @t3(i32 %a, i64 %b, i32 %c) { +entry: + %conv = sext i32 %a to i64 + %add = add nsw i64 %conv, %b + %conv1 = sext i32 %c to i64 + %add2 = add nsw i64 %add, %conv1 + ret i64 %add2 +} diff --git a/test/CodeGen/X86/fast-isel-constant.ll b/test/CodeGen/X86/fast-isel-constant.ll new file mode 100644 index 0000000000..6f9240ac47 --- /dev/null +++ b/test/CodeGen/X86/fast-isel-constant.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -march=x86-64 -O0 | FileCheck %s +; Make sure fast-isel doesn't reset the materialised constant map +; across an intrinsic call. + +; CHECK: movl $100000 +; CHECK-NOT: movl $100000 +define i1 @test1(i32 %v1, i32 %v2, i32* %X) nounwind { +entry: + %a = shl i32 100000, %v1 + %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %v2) + %ext = extractvalue {i32, i1} %t, 0 + %sum = shl i32 100000, %ext + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %overflow, label %normal + +normal: + store i32 %sum, i32* %X + br label %overflow + +overflow: + ret i1 false +} + +declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) diff --git a/test/CodeGen/X86/fast-isel-expect.ll b/test/CodeGen/X86/fast-isel-expect.ll new file mode 100644 index 0000000000..1f53348bd0 --- /dev/null +++ b/test/CodeGen/X86/fast-isel-expect.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -O0 -march=x86 | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@glbl = extern_weak constant i8 + +declare i64 @llvm.expect.i64(i64, i64) #0 + +define void @test() { +; CHECK: movl $glbl + %tmp = call i64 @llvm.expect.i64(i64 zext (i1 icmp eq (i8* @glbl, i8* null) to i64), i64 0) + %tmp2 = icmp ne i64 %tmp, 0 + br i1 %tmp2, label %bb1, label %bb2 + +bb1: + unreachable + +bb2: + unreachable +} + +attributes #0 = { nounwind readnone } diff --git a/test/CodeGen/X86/fast-isel-x86-64.ll b/test/CodeGen/X86/fast-isel-x86-64.ll index cdfaf7f4c1..ad1520ef81 100644 --- a/test/CodeGen/X86/fast-isel-x86-64.ll +++ b/test/CodeGen/X86/fast-isel-x86-64.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mattr=-avx -fast-isel -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort | FileCheck %s -; RUN: llc < %s -mattr=+avx -fast-isel -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort | FileCheck %s --check-prefix=AVX +; RUN: llc < %s -mattr=-avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort | FileCheck %s +; RUN: llc < %s -mattr=+avx -fast-isel -mcpu=core2 -O0 -regalloc=fast -asm-verbose=0 -fast-isel-abort | FileCheck %s --check-prefix=AVX target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" diff --git a/test/CodeGen/X86/float-asmprint.ll b/test/CodeGen/X86/float-asmprint.ll new file mode 100644 index 0000000000..4aeae7fe04 --- /dev/null +++ b/test/CodeGen/X86/float-asmprint.ll @@ -0,0 +1,40 @@ +; RUN: llc -mtriple=x86_64-none-linux < %s | FileCheck %s + +; Check that all current floating-point types are correctly emitted to assembly +; on a little-endian target. + +@var128 = global fp128 0xL00000000000000008000000000000000, align 16 +@varppc128 = global ppc_fp128 0xM80000000000000000000000000000000, align 16 +@var80 = global x86_fp80 0xK80000000000000000000, align 16 +@var64 = global double -0.0, align 8 +@var32 = global float -0.0, align 4 +@var16 = global half -0.0, align 2 + +; CHECK: var128: +; CHECK-NEXT: .quad 0 # fp128 -0 +; CHECK-NEXT: .quad -9223372036854775808 +; CHECK-NEXT: .size + +; CHECK: varppc128: +; CHECK-NEXT: .quad 0 # ppc_fp128 -0 +; CHECK-NEXT: .quad -9223372036854775808 +; CHECK-NEXT: .size + +; CHECK: var80: +; CHECK-NEXT: .quad 0 # x86_fp80 -0 +; CHECK-NEXT: .short 32768 +; CHECK-NEXT: .zero 6 +; CHECK-NEXT: .size + +; CHECK: var64: +; CHECK-NEXT: .quad -9223372036854775808 # double -0 +; CHECK-NEXT: .size + +; CHECK: var32: +; CHECK-NEXT: .long 2147483648 # float -0 +; CHECK-NEXT: .size + +; CHECK: var16: +; CHECK-NEXT: .short 32768 # half -0 +; CHECK-NEXT: .size + diff --git a/test/CodeGen/X86/fold-call.ll b/test/CodeGen/X86/fold-call.ll index 603e9ad66c..35327faa64 100644 --- a/test/CodeGen/X86/fold-call.ll +++ b/test/CodeGen/X86/fold-call.ll @@ -1,10 +1,27 @@ -; RUN: llc < %s -march=x86 | not grep mov -; RUN: llc < %s -march=x86-64 | not grep mov +; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -march=x86-64 | FileCheck %s -declare void @bar() +; CHECK: test1 +; CHECK-NOT: mov -define void @foo(i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, void()* %arg) nounwind { +declare void @bar() +define void @test1(i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, void()* %arg) nounwind { call void @bar() call void %arg() ret void } + +; PR14739 +; CHECK: test2 +; CHECK: mov{{.*}} $0, ([[REGISTER:%[a-z]+]]) +; CHECK-NOT: jmp{{.*}} *([[REGISTER]]) + +%struct.X = type { void ()* } +define void @test2(%struct.X* nocapture %x) { +entry: + %f = getelementptr inbounds %struct.X* %x, i64 0, i32 0 + %0 = load void ()** %f + store void ()* null, void ()** %f + tail call void %0() + ret void +} diff --git a/test/CodeGen/X86/fold-vex.ll b/test/CodeGen/X86/fold-vex.ll new file mode 100644 index 0000000000..2bb5b441c7 --- /dev/null +++ b/test/CodeGen/X86/fold-vex.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=corei7-avx | FileCheck %s + +;CHECK: @test +; No need to load from memory. The operand will be loaded as part of th AND instr. +;CHECK-NOT: vmovaps +;CHECK: vandps +;CHECK: ret + +define void @test1(<8 x i32>* %p0, <8 x i32> %in1) nounwind { +entry: + %in0 = load <8 x i32>* %p0, align 2 + %a = and <8 x i32> %in0, %in1 + store <8 x i32> %a, <8 x i32>* undef + ret void +} + diff --git a/test/CodeGen/X86/fp-fast.ll b/test/CodeGen/X86/fp-fast.ll index d70aa7d79f..287504801d 100644 --- a/test/CodeGen/X86/fp-fast.ll +++ b/test/CodeGen/X86/fp-fast.ll @@ -38,7 +38,7 @@ define float @test3(float %a) { ; CHECK: test4 define float @test4(float %a) { ; CHECK-NOT: fma -; CHECK-NOT mul +; CHECK-NOT: mul ; CHECK-NOT: add ; CHECK: ret %t1 = fmul float %a, 0.0 diff --git a/test/CodeGen/X86/fp-load-trunc.ll b/test/CodeGen/X86/fp-load-trunc.ll index 2ae65c97d9..a973befdaf 100644 --- a/test/CodeGen/X86/fp-load-trunc.ll +++ b/test/CodeGen/X86/fp-load-trunc.ll @@ -49,8 +49,8 @@ define <8 x float> @test4(<8 x double>* %p) nounwind { ; CHECK: movlhps ; CHECK: ret ; AVX: test4 -; AVX: vcvtpd2psy {{[0-9]*}}(%{{.*}}) -; AVX: vcvtpd2psy {{[0-9]*}}(%{{.*}}) +; AVX: vcvtpd2psy +; AVX: vcvtpd2psy ; AVX: vinsertf128 ; AVX: ret %x = load <8 x double>* %p diff --git a/test/CodeGen/X86/handle-move.ll b/test/CodeGen/X86/handle-move.ll index e9f7a962e2..93441cd7e8 100644 --- a/test/CodeGen/X86/handle-move.ll +++ b/test/CodeGen/X86/handle-move.ll @@ -1,6 +1,7 @@ ; RUN: llc -march=x86-64 -mcpu=core2 -fast-isel -enable-misched -misched=shuffle -misched-bottomup -verify-machineinstrs < %s ; RUN: llc -march=x86-64 -mcpu=core2 -fast-isel -enable-misched -misched=shuffle -misched-topdown -verify-machineinstrs < %s ; REQUIRES: asserts +; XFAIL: cygwin,mingw32 ; ; Test the LiveIntervals::handleMove() function. ; @@ -16,7 +17,7 @@ ; DL: [0B,16r:0)[128r,144r:2)[144r,144d:1) 0@0B-phi 1@144r 2@128r ; --> [0B,16r:0)[128r,180r:2)[180r,180d:1) 0@0B-phi 1@180r 2@128r ; -define i32 @f1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind uwtable readnone ssp { +define i32 @f1(i32 %a, i32 %b, i32 %c) nounwind uwtable readnone ssp { entry: %y = add i32 %c, 1 %x = udiv i32 %b, %a @@ -50,7 +51,7 @@ entry: ; %vreg5: [16r,112r:0) 0@16r ; --> [16r,120r:0) 0@16r ; -define i32 @f3(i32 %a, i32 %b, i32 %c, i32 %d) nounwind uwtable readnone ssp { +define i32 @f3(i32 %a, i32 %b) nounwind uwtable readnone ssp { entry: %y = sub i32 %a, %b %x = add i32 %a, %b diff --git a/test/CodeGen/X86/hipe-prologue.ll b/test/CodeGen/X86/hipe-prologue.ll new file mode 100644 index 0000000000..ff3c5c803c --- /dev/null +++ b/test/CodeGen/X86/hipe-prologue.ll @@ -0,0 +1,67 @@ +; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux +; RUN: llc < %s -mtriple=x86_64-linux-gnu -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux + +; The HiPE compiler (i.e., the native code compiler of the Erlang/OTP system) +; adds a custom assembly prologue in order to efficiently manipulate the stack +; at runtime. + +; Just to prevent the alloca from being optimized away. +declare void @dummy_use(i32*, i32) + +define {i32, i32} @test_basic(i32 %hp, i32 %p) { + ; X32-Linux: test_basic: + ; X32-Linux-NOT: calll inc_stack_0 + + ; X64-Linux: test_basic: + ; X64-Linux-NOT: callq inc_stack_0 + + %mem = alloca i32, i32 10 + call void @dummy_use (i32* %mem, i32 10) + %1 = insertvalue {i32, i32} undef, i32 %hp, 0 + %2 = insertvalue {i32, i32} %1, i32 %p, 1 + ret {i32, i32} %1 +} + +define cc 11 {i32, i32} @test_basic_hipecc(i32 %hp, i32 %p) { + ; X32-Linux: test_basic_hipecc: + ; X32-Linux: leal -156(%esp), %ebx + ; X32-Linux-NEXT: cmpl 76(%ebp), %ebx + ; X32-Linux-NEXT: jb .LBB1_1 + + ; X32-Linux: ret + + ; X32-Linux: .LBB1_1: + ; X32-Linux-NEXT: calll inc_stack_0 + + ; X64-Linux: test_basic_hipecc: + ; X64-Linux: leaq -232(%rsp), %r14 + ; X64-Linux-NEXT: cmpq 144(%rbp), %r14 + ; X64-Linux-NEXT: jb .LBB1_1 + + ; X64-Linux: ret + + ; X64-Linux: .LBB1_1: + ; X64-Linux-NEXT: callq inc_stack_0 + + %mem = alloca i32, i32 10 + call void @dummy_use (i32* %mem, i32 10) + %1 = insertvalue {i32, i32} undef, i32 %hp, 0 + %2 = insertvalue {i32, i32} %1, i32 %p, 1 + ret {i32, i32} %2 +} + +define cc 11 {i32,i32,i32} @test_nocall_hipecc(i32 %hp,i32 %p,i32 %x,i32 %y) { + ; X32-Linux: test_nocall_hipecc: + ; X32-Linux-NOT: calll inc_stack_0 + + ; X64-Linux: test_nocall_hipecc: + ; X64-Linux-NOT: callq inc_stack_0 + + %1 = add i32 %x, %y + %2 = mul i32 42, %1 + %3 = sub i32 24, %2 + %4 = insertvalue {i32, i32, i32} undef, i32 %hp, 0 + %5 = insertvalue {i32, i32, i32} %4, i32 %p, 1 + %6 = insertvalue {i32, i32, i32} %5, i32 %p, 2 + ret {i32, i32, i32} %6 +} diff --git a/test/CodeGen/X86/imul-lea-2.ll b/test/CodeGen/X86/imul-lea-2.ll index 1cb54b37b0..7b79d0678b 100644 --- a/test/CodeGen/X86/imul-lea-2.ll +++ b/test/CodeGen/X86/imul-lea-2.ll @@ -1,15 +1,19 @@ -; RUN: llc < %s -march=x86-64 | grep lea | count 3 -; RUN: llc < %s -march=x86-64 | grep shl | count 1 -; RUN: llc < %s -march=x86-64 | not grep imul +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; CHECK-NOT: imul define i64 @t1(i64 %a) nounwind readnone { entry: - %0 = mul i64 %a, 81 ; <i64> [#uses=1] - ret i64 %0 + %0 = mul i64 %a, 81 +; CHECK: lea +; CHECK: lea + ret i64 %0 } define i64 @t2(i64 %a) nounwind readnone { entry: - %0 = mul i64 %a, 40 ; <i64> [#uses=1] - ret i64 %0 + %0 = mul i64 %a, 40 +; CHECK: shl +; CHECK: lea + ret i64 %0 } diff --git a/test/CodeGen/X86/imul-lea.ll b/test/CodeGen/X86/imul-lea.ll index 4e8e2af0f2..d55ece7996 100644 --- a/test/CodeGen/X86/imul-lea.ll +++ b/test/CodeGen/X86/imul-lea.ll @@ -1,10 +1,12 @@ -; RUN: llc < %s -march=x86 | grep lea +; RUN: llc < %s -march=x86 | FileCheck %s declare i32 @foo() define i32 @test() { - %tmp.0 = tail call i32 @foo( ) ; <i32> [#uses=1] - %tmp.1 = mul i32 %tmp.0, 9 ; <i32> [#uses=1] - ret i32 %tmp.1 + %tmp.0 = tail call i32 @foo( ) + %tmp.1 = mul i32 %tmp.0, 9 +; CHECK-NOT: mul +; CHECK: lea + ret i32 %tmp.1 } diff --git a/test/CodeGen/X86/imul64-lea.ll b/test/CodeGen/X86/imul64-lea.ll new file mode 100644 index 0000000000..047c129ddb --- /dev/null +++ b/test/CodeGen/X86/imul64-lea.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s + +; Test that 64-bit LEAs are generated for both LP64 and ILP32 in 64-bit mode. +declare i64 @foo64() + +define i64 @test64() { + %tmp.0 = tail call i64 @foo64( ) + %tmp.1 = mul i64 %tmp.0, 9 +; CHECK-NOT: mul +; CHECK: leaq + ret i64 %tmp.1 +} + +; Test that 32-bit LEAs are generated for both LP64 and ILP32 in 64-bit mode. +declare i32 @foo32() + +define i32 @test32() { + %tmp.0 = tail call i32 @foo32( ) + %tmp.1 = mul i32 %tmp.0, 9 +; CHECK-NOT: mul +; CHECK: leal + ret i32 %tmp.1 +} + diff --git a/test/CodeGen/X86/insertelement-copytoregs.ll b/test/CodeGen/X86/insertelement-copytoregs.ll index 34a29ca7d9..88ff4dafad 100644 --- a/test/CodeGen/X86/insertelement-copytoregs.ll +++ b/test/CodeGen/X86/insertelement-copytoregs.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | grep -v IMPLICIT_DEF +; RUN: llc < %s -march=x86-64 | FileCheck %s +; CHECK-NOT: IMPLICIT_DEF define void @foo(<2 x float>* %p) { %t = insertelement <2 x float> undef, float 0.0, i32 0 diff --git a/test/CodeGen/X86/lea-2.ll b/test/CodeGen/X86/lea-2.ll index 43f69b0c6e..21128096e6 100644 --- a/test/CodeGen/X86/lea-2.ll +++ b/test/CodeGen/X86/lea-2.ll @@ -1,13 +1,15 @@ -; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \ -; RUN: grep "lea EAX, DWORD PTR \[... + 4\*... - 5\]" -; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \ -; RUN: not grep add +; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | FileCheck %s define i32 @test1(i32 %A, i32 %B) { - %tmp1 = shl i32 %A, 2 ; <i32> [#uses=1] - %tmp3 = add i32 %B, -5 ; <i32> [#uses=1] - %tmp4 = add i32 %tmp3, %tmp1 ; <i32> [#uses=1] - ret i32 %tmp4 + %tmp1 = shl i32 %A, 2 + %tmp3 = add i32 %B, -5 + %tmp4 = add i32 %tmp3, %tmp1 +; The above computation of %tmp4 should match a single lea, without using +; actual add instructions. +; CHECK-NOT: add +; CHECK: lea {{[A-Z]+}}, DWORD PTR [{{[A-Z]+}} + 4*{{[A-Z]+}} - 5] + + ret i32 %tmp4 } diff --git a/test/CodeGen/X86/lea-4.ll b/test/CodeGen/X86/lea-4.ll index 2171204c01..cef47264a5 100644 --- a/test/CodeGen/X86/lea-4.ll +++ b/test/CodeGen/X86/lea-4.ll @@ -1,19 +1,21 @@ -; RUN: llc < %s -march=x86-64 | grep lea | count 2 +; RUN: llc < %s -march=x86-64 | FileCheck %s define zeroext i16 @t1(i32 %on_off) nounwind { entry: - %0 = sub i32 %on_off, 1 - %1 = mul i32 %0, 2 - %2 = trunc i32 %1 to i16 - %3 = zext i16 %2 to i32 - %4 = trunc i32 %3 to i16 - ret i16 %4 + %0 = sub i32 %on_off, 1 + %1 = mul i32 %0, 2 + %2 = trunc i32 %1 to i16 + %3 = zext i16 %2 to i32 + %4 = trunc i32 %3 to i16 +; CHECK: lea + ret i16 %4 } define i32 @t2(i32 %on_off) nounwind { entry: - %0 = sub i32 %on_off, 1 - %1 = mul i32 %0, 2 - %2 = and i32 %1, 65535 - ret i32 %2 + %0 = sub i32 %on_off, 1 + %1 = mul i32 %0, 2 + %2 = and i32 %1, 65535 +; CHECK: lea + ret i32 %2 } diff --git a/test/CodeGen/X86/legalize-shift-64.ll b/test/CodeGen/X86/legalize-shift-64.ll index c9f2fc27db..71ef2d3152 100644 --- a/test/CodeGen/X86/legalize-shift-64.ll +++ b/test/CodeGen/X86/legalize-shift-64.ll @@ -54,3 +54,14 @@ define i64 @test4(i64 %xx, i32 %test) nounwind { ; CHECK: orl %esi, %eax ; CHECK: sarl %cl, %edx } + +; PR14668 +define <2 x i64> @test5(<2 x i64> %A, <2 x i64> %B) { + %shl = shl <2 x i64> %A, %B + ret <2 x i64> %shl +; CHECK: test5 +; CHECK: shl +; CHECK: shldl +; CHECK: shl +; CHECK: shldl +} diff --git a/test/CodeGen/X86/memcpy-2.ll b/test/CodeGen/X86/memcpy-2.ll index dcc8f0d268..630c0ed1a3 100644 --- a/test/CodeGen/X86/memcpy-2.ll +++ b/test/CodeGen/X86/memcpy-2.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mattr=+sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE2 -; RUN: llc < %s -mattr=+sse2 -mtriple=i686-pc-mingw32 -mcpu=core2 | FileCheck %s -check-prefix=SSE2 +; RUN: llc < %s -mattr=+sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE2-Darwin +; RUN: llc < %s -mattr=+sse2 -mtriple=i686-pc-mingw32 -mcpu=core2 | FileCheck %s -check-prefix=SSE2-Mingw32 ; RUN: llc < %s -mattr=+sse,-sse2 -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=SSE1 ; RUN: llc < %s -mattr=-sse -mtriple=i686-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=NOSSE ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core2 | FileCheck %s -check-prefix=X86-64 @@ -9,19 +9,26 @@ define void @t1(i32 %argc, i8** %argv) nounwind { entry: -; SSE2: t1: -; SSE2: movsd _.str+16, %xmm0 -; SSE2: movsd %xmm0, 16(%esp) -; SSE2: movaps _.str, %xmm0 -; SSE2: movaps %xmm0 -; SSE2: movb $0, 24(%esp) +; SSE2-Darwin: t1: +; SSE2-Darwin: movsd _.str+16, %xmm0 +; SSE2-Darwin: movsd %xmm0, 16(%esp) +; SSE2-Darwin: movaps _.str, %xmm0 +; SSE2-Darwin: movaps %xmm0 +; SSE2-Darwin: movb $0, 24(%esp) + +; SSE2-Mingw32: t1: +; SSE2-Mingw32: movsd _.str+16, %xmm0 +; SSE2-Mingw32: movsd %xmm0, 16(%esp) +; SSE2-Mingw32: movaps _.str, %xmm0 +; SSE2-Mingw32: movups %xmm0 +; SSE2-Mingw32: movb $0, 24(%esp) ; SSE1: t1: -; SSE1: fldl _.str+16 -; SSE1: fstpl 16(%esp) ; SSE1: movaps _.str, %xmm0 ; SSE1: movaps %xmm0 ; SSE1: movb $0, 24(%esp) +; SSE1: movl $0, 20(%esp) +; SSE1: movl $0, 16(%esp) ; NOSSE: t1: ; NOSSE: movb $0 @@ -48,9 +55,13 @@ entry: define void @t2(%struct.s0* nocapture %a, %struct.s0* nocapture %b) nounwind ssp { entry: -; SSE2: t2: -; SSE2: movaps (%eax), %xmm0 -; SSE2: movaps %xmm0, (%eax) +; SSE2-Darwin: t2: +; SSE2-Darwin: movaps (%eax), %xmm0 +; SSE2-Darwin: movaps %xmm0, (%eax) + +; SSE2-Mingw32: t2: +; SSE2-Mingw32: movaps (%eax), %xmm0 +; SSE2-Mingw32: movaps %xmm0, (%eax) ; SSE1: t2: ; SSE1: movaps (%eax), %xmm0 @@ -79,11 +90,17 @@ entry: define void @t3(%struct.s0* nocapture %a, %struct.s0* nocapture %b) nounwind ssp { entry: -; SSE2: t3: -; SSE2: movsd (%eax), %xmm0 -; SSE2: movsd 8(%eax), %xmm1 -; SSE2: movsd %xmm1, 8(%eax) -; SSE2: movsd %xmm0, (%eax) +; SSE2-Darwin: t3: +; SSE2-Darwin: movsd (%eax), %xmm0 +; SSE2-Darwin: movsd 8(%eax), %xmm1 +; SSE2-Darwin: movsd %xmm1, 8(%eax) +; SSE2-Darwin: movsd %xmm0, (%eax) + +; SSE2-Mingw32: t3: +; SSE2-Mingw32: movsd (%eax), %xmm0 +; SSE2-Mingw32: movsd 8(%eax), %xmm1 +; SSE2-Mingw32: movsd %xmm1, 8(%eax) +; SSE2-Mingw32: movsd %xmm0, (%eax) ; SSE1: t3: ; SSE1: movl @@ -122,15 +139,25 @@ entry: define void @t4() nounwind { entry: -; SSE2: t4: -; SSE2: movw $120 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 -; SSE2: movl $2021161080 +; SSE2-Darwin: t4: +; SSE2-Darwin: movw $120 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 +; SSE2-Darwin: movl $2021161080 + +; SSE2-Mingw32: t4: +; SSE2-Mingw32: movw $120 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 +; SSE2-Mingw32: movl $2021161080 ; SSE1: t4: ; SSE1: movw $120 diff --git a/test/CodeGen/X86/memcpy.ll b/test/CodeGen/X86/memcpy.ll index 39c7fbafd4..3372a4adc5 100644 --- a/test/CodeGen/X86/memcpy.ll +++ b/test/CodeGen/X86/memcpy.ll @@ -87,8 +87,34 @@ entry: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([30 x i8]* @.str, i64 0, i64 0), i64 16, i32 1, i1 false) ret void +; DARWIN: test5: ; DARWIN: movabsq $7016996765293437281 ; DARWIN: movabsq $7016996765293437184 } +; PR14896 +@.str2 = private unnamed_addr constant [2 x i8] c"x\00", align 1 + +define void @test6() nounwind uwtable { +entry: +; DARWIN: test6 +; DARWIN: movw $0, 8 +; DARWIN: movq $120, 0 + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* null, i8* getelementptr inbounds ([2 x i8]* @.str2, i64 0, i64 0), i64 10, i32 1, i1 false) + ret void +} + +define void @PR15348(i8* %a, i8* %b) { +; Ensure that alignment of '0' in an @llvm.memcpy intrinsic results in +; unaligned loads and stores. +; LINUX: PR15348 +; LINUX: movb +; LINUX: movb +; LINUX: movq +; LINUX: movq +; LINUX: movq +; LINUX: movq + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 17, i32 0, i1 false) + ret void +} diff --git a/test/CodeGen/X86/memset.ll b/test/CodeGen/X86/memset.ll index b35f2615d0..0d479f0abe 100644 --- a/test/CodeGen/X86/memset.ll +++ b/test/CodeGen/X86/memset.ll @@ -20,15 +20,18 @@ entry: ; X86: movl $0, ; X86: movl $0, ; X86-NOT: movl $0, +; X86: ret ; XMM: xorps %xmm{{[0-9]+}}, [[Z:%xmm[0-9]+]] ; XMM: movaps [[Z]], ; XMM: movaps [[Z]], ; XMM-NOT: movaps +; XMM: ret ; YMM: vxorps %ymm{{[0-9]+}}, %ymm{{[0-9]+}}, [[Z:%ymm[0-9]+]] ; YMM: vmovaps [[Z]], ; YMM-NOT: movaps +; YMM: ret call void @foo( %struct.x* %up_mvd116 ) nounwind ret void @@ -37,3 +40,16 @@ entry: declare void @foo(%struct.x*) declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind + +define void @PR15348(i8* %a) { +; Ensure that alignment of '0' in an @llvm.memset intrinsic results in +; unaligned loads and stores. +; XMM: PR15348 +; XMM: movb $0, +; XMM: movl $0, +; XMM: movl $0, +; XMM: movl $0, +; XMM: movl $0, + call void @llvm.memset.p0i8.i64(i8* %a, i8 0, i64 17, i32 0, i1 false) + ret void +} diff --git a/test/CodeGen/X86/misched-crash.ll b/test/CodeGen/X86/misched-crash.ll new file mode 100644 index 0000000000..7644ee0708 --- /dev/null +++ b/test/CodeGen/X86/misched-crash.ll @@ -0,0 +1,40 @@ +; RUN: llc < %s -enable-misched -verify-misched +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10" + +; This function contains a cmp instruction with two users. +; Hoisting the last use requires trimming the EFLAGS live range to the second. +define void @rdar13353090(i8* %plane, i64 %_x1, i64 %_x2) { +entry: + %cmp = icmp ult i64 %_x1, %_x2 + %cond = select i1 %cmp, i64 %_x1, i64 %_x2 + %cond10 = select i1 %cmp, i64 %_x2, i64 %_x1 + %0 = load i64* null, align 8 + %cmp16 = icmp ult i64 %cond, %0 + %cmp23 = icmp ugt i64 %cond10, 0 + br i1 %cmp16, label %land.lhs.true21, label %return + +land.lhs.true21: ; preds = %entry + %sub = add i64 %0, -1 + br i1 %cmp23, label %if.then24, label %return + +if.then24: ; preds = %land.lhs.true21 + %cmp16.i = icmp ult i64 %cond, %sub + %cond20.i = select i1 %cmp16.i, i64 %cond, i64 %sub + %add21.i = add i64 0, %cond20.i + br label %for.body34.i + +for.body34.i: ; preds = %for.inc39.i, %if.then24 + %index.178.i = phi i64 [ %add21.i, %if.then24 ], [ %inc41.i, %for.inc39.i ] + %arrayidx35.i = getelementptr inbounds i8* %plane, i64 %index.178.i + %1 = load i8* %arrayidx35.i, align 1 + %tobool36.i = icmp eq i8 %1, 0 + br i1 %tobool36.i, label %for.inc39.i, label %return + +for.inc39.i: ; preds = %for.body34.i + %inc41.i = add i64 %index.178.i, 1 + br i1 undef, label %return, label %for.body34.i + +return: ; preds = %for.inc39.i, %for.body34.i, %land.lhs.true21, %entry + ret void +} diff --git a/test/CodeGen/X86/ms-inline-asm.ll b/test/CodeGen/X86/ms-inline-asm.ll index 24d28adda8..5048a93ad3 100644 --- a/test/CodeGen/X86/ms-inline-asm.ll +++ b/test/CodeGen/X86/ms-inline-asm.ll @@ -1,10 +1,11 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -march=x86 -mcpu=core2 | FileCheck %s define i32 @t1() nounwind { entry: %0 = tail call i32 asm sideeffect inteldialect "mov eax, $1\0A\09mov $0, eax", "=r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 1) nounwind ret i32 %0 ; CHECK: t1 +; CHECK: movl %esp, %ebp ; CHECK: {{## InlineAsm Start|#APP}} ; CHECK: .intel_syntax ; CHECK: mov eax, ecx @@ -18,6 +19,7 @@ entry: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind ret void ; CHECK: t2 +; CHECK: movl %esp, %ebp ; CHECK: {{## InlineAsm Start|#APP}} ; CHECK: .intel_syntax ; CHECK: mov eax, 1 @@ -32,6 +34,7 @@ entry: call void asm sideeffect inteldialect "mov eax, DWORD PTR [$0]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %V.addr) nounwind ret void ; CHECK: t3 +; CHECK: movl %esp, %ebp ; CHECK: {{## InlineAsm Start|#APP}} ; CHECK: .intel_syntax ; CHECK: mov eax, DWORD PTR {{[[esp]}} @@ -53,6 +56,7 @@ entry: %0 = load i32* %b1, align 4 ret i32 %0 ; CHECK: t18 +; CHECK: movl %esp, %ebp ; CHECK: {{## InlineAsm Start|#APP}} ; CHECK: .intel_syntax ; CHECK: lea ebx, foo @@ -61,3 +65,46 @@ entry: ; CHECK: .att_syntax ; CHECK: {{## InlineAsm End|#NO_APP}} } + +define void @t19_helper() nounwind { +entry: + ret void +} + +define void @t19() nounwind { +entry: + call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t19_helper) nounwind + ret void +; CHECK: t19: +; CHECK: movl %esp, %ebp +; CHECK: movl ${{_?}}t19_helper, %eax +; CHECK: {{## InlineAsm Start|#APP}} +; CHECK: .intel_syntax +; CHECK: call eax +; CHECK: .att_syntax +; CHECK: {{## InlineAsm End|#NO_APP}} +} + +@results = global [2 x i32] [i32 3, i32 2], align 4 + +define i32* @t30() nounwind ssp { +entry: + %res = alloca i32*, align 4 + call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @results) nounwind + call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %res) nounwind + %0 = load i32** %res, align 4 + ret i32* %0 +; CHECK: t30: +; CHECK: movl %esp, %ebp +; CHECK: {{## InlineAsm Start|#APP}} +; CHECK: .intel_syntax +; CHECK: lea edi, dword ptr [{{_?}}results] +; CHECK: .att_syntax +; CHECK: {{## InlineAsm End|#NO_APP}} +; CHECK: {{## InlineAsm Start|#APP}} +; CHECK: .intel_syntax +; CHECK: mov dword ptr [esi], edi +; CHECK: .att_syntax +; CHECK: {{## InlineAsm End|#NO_APP}} +; CHECK: movl (%esi), %eax +} diff --git a/test/CodeGen/X86/no-cmov.ll b/test/CodeGen/X86/no-cmov.ll new file mode 100644 index 0000000000..62d73b0732 --- /dev/null +++ b/test/CodeGen/X86/no-cmov.ll @@ -0,0 +1,11 @@ +; RUN: llc -march=x86 -mcpu=i486 < %s | FileCheck %s + +define i32 @test1(i32 %g, i32* %j) { + %tobool = icmp eq i32 %g, 0 + %cmp = load i32* %j, align 4 + %retval.0 = select i1 %tobool, i32 1, i32 %cmp + ret i32 %retval.0 + +; CHECK: test1: +; CHECK-NOT: cmov +} diff --git a/test/CodeGen/X86/pmovsx-inreg.ll b/test/CodeGen/X86/pmovsx-inreg.ll new file mode 100644 index 0000000000..d8c27f2504 --- /dev/null +++ b/test/CodeGen/X86/pmovsx-inreg.ll @@ -0,0 +1,176 @@ +; RUN: llc < %s -march=x86-64 -mcpu=penryn | FileCheck -check-prefix=SSE41 %s +; RUN: llc < %s -march=x86-64 -mcpu=corei7-avx | FileCheck -check-prefix=AVX1 %s +; RUN: llc < %s -march=x86-64 -mcpu=core-avx2 | FileCheck -check-prefix=AVX2 %s + +; PR14887 +; These tests inject a store into the chain to test the inreg versions of pmovsx + +define void @test1(<2 x i8>* %in, <2 x i64>* %out) nounwind { + %wide.load35 = load <2 x i8>* %in, align 1 + %sext = sext <2 x i8> %wide.load35 to <2 x i64> + store <2 x i64> zeroinitializer, <2 x i64>* undef, align 8 + store <2 x i64> %sext, <2 x i64>* %out, align 8 + ret void + +; SSE41: test1: +; SSE41: pmovsxbq + +; AVX1: test1: +; AVX1: vpmovsxbq + +; AVX2: test1: +; AVX2: vpmovsxbq +} + +define void @test2(<4 x i8>* %in, <4 x i64>* %out) nounwind { + %wide.load35 = load <4 x i8>* %in, align 1 + %sext = sext <4 x i8> %wide.load35 to <4 x i64> + store <4 x i64> zeroinitializer, <4 x i64>* undef, align 8 + store <4 x i64> %sext, <4 x i64>* %out, align 8 + ret void + +; AVX2: test2: +; AVX2: vpmovsxbq +} + +define void @test3(<4 x i8>* %in, <4 x i32>* %out) nounwind { + %wide.load35 = load <4 x i8>* %in, align 1 + %sext = sext <4 x i8> %wide.load35 to <4 x i32> + store <4 x i32> zeroinitializer, <4 x i32>* undef, align 8 + store <4 x i32> %sext, <4 x i32>* %out, align 8 + ret void + +; SSE41: test3: +; SSE41: pmovsxbd + +; AVX1: test3: +; AVX1: vpmovsxbd + +; AVX2: test3: +; AVX2: vpmovsxbd +} + +define void @test4(<8 x i8>* %in, <8 x i32>* %out) nounwind { + %wide.load35 = load <8 x i8>* %in, align 1 + %sext = sext <8 x i8> %wide.load35 to <8 x i32> + store <8 x i32> zeroinitializer, <8 x i32>* undef, align 8 + store <8 x i32> %sext, <8 x i32>* %out, align 8 + ret void + +; AVX2: test4: +; AVX2: vpmovsxbd +} + +define void @test5(<8 x i8>* %in, <8 x i16>* %out) nounwind { + %wide.load35 = load <8 x i8>* %in, align 1 + %sext = sext <8 x i8> %wide.load35 to <8 x i16> + store <8 x i16> zeroinitializer, <8 x i16>* undef, align 8 + store <8 x i16> %sext, <8 x i16>* %out, align 8 + ret void + +; SSE41: test5: +; SSE41: pmovsxbw + +; AVX1: test5: +; AVX1: vpmovsxbw + +; AVX2: test5: +; AVX2: vpmovsxbw +} + +define void @test6(<16 x i8>* %in, <16 x i16>* %out) nounwind { + %wide.load35 = load <16 x i8>* %in, align 1 + %sext = sext <16 x i8> %wide.load35 to <16 x i16> + store <16 x i16> zeroinitializer, <16 x i16>* undef, align 8 + store <16 x i16> %sext, <16 x i16>* %out, align 8 + ret void + +; AVX2: test6: +; FIXME: v16i8 -> v16i16 is scalarized. +; AVX2-NOT: pmovsx +} + +define void @test7(<2 x i16>* %in, <2 x i64>* %out) nounwind { + %wide.load35 = load <2 x i16>* %in, align 1 + %sext = sext <2 x i16> %wide.load35 to <2 x i64> + store <2 x i64> zeroinitializer, <2 x i64>* undef, align 8 + store <2 x i64> %sext, <2 x i64>* %out, align 8 + ret void + + +; SSE41: test7: +; SSE41: pmovsxwq + +; AVX1: test7: +; AVX1: vpmovsxwq + +; AVX2: test7: +; AVX2: vpmovsxwq +} + +define void @test8(<4 x i16>* %in, <4 x i64>* %out) nounwind { + %wide.load35 = load <4 x i16>* %in, align 1 + %sext = sext <4 x i16> %wide.load35 to <4 x i64> + store <4 x i64> zeroinitializer, <4 x i64>* undef, align 8 + store <4 x i64> %sext, <4 x i64>* %out, align 8 + ret void + +; AVX2: test8: +; AVX2: vpmovsxwq +} + +define void @test9(<4 x i16>* %in, <4 x i32>* %out) nounwind { + %wide.load35 = load <4 x i16>* %in, align 1 + %sext = sext <4 x i16> %wide.load35 to <4 x i32> + store <4 x i32> zeroinitializer, <4 x i32>* undef, align 8 + store <4 x i32> %sext, <4 x i32>* %out, align 8 + ret void + +; SSE41: test9: +; SSE41: pmovsxwd + +; AVX1: test9: +; AVX1: vpmovsxwd + +; AVX2: test9: +; AVX2: vpmovsxwd +} + +define void @test10(<8 x i16>* %in, <8 x i32>* %out) nounwind { + %wide.load35 = load <8 x i16>* %in, align 1 + %sext = sext <8 x i16> %wide.load35 to <8 x i32> + store <8 x i32> zeroinitializer, <8 x i32>* undef, align 8 + store <8 x i32> %sext, <8 x i32>* %out, align 8 + ret void + +; AVX2: test10: +; AVX2: vpmovsxwd +} + +define void @test11(<2 x i32>* %in, <2 x i64>* %out) nounwind { + %wide.load35 = load <2 x i32>* %in, align 1 + %sext = sext <2 x i32> %wide.load35 to <2 x i64> + store <2 x i64> zeroinitializer, <2 x i64>* undef, align 8 + store <2 x i64> %sext, <2 x i64>* %out, align 8 + ret void + +; SSE41: test11: +; SSE41: pmovsxdq + +; AVX1: test11: +; AVX1: vpmovsxdq + +; AVX2: test11: +; AVX2: vpmovsxdq +} + +define void @test12(<4 x i32>* %in, <4 x i64>* %out) nounwind { + %wide.load35 = load <4 x i32>* %in, align 1 + %sext = sext <4 x i32> %wide.load35 to <4 x i64> + store <4 x i64> zeroinitializer, <4 x i64>* undef, align 8 + store <4 x i64> %sext, <4 x i64>* %out, align 8 + ret void + +; AVX2: test12: +; AVX2: vpmovsxdq +} diff --git a/test/CodeGen/X86/pointer-vector.ll b/test/CodeGen/X86/pointer-vector.ll index 58423d1959..0ee9987526 100644 --- a/test/CodeGen/X86/pointer-vector.ll +++ b/test/CodeGen/X86/pointer-vector.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=i686-linux -mcpu=corei7 | FileCheck %s -; RUN: opt -instsimplify %s -disable-output +; RUN: opt -instsimplify -disable-output < %s ;CHECK: SHUFF0 define <8 x i32*> @SHUFF0(<4 x i32*> %ptrv) nounwind { diff --git a/test/CodeGen/X86/pr10475.ll b/test/CodeGen/X86/pr10475.ll new file mode 100644 index 0000000000..3efc39ee9f --- /dev/null +++ b/test/CodeGen/X86/pr10475.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7-avx + +; No check in a crash test + +define void @autogen_262380_1000() { +BB: + br label %CF79 + +CF79: ; preds = %CF79, %BB + br i1 undef, label %CF79, label %CF84.critedge.critedge + +CF84.critedge.critedge: ; preds = %CF79 + %L35 = load <8 x i32>* undef + br label %CF85 + +CF85: ; preds = %CF85, %CF84.critedge.critedge + br i1 undef, label %CF85, label %CF86 + +CF86: ; preds = %CF86, %CF85 + %B61 = sub <8 x i32> %L35, zeroinitializer + %S64 = icmp ne <8 x i32> %B61, zeroinitializer + %E73 = extractelement <8 x i1> %S64, i32 6 + br i1 %E73, label %CF86, label %CF87 + +CF87: ; preds = %CF87, %CF86 + br i1 undef, label %CF87, label %CF88 + +CF88: ; preds = %CF87 + ret void +} diff --git a/test/CodeGen/X86/pr10499.ll b/test/CodeGen/X86/pr10499.ll new file mode 100644 index 0000000000..f9cc747e49 --- /dev/null +++ b/test/CodeGen/X86/pr10499.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7-avx -mattr=-sse2 + +; No check as PR10499 is a crashing bug. + +define void @autogen_24438_500() { +BB: + %I = insertelement <8 x i32> undef, i32 -1, i32 4 + %BC = bitcast <8 x i32> %I to <8 x float> + br label %CF + +CF: ; preds = %CF, %BB + %ZE = fpext <8 x float> %BC to <8 x double> + br label %CF +} diff --git a/test/CodeGen/X86/pr10523.ll b/test/CodeGen/X86/pr10523.ll new file mode 100644 index 0000000000..7191d6949c --- /dev/null +++ b/test/CodeGen/X86/pr10523.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse41 + +; No check in a crash test + +define void @autogen_129334_5000() { +BB: + %I74 = insertelement <32 x i32> undef, i32 undef, i32 15 + %I105 = insertelement <32 x i32> undef, i32 undef, i32 14 + %Shuff292 = shufflevector <32 x i32> %I74, <32 x i32> undef, <32 x i32> <i32 undef, i32 12, i32 14, i32 16, i32 undef, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30, i32 undef, i32 34, i32 36, i32 38, i32 40, i32 42, i32 44, i32 46, i32 48, i32 50, i32 undef, i32 54, i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 2, i32 4, i32 6, i32 8> + %Shuff302 = shufflevector <32 x i32> %Shuff292, <32 x i32> undef, <32 x i32> <i32 27, i32 29, i32 undef, i32 33, i32 undef, i32 37, i32 39, i32 undef, i32 undef, i32 undef, i32 47, i32 undef, i32 51, i32 53, i32 55, i32 57, i32 undef, i32 undef, i32 63, i32 1, i32 undef, i32 undef, i32 undef, i32 9, i32 11, i32 13, i32 undef, i32 17, i32 19, i32 21, i32 23, i32 undef> + %I326 = insertelement <32 x i32> undef, i32 undef, i32 15 + %B338 = sub <32 x i32> zeroinitializer, %I105 + %FC339 = sitofp <32 x i32> %I326 to <32 x double> + %S341 = icmp ne <32 x i32> %B338, undef + %E376 = extractelement <32 x i1> %S341, i32 0 + %Shuff419 = shufflevector <32 x i32> undef, <32 x i32> %Shuff302, <32 x i32> <i32 undef, i32 44, i32 46, i32 48, i32 50, i32 52, i32 undef, i32 56, i32 58, i32 60, i32 62, i32 0, i32 2, i32 4, i32 6, i32 undef, i32 undef, i32 12, i32 14, i32 undef, i32 undef, i32 20, i32 22, i32 undef, i32 26, i32 28, i32 undef, i32 32, i32 34, i32 36, i32 38, i32 40> + ret void +} diff --git a/test/CodeGen/X86/pr10524.ll b/test/CodeGen/X86/pr10524.ll new file mode 100644 index 0000000000..ed3e7c5280 --- /dev/null +++ b/test/CodeGen/X86/pr10524.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse41 + +; No check in a crash test + +define void @autogen_178513_5000() { +BB: + %Shuff22 = shufflevector <2 x i32> undef, <2 x i32> zeroinitializer, <2 x i32> <i32 3, i32 1> + %B26 = sub <2 x i32> %Shuff22, zeroinitializer + %S79 = icmp eq <2 x i32> %B26, zeroinitializer + %B269 = urem <2 x i1> zeroinitializer, %S79 + %Se335 = sext <2 x i1> %B269 to <2 x i8> + store <2 x i8> %Se335, <2 x i8>* undef + ret void +} diff --git a/test/CodeGen/X86/pr10525.ll b/test/CodeGen/X86/pr10525.ll new file mode 100644 index 0000000000..342c1d63e1 --- /dev/null +++ b/test/CodeGen/X86/pr10525.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse41 + +; No check in a crash test + +define void @autogen_163411_5000() { +BB: + %L = load <2 x i64>* undef + %Shuff11 = shufflevector <2 x i64> %L, <2 x i64> %L, <2 x i32> <i32 2, i32 0> + %I51 = insertelement <2 x i64> undef, i64 undef, i32 0 + %Shuff152 = shufflevector <2 x i64> %I51, <2 x i64> %Shuff11, <2 x i32> <i32 1, i32 3> + store <2 x i64> %Shuff152, <2 x i64>* undef + ret void +} diff --git a/test/CodeGen/X86/pr10526.ll b/test/CodeGen/X86/pr10526.ll new file mode 100644 index 0000000000..6963fe5158 --- /dev/null +++ b/test/CodeGen/X86/pr10526.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse41 + +; No check in a crash test + +define void @autogen_142660_5000() { +BB: + %Shuff49 = shufflevector <8 x i32> zeroinitializer, <8 x i32> undef, <8 x i32> <i32 2, i32 4, i32 undef, i32 8, i32 10, i32 12, i32 14, i32 0> + %B85 = sub <8 x i32> %Shuff49, zeroinitializer + %S242 = icmp eq <8 x i32> zeroinitializer, %B85 + %FC284 = uitofp <8 x i1> %S242 to <8 x float> + store <8 x float> %FC284, <8 x float>* undef + ret void +} diff --git a/test/CodeGen/X86/pr11998.ll b/test/CodeGen/X86/pr11998.ll new file mode 100644 index 0000000000..1baf07924d --- /dev/null +++ b/test/CodeGen/X86/pr11998.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mcpu=corei7-avx -march=x86-64 -mattr=+avx + +define void @autogen_51367_5000(i8) { +BB: + %B = srem i8 55, %0 + %B9 = shl i8 %B, %B + br label %CF + +CF: ; preds = %CF, %BB + br i1 undef, label %CF, label %CF403 + +CF403: ; preds = %CF403, %CF + %S44 = icmp eq i8 %B9, %0 + br i1 %S44, label %CF403, label %CF405 + +CF405: ; preds = %CF405, %CF403 + br label %CF405 +} diff --git a/test/CodeGen/X86/pr14562.ll b/test/CodeGen/X86/pr14562.ll new file mode 100644 index 0000000000..e66f1752a3 --- /dev/null +++ b/test/CodeGen/X86/pr14562.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -march=x86 | FileCheck %s + +@temp1 = global i64 -77129852189294865, align 8 + +define void @foo() nounwind { + %x = load i64* @temp1, align 8 + %s = shl i64 %x, 32 + %t = trunc i64 %s to i32 + %z = zext i32 %t to i64 + store i64 %z, i64* @temp1, align 8 +; CHECK: movl $0, {{_?}}temp1+4 +; CHECK: movl $0, {{_?}}temp1 + ret void +} + diff --git a/test/CodeGen/X86/pr15267.ll b/test/CodeGen/X86/pr15267.ll new file mode 100644 index 0000000000..c8aaf327a7 --- /dev/null +++ b/test/CodeGen/X86/pr15267.ll @@ -0,0 +1,66 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7-avx | FileCheck %s + +define <4 x i3> @test1(<4 x i3>* %in) nounwind { + %ret = load <4 x i3>* %in, align 1 + ret <4 x i3> %ret +} + +; CHECK: test1 +; CHECK: movzwl +; CHECK: shrl $3 +; CHECK: andl $7 +; CHECK: andl $7 +; CHECK: vmovd +; CHECK: pinsrd $1 +; CHECK: shrl $6 +; CHECK: andl $7 +; CHECK: pinsrd $2 +; CHECK: shrl $9 +; CHECK: andl $7 +; CHECK: pinsrd $3 +; CHECK: ret + +define <4 x i1> @test2(<4 x i1>* %in) nounwind { + %ret = load <4 x i1>* %in, align 1 + ret <4 x i1> %ret +} + +; CHECK: test2 +; CHECK: movzbl +; CHECK: shrl +; CHECK: andl $1 +; CHECK: andl $1 +; CHECK: vmovd +; CHECK: pinsrd $1 +; CHECK: shrl $2 +; CHECK: andl $1 +; CHECK: pinsrd $2 +; CHECK: shrl $3 +; CHECK: andl $1 +; CHECK: pinsrd $3 +; CHECK: ret + +define <4 x i64> @test3(<4 x i1>* %in) nounwind { + %wide.load35 = load <4 x i1>* %in, align 1 + %sext = sext <4 x i1> %wide.load35 to <4 x i64> + ret <4 x i64> %sext +} + +; CHECK: test3 +; CHECK: movzbl +; CHECK: shrl +; CHECK: andl $1 +; CHECK: andl $1 +; CHECK: vmovd +; CHECK: pinsrd $1 +; CHECK: shrl $2 +; CHECK: andl $1 +; CHECK: pinsrd $2 +; CHECK: shrl $3 +; CHECK: andl $1 +; CHECK: pinsrd $3 +; CHECK: pslld +; CHECK: psrad +; CHECK: pmovsxdq +; CHECK: pmovsxdq +; CHECK: ret diff --git a/test/CodeGen/X86/pre-ra-sched.ll b/test/CodeGen/X86/pre-ra-sched.ll new file mode 100644 index 0000000000..b792ffa09f --- /dev/null +++ b/test/CodeGen/X86/pre-ra-sched.ll @@ -0,0 +1,56 @@ +; RUN: llc < %s -mtriple=x86_64-apple-macosx -debug-only=pre-RA-sched \ +; RUN: 2>&1 | FileCheck %s +; REQUIRES: asserts +; +; rdar:13279013: pre-RA-sched should not check all interferences and +; repush them on the ready queue after scheduling each instruction. +; +; CHECK: *** List Scheduling +; CHECK: Interfering reg EFLAGS +; CHECK: Repushing +; CHECK: Repushing +; CHECK: Repushing +; CHECK-NOT: Repushing +; CHECK: *** Final schedule +define i32 @test(i8* %pin) #0 { + %g0 = getelementptr inbounds i8* %pin, i64 0 + %l0 = load i8* %g0, align 1 + + %g1a = getelementptr inbounds i8* %pin, i64 1 + %l1a = load i8* %g1a, align 1 + %z1a = zext i8 %l1a to i32 + %g1b = getelementptr inbounds i8* %pin, i64 2 + %l1b = load i8* %g1b, align 1 + %z1b = zext i8 %l1b to i32 + %c1 = icmp ne i8 %l0, 0 + %x1 = xor i32 %z1a, %z1b + %s1 = select i1 %c1, i32 %z1a, i32 %x1 + + %g2a = getelementptr inbounds i8* %pin, i64 3 + %l2a = load i8* %g2a, align 1 + %z2a = zext i8 %l2a to i32 + %g2b = getelementptr inbounds i8* %pin, i64 4 + %l2b = load i8* %g2b, align 1 + %z2b = zext i8 %l2b to i32 + %x2 = xor i32 %z2a, %z2b + %s2 = select i1 %c1, i32 %z2a, i32 %x2 + + %g3a = getelementptr inbounds i8* %pin, i64 5 + %l3a = load i8* %g3a, align 1 + %z3a = zext i8 %l3a to i32 + %g3b = getelementptr inbounds i8* %pin, i64 6 + %l3b = load i8* %g3b, align 1 + %z3b = zext i8 %l3b to i32 + %x3 = xor i32 %z3a, %z3b + %s3 = select i1 %c1, i32 %z3a, i32 %x3 + + %c3 = icmp ne i8 %l1a, 0 + %c4 = icmp ne i8 %l2a, 0 + + %s4 = select i1 %c3, i32 %s1, i32 %s2 + %s5 = select i1 %c4, i32 %s4, i32 %s3 + + ret i32 %s5 +} + +attributes #0 = { nounwind ssp uwtable } diff --git a/test/CodeGen/X86/psubus.ll b/test/CodeGen/X86/psubus.ll new file mode 100644 index 0000000000..aff4afbd2e --- /dev/null +++ b/test/CodeGen/X86/psubus.ll @@ -0,0 +1,340 @@ +; RUN: llc -mcpu=core2 < %s | FileCheck %s -check-prefix=SSE2 +; RUN: llc -mcpu=corei7-avx < %s | FileCheck %s -check-prefix=AVX1 +; RUN: llc -mcpu=core-avx2 < %s | FileCheck %s -check-prefix=AVX2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +define void @test1(i16* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i16* %head, i64 %index + %1 = bitcast i16* %0 to <8 x i16>* + %2 = load <8 x i16>* %1, align 2 + %3 = icmp slt <8 x i16> %2, zeroinitializer + %4 = xor <8 x i16> %2, <i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768> + %5 = select <8 x i1> %3, <8 x i16> %4, <8 x i16> zeroinitializer + store <8 x i16> %5, <8 x i16>* %1, align 2 + %index.next = add i64 %index, 8 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test1 +; SSE2: psubusw LCPI0_0(%rip), %xmm0 + +; AVX1: @test1 +; AVX1: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0 + +; AVX2: @test1 +; AVX2: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0 +} + +define void @test2(i16* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i16* %head, i64 %index + %1 = bitcast i16* %0 to <8 x i16>* + %2 = load <8 x i16>* %1, align 2 + %3 = icmp ugt <8 x i16> %2, <i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766> + %4 = add <8 x i16> %2, <i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767> + %5 = select <8 x i1> %3, <8 x i16> %4, <8 x i16> zeroinitializer + store <8 x i16> %5, <8 x i16>* %1, align 2 + %index.next = add i64 %index, 8 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test2 +; SSE2: psubusw LCPI1_0(%rip), %xmm0 + +; AVX1: @test2 +; AVX1: vpsubusw LCPI1_0(%rip), %xmm0, %xmm0 + +; AVX2: @test2 +; AVX2: vpsubusw LCPI1_0(%rip), %xmm0, %xmm0 +} + +define void @test3(i16* nocapture %head, i16 zeroext %w) nounwind { +vector.ph: + %0 = insertelement <8 x i16> undef, i16 %w, i32 0 + %broadcast15 = shufflevector <8 x i16> %0, <8 x i16> undef, <8 x i32> zeroinitializer + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %1 = getelementptr inbounds i16* %head, i64 %index + %2 = bitcast i16* %1 to <8 x i16>* + %3 = load <8 x i16>* %2, align 2 + %4 = icmp ult <8 x i16> %3, %broadcast15 + %5 = sub <8 x i16> %3, %broadcast15 + %6 = select <8 x i1> %4, <8 x i16> zeroinitializer, <8 x i16> %5 + store <8 x i16> %6, <8 x i16>* %2, align 2 + %index.next = add i64 %index, 8 + %7 = icmp eq i64 %index.next, 16384 + br i1 %7, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test3 +; SSE2: psubusw %xmm0, %xmm1 + +; AVX1: @test3 +; AVX1: vpsubusw %xmm0, %xmm1, %xmm1 + +; AVX2: @test3 +; AVX2: vpsubusw %xmm0, %xmm1, %xmm1 +} + +define void @test4(i8* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i8* %head, i64 %index + %1 = bitcast i8* %0 to <16 x i8>* + %2 = load <16 x i8>* %1, align 1 + %3 = icmp slt <16 x i8> %2, zeroinitializer + %4 = xor <16 x i8> %2, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128> + %5 = select <16 x i1> %3, <16 x i8> %4, <16 x i8> zeroinitializer + store <16 x i8> %5, <16 x i8>* %1, align 1 + %index.next = add i64 %index, 16 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test4 +; SSE2: psubusb LCPI3_0(%rip), %xmm0 + +; AVX1: @test4 +; AVX1: vpsubusb LCPI3_0(%rip), %xmm0, %xmm0 + +; AVX2: @test4 +; AVX2: vpsubusb LCPI3_0(%rip), %xmm0, %xmm0 +} + +define void @test5(i8* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i8* %head, i64 %index + %1 = bitcast i8* %0 to <16 x i8>* + %2 = load <16 x i8>* %1, align 1 + %3 = icmp ugt <16 x i8> %2, <i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126> + %4 = add <16 x i8> %2, <i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127> + %5 = select <16 x i1> %3, <16 x i8> %4, <16 x i8> zeroinitializer + store <16 x i8> %5, <16 x i8>* %1, align 1 + %index.next = add i64 %index, 16 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test5 +; SSE2: psubusb LCPI4_0(%rip), %xmm0 + +; AVX1: @test5 +; AVX1: vpsubusb LCPI4_0(%rip), %xmm0, %xmm0 + +; AVX2: @test5 +; AVX2: vpsubusb LCPI4_0(%rip), %xmm0, %xmm0 +} + +define void @test6(i8* nocapture %head, i8 zeroext %w) nounwind { +vector.ph: + %0 = insertelement <16 x i8> undef, i8 %w, i32 0 + %broadcast15 = shufflevector <16 x i8> %0, <16 x i8> undef, <16 x i32> zeroinitializer + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %1 = getelementptr inbounds i8* %head, i64 %index + %2 = bitcast i8* %1 to <16 x i8>* + %3 = load <16 x i8>* %2, align 1 + %4 = icmp ult <16 x i8> %3, %broadcast15 + %5 = sub <16 x i8> %3, %broadcast15 + %6 = select <16 x i1> %4, <16 x i8> zeroinitializer, <16 x i8> %5 + store <16 x i8> %6, <16 x i8>* %2, align 1 + %index.next = add i64 %index, 16 + %7 = icmp eq i64 %index.next, 16384 + br i1 %7, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: @test6 +; SSE2: psubusb %xmm0, %xmm1 + +; AVX1: @test6 +; AVX1: vpsubusb %xmm0, %xmm1, %xmm1 + +; AVX2: @test6 +; AVX2: vpsubusb %xmm0, %xmm1, %xmm1 +} + +define void @test7(i16* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i16* %head, i64 %index + %1 = bitcast i16* %0 to <16 x i16>* + %2 = load <16 x i16>* %1, align 2 + %3 = icmp slt <16 x i16> %2, zeroinitializer + %4 = xor <16 x i16> %2, <i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768, i16 -32768> + %5 = select <16 x i1> %3, <16 x i16> %4, <16 x i16> zeroinitializer + store <16 x i16> %5, <16 x i16>* %1, align 2 + %index.next = add i64 %index, 8 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: @test7 +; AVX2: vpsubusw LCPI6_0(%rip), %ymm0, %ymm0 +} + +define void @test8(i16* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i16* %head, i64 %index + %1 = bitcast i16* %0 to <16 x i16>* + %2 = load <16 x i16>* %1, align 2 + %3 = icmp ugt <16 x i16> %2, <i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766> + %4 = add <16 x i16> %2, <i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767, i16 -32767> + %5 = select <16 x i1> %3, <16 x i16> %4, <16 x i16> zeroinitializer + store <16 x i16> %5, <16 x i16>* %1, align 2 + %index.next = add i64 %index, 8 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: @test8 +; AVX2: vpsubusw LCPI7_0(%rip), %ymm0, %ymm0 +} + +define void @test9(i16* nocapture %head, i16 zeroext %w) nounwind { +vector.ph: + %0 = insertelement <16 x i16> undef, i16 %w, i32 0 + %broadcast15 = shufflevector <16 x i16> %0, <16 x i16> undef, <16 x i32> zeroinitializer + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %1 = getelementptr inbounds i16* %head, i64 %index + %2 = bitcast i16* %1 to <16 x i16>* + %3 = load <16 x i16>* %2, align 2 + %4 = icmp ult <16 x i16> %3, %broadcast15 + %5 = sub <16 x i16> %3, %broadcast15 + %6 = select <16 x i1> %4, <16 x i16> zeroinitializer, <16 x i16> %5 + store <16 x i16> %6, <16 x i16>* %2, align 2 + %index.next = add i64 %index, 8 + %7 = icmp eq i64 %index.next, 16384 + br i1 %7, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + + +; AVX2: @test9 +; AVX2: vpsubusw %ymm0, %ymm1, %ymm1 +} + +define void @test10(i8* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i8* %head, i64 %index + %1 = bitcast i8* %0 to <32 x i8>* + %2 = load <32 x i8>* %1, align 1 + %3 = icmp slt <32 x i8> %2, zeroinitializer + %4 = xor <32 x i8> %2, <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128> + %5 = select <32 x i1> %3, <32 x i8> %4, <32 x i8> zeroinitializer + store <32 x i8> %5, <32 x i8>* %1, align 1 + %index.next = add i64 %index, 16 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + + +; AVX2: @test10 +; AVX2: vpsubusb LCPI9_0(%rip), %ymm0, %ymm0 +} + +define void @test11(i8* nocapture %head) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %0 = getelementptr inbounds i8* %head, i64 %index + %1 = bitcast i8* %0 to <32 x i8>* + %2 = load <32 x i8>* %1, align 1 + %3 = icmp ugt <32 x i8> %2, <i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126, i8 126> + %4 = add <32 x i8> %2, <i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127, i8 -127> + %5 = select <32 x i1> %3, <32 x i8> %4, <32 x i8> zeroinitializer + store <32 x i8> %5, <32 x i8>* %1, align 1 + %index.next = add i64 %index, 16 + %6 = icmp eq i64 %index.next, 16384 + br i1 %6, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: @test11 +; AVX2: vpsubusb LCPI10_0(%rip), %ymm0, %ymm0 +} + +define void @test12(i8* nocapture %head, i8 zeroext %w) nounwind { +vector.ph: + %0 = insertelement <32 x i8> undef, i8 %w, i32 0 + %broadcast15 = shufflevector <32 x i8> %0, <32 x i8> undef, <32 x i32> zeroinitializer + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %1 = getelementptr inbounds i8* %head, i64 %index + %2 = bitcast i8* %1 to <32 x i8>* + %3 = load <32 x i8>* %2, align 1 + %4 = icmp ult <32 x i8> %3, %broadcast15 + %5 = sub <32 x i8> %3, %broadcast15 + %6 = select <32 x i1> %4, <32 x i8> zeroinitializer, <32 x i8> %5 + store <32 x i8> %6, <32 x i8>* %2, align 1 + %index.next = add i64 %index, 16 + %7 = icmp eq i64 %index.next, 16384 + br i1 %7, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: @test12 +; AVX2: vpsubusb %ymm0, %ymm1, %ymm1 +} diff --git a/test/CodeGen/X86/ret-mmx.ll b/test/CodeGen/X86/ret-mmx.ll index 865e147a4a..778e4722cd 100644 --- a/test/CodeGen/X86/ret-mmx.ll +++ b/test/CodeGen/X86/ret-mmx.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin11 -mattr=+mmx,+sse2 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin11 -mcpu=core2 -mattr=+mmx,+sse2 | FileCheck %s ; rdar://6602459 @g_v1di = external global <1 x i64> diff --git a/test/CodeGen/X86/rip-rel-lea.ll b/test/CodeGen/X86/rip-rel-lea.ll new file mode 100644 index 0000000000..71dacf60ca --- /dev/null +++ b/test/CodeGen/X86/rip-rel-lea.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -relocation-model=pic | FileCheck %s -check-prefix=PIC64 +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 -relocation-model=pic | FileCheck %s -check-prefix=PICX32 +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s -check-prefix=PIC32 + +; Use %rip-relative addressing even in static mode on x86-64, because +; it has a smaller encoding. + +@a = internal global double 3.4 +define double* @foo() nounwind { + %a = getelementptr double* @a, i64 0 + ret double* %a + +; PIC64: leaq a(%rip) +; PICX32: leal a(%rip) +; PIC32: leal a@GOTOFF(%eax) +} diff --git a/test/CodeGen/X86/sandybridge-loads.ll b/test/CodeGen/X86/sandybridge-loads.ll new file mode 100644 index 0000000000..5a23cf136d --- /dev/null +++ b/test/CodeGen/X86/sandybridge-loads.ll @@ -0,0 +1,39 @@ +; RUN: llc -march=x86-64 -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -o - < %s | FileCheck %s + +;CHECK: wideloads +;CHECK: vmovaps +;CHECK: vinsertf128 +;CHECK: vmovaps +;CHECK-NOT: vinsertf128 +;CHECK: ret + +define void @wideloads(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwind uwtable noinline ssp { + %v0 = load <8 x float>* %a, align 16 ; <---- unaligned! + %v1 = load <8 x float>* %b, align 32 ; <---- aligned! + %m0 = fcmp olt <8 x float> %v1, %v0 + %v2 = load <8 x float>* %c, align 32 ; <---- aligned! + %m1 = fcmp olt <8 x float> %v2, %v0 + %mand = and <8 x i1> %m1, %m0 + %r = zext <8 x i1> %mand to <8 x i32> + store <8 x i32> %r, <8 x i32>* undef, align 32 + ret void +} + +; CHECK: widestores +; loads: +; CHECK: vmovaps +; CHECK: vmovaps +; stores: +; CHECK: vmovaps +; CHECK: vextractf128 +; CHECK: vmovaps +;CHECK: ret + +define void @widestores(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwind uwtable noinline ssp { + %v0 = load <8 x float>* %a, align 32 + %v1 = load <8 x float>* %b, align 32 + store <8 x float> %v0, <8 x float>* %b, align 32 ; <--- aligned + store <8 x float> %v1, <8 x float>* %a, align 16 ; <--- unaligned + ret void +} + diff --git a/test/CodeGen/X86/select.ll b/test/CodeGen/X86/select.ll index 3bec3acdbf..09ca07b31a 100644 --- a/test/CodeGen/X86/select.ll +++ b/test/CodeGen/X86/select.ll @@ -282,7 +282,7 @@ define i32 @test13(i32 %a, i32 %b) nounwind { ; ATOM: test13: ; ATOM: cmpl ; ATOM-NEXT: sbbl -; ATOM-NEXT: ret +; ATOM: ret } define i32 @test14(i32 %a, i32 %b) nounwind { @@ -299,7 +299,7 @@ define i32 @test14(i32 %a, i32 %b) nounwind { ; ATOM: cmpl ; ATOM-NEXT: sbbl ; ATOM-NEXT: notl -; ATOM-NEXT: ret +; ATOM: ret } ; rdar://10961709 diff --git a/test/CodeGen/X86/sincos-opt.ll b/test/CodeGen/X86/sincos-opt.ll new file mode 100644 index 0000000000..f364d1fc2d --- /dev/null +++ b/test/CodeGen/X86/sincos-opt.ll @@ -0,0 +1,66 @@ +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_SINCOS +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 | FileCheck %s --check-prefix=OSX_NOOPT +; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mcpu=core2 -enable-unsafe-fp-math | FileCheck %s --check-prefix=GNU_SINCOS + +; Combine sin / cos into a single call. +; rdar://13087969 + +define float @test1(float %x) nounwind { +entry: +; GNU_SINCOS: test1: +; GNU_SINCOS: callq sincosf +; GNU_SINCOS: movss 4(%rsp), %xmm0 +; GNU_SINCOS: addss (%rsp), %xmm0 + +; OSX_SINCOS: test1: +; OSX_SINCOS: callq ___sincosf_stret +; OSX_SINCOS: addss %xmm1, %xmm0 + +; OSX_NOOPT: test1 +; OSX_NOOPT: callq _cosf +; OSX_NOOPT: callq _sinf + %call = tail call float @sinf(float %x) nounwind readnone + %call1 = tail call float @cosf(float %x) nounwind readnone + %add = fadd float %call, %call1 + ret float %add +} + +define double @test2(double %x) nounwind { +entry: +; GNU_SINCOS: test2: +; GNU_SINCOS: callq sincos +; GNU_SINCOS: movsd 16(%rsp), %xmm0 +; GNU_SINCOS: addsd 8(%rsp), %xmm0 + +; OSX_SINCOS: test2: +; OSX_SINCOS: callq ___sincos_stret +; OSX_SINCOS: addsd %xmm1, %xmm0 + +; OSX_NOOPT: test2 +; OSX_NOOPT: callq _cos +; OSX_NOOPT: callq _sin + %call = tail call double @sin(double %x) nounwind readnone + %call1 = tail call double @cos(double %x) nounwind readnone + %add = fadd double %call, %call1 + ret double %add +} + +define x86_fp80 @test3(x86_fp80 %x) nounwind { +entry: +; GNU_SINCOS: test3: +; GNU_SINCOS: callq sinl +; GNU_SINCOS: callq cosl +; GNU_SINCOS: ret + %call = tail call x86_fp80 @sinl(x86_fp80 %x) nounwind + %call1 = tail call x86_fp80 @cosl(x86_fp80 %x) nounwind + %add = fadd x86_fp80 %call, %call1 + ret x86_fp80 %add +} + +declare float @sinf(float) readonly +declare double @sin(double) readonly +declare float @cosf(float) readonly +declare double @cos(double) readonly + +declare x86_fp80 @sinl(x86_fp80) +declare x86_fp80 @cosl(x86_fp80) diff --git a/test/CodeGen/X86/sse-align-2.ll b/test/CodeGen/X86/sse-align-2.ll index 102c3fb06c..22cd772306 100644 --- a/test/CodeGen/X86/sse-align-2.ll +++ b/test/CodeGen/X86/sse-align-2.ll @@ -1,12 +1,21 @@ -; RUN: llc < %s -march=x86-64 | grep movup | count 2 +; RUN: llc < %s -march=x86-64 -mcpu=penryn | FileCheck %s define <4 x float> @foo(<4 x float>* %p, <4 x float> %x) nounwind { %t = load <4 x float>* %p, align 4 %z = fmul <4 x float> %t, %x ret <4 x float> %z } + +; CHECK: foo: +; CHECK: movups +; CHECK: ret + define <2 x double> @bar(<2 x double>* %p, <2 x double> %x) nounwind { %t = load <2 x double>* %p, align 8 %z = fmul <2 x double> %t, %x ret <2 x double> %z } + +; CHECK: bar: +; CHECK: movupd +; CHECK: ret diff --git a/test/CodeGen/X86/sse-domains.ll b/test/CodeGen/X86/sse-domains.ll index c99287bdfb..168959a5d6 100644 --- a/test/CodeGen/X86/sse-domains.ll +++ b/test/CodeGen/X86/sse-domains.ll @@ -55,10 +55,10 @@ while.end: ; instructions, they are still dependent on themselves. ; CHECK: xorps [[XMM1:%xmm[0-9]+]] ; CHECK: , [[XMM1]] -; CHECK: cvtsi2ss %{{.*}}, [[XMM1]] +; CHECK: cvtsi2ssl %{{.*}}, [[XMM1]] ; CHECK: xorps [[XMM2:%xmm[0-9]+]] ; CHECK: , [[XMM2]] -; CHECK: cvtsi2ss %{{.*}}, [[XMM2]] +; CHECK: cvtsi2ssl %{{.*}}, [[XMM2]] ; define float @f2(i32 %m) nounwind uwtable readnone ssp { entry: diff --git a/test/CodeGen/X86/sse2-blend.ll b/test/CodeGen/X86/sse2-blend.ll index 67ce1be135..30a0fbe7d6 100644 --- a/test/CodeGen/X86/sse2-blend.ll +++ b/test/CodeGen/X86/sse2-blend.ll @@ -29,7 +29,6 @@ define void@vsel_i32(<4 x i32>* %v1, <4 x i32>* %v2) { ; Without forcing instructions, fall back to the preferred PS domain. ; CHECK: vsel_i64 ; CHECK: andnps -; CHECK: andps ; CHECK: orps ; CHECK: ret @@ -44,7 +43,6 @@ define void@vsel_i64(<2 x i64>* %v1, <2 x i64>* %v2) { ; Without forcing instructions, fall back to the preferred PS domain. ; CHECK: vsel_double ; CHECK: andnps -; CHECK: andps ; CHECK: orps ; CHECK: ret diff --git a/test/CodeGen/X86/sse2-mul.ll b/test/CodeGen/X86/sse2-mul.ll new file mode 100644 index 0000000000..0466d60ec3 --- /dev/null +++ b/test/CodeGen/X86/sse2-mul.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86-64 -mcpu=core2 | FileCheck %s + +define <4 x i32> @test1(<4 x i32> %x, <4 x i32> %y) { + %m = mul <4 x i32> %x, %y + ret <4 x i32> %m +; CHECK: test1: +; CHECK: pshufd $49 +; CHECK: pmuludq +; CHECK: pshufd $49 +; CHECK: pmuludq +; CHECK: shufps $-120 +; CHECK: pshufd $-40 +; CHECK: ret +} diff --git a/test/CodeGen/X86/stack-align-memcpy.ll b/test/CodeGen/X86/stack-align-memcpy.ll new file mode 100644 index 0000000000..74945e5bb1 --- /dev/null +++ b/test/CodeGen/X86/stack-align-memcpy.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -force-align-stack -mtriple i386-apple-darwin -mcpu=i486 | FileCheck %s + +%struct.foo = type { [88 x i8] } + +; PR15249 +; We can't use rep;movsl here because it clobbers the base pointer in %esi. +define void @test1(%struct.foo* nocapture %x, i32 %y) nounwind { + %dynalloc = alloca i8, i32 %y, align 1 + call void @bar(i8* %dynalloc, %struct.foo* align 4 byval %x) + ret void + +; CHECK: test1: +; CHECK: andl $-16, %esp +; CHECK: movl %esp, %esi +; CHECK-NOT: rep;movsl +} + +declare void @bar(i8* nocapture, %struct.foo* align 4 byval) nounwind diff --git a/test/CodeGen/X86/stack-protector.ll b/test/CodeGen/X86/stack-protector.ll index c07511443b..1e9ca1d2c2 100644 --- a/test/CodeGen/X86/stack-protector.ll +++ b/test/CodeGen/X86/stack-protector.ll @@ -1,28 +1,3141 @@ -; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | grep %gs: -; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %fs: -; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %gs: -; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep "__stack_chk_guard" -; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep "__stack_chk_fail" +; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-I386 %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s +; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s +; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s -@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1] +%struct.foo = type { [16 x i8] } +%struct.foo.0 = type { [4 x i8] } +%struct.pair = type { i32, i32 } +%struct.nest = type { %struct.pair, %struct.pair } +%struct.vec = type { <4 x i32> } +%class.A = type { [2 x i8] } +%struct.deep = type { %union.anon } +%union.anon = type { %struct.anon } +%struct.anon = type { %struct.anon.0 } +%struct.anon.0 = type { %union.anon.1 } +%union.anon.1 = type { [2 x i8] } +%struct.small = type { i8 } -define void @test(i8* %a) nounwind ssp { +@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 + +; test1a: array of [16 x i8] +; no ssp attribute +; Requires no protector. +define void @test1a(i8* %a) nounwind uwtable { +entry: +; LINUX-I386: test1a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test1a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test1a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test1a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %buf = alloca [16 x i8], align 16 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test1b: array of [16 x i8] +; ssp attribute +; Requires protector. +define void @test1b(i8* %a) nounwind uwtable ssp { +entry: +; LINUX-I386: test1b: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test1b: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test1b: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test1b: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %buf = alloca [16 x i8], align 16 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test1c: array of [16 x i8] +; sspstrong attribute +; Requires protector. +define void @test1c(i8* %a) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test1c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test1c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test1c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test1c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %buf = alloca [16 x i8], align 16 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test1d: array of [16 x i8] +; sspreq attribute +; Requires protector. +define void @test1d(i8* %a) nounwind uwtable sspreq { +entry: +; LINUX-I386: test1d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test1d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test1d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test1d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %buf = alloca [16 x i8], align 16 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test2a: struct { [16 x i8] } +; no ssp attribute +; Requires no protector. +define void @test2a(i8* %a) nounwind uwtable { +entry: +; LINUX-I386: test2a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test2a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test2a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test2a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test2b: struct { [16 x i8] } +; ssp attribute +; Requires protector. +define void @test2b(i8* %a) nounwind uwtable ssp { +entry: +; LINUX-I386: test2b: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test2b: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test2b: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test2b: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test2c: struct { [16 x i8] } +; sspstrong attribute +; Requires protector. +define void @test2c(i8* %a) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test2c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test2c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test2c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test2c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test2d: struct { [16 x i8] } +; sspreq attribute +; Requires protector. +define void @test2d(i8* %a) nounwind uwtable sspreq { +entry: +; LINUX-I386: test2d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test2d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test2d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test2d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test3a: array of [4 x i8] +; no ssp attribute +; Requires no protector. +define void @test3a(i8* %a) nounwind uwtable { +entry: +; LINUX-I386: test3a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test3a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test3a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test3a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %buf = alloca [4 x i8], align 1 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test3b: array [4 x i8] +; ssp attribute +; Requires no protector. +define void @test3b(i8* %a) nounwind uwtable ssp { +entry: +; LINUX-I386: test3b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test3b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test3b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test3b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %buf = alloca [4 x i8], align 1 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test3c: array of [4 x i8] +; sspstrong attribute +; Requires protector. +define void @test3c(i8* %a) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test3c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test3c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test3c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test3c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %buf = alloca [4 x i8], align 1 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test3d: array of [4 x i8] +; sspreq attribute +; Requires protector. +define void @test3d(i8* %a) nounwind uwtable sspreq { +entry: +; LINUX-I386: test3d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test3d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test3d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test3d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %buf = alloca [4 x i8], align 1 + store i8* %a, i8** %a.addr, align 8 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1) + ret void +} + +; test4a: struct { [4 x i8] } +; no ssp attribute +; Requires no protector. +define void @test4a(i8* %a) nounwind uwtable { +entry: +; LINUX-I386: test4a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test4a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test4a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test4a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo.0, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test4b: struct { [4 x i8] } +; ssp attribute +; Requires no protector. +define void @test4b(i8* %a) nounwind uwtable ssp { +entry: +; LINUX-I386: test4b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test4b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test4b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test4b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo.0, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test4c: struct { [4 x i8] } +; sspstrong attribute +; Requires protector. +define void @test4c(i8* %a) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test4c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test4c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test4c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test4c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo.0, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test4d: struct { [4 x i8] } +; sspreq attribute +; Requires protector. +define void @test4d(i8* %a) nounwind uwtable sspreq { +entry: +; LINUX-I386: test4d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test4d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test4d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test4d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + %b = alloca %struct.foo.0, align 1 + store i8* %a, i8** %a.addr, align 8 + %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0 + %0 = load i8** %a.addr, align 8 + %call = call i8* @strcpy(i8* %arraydecay, i8* %0) + %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0 + %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2) + ret void +} + +; test5a: no arrays / no nested arrays +; no ssp attribute +; Requires no protector. +define void @test5a(i8* %a) nounwind uwtable { +entry: +; LINUX-I386: test5a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test5a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test5a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test5a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + store i8* %a, i8** %a.addr, align 8 + %0 = load i8** %a.addr, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0) + ret void +} + +; test5b: no arrays / no nested arrays +; ssp attribute +; Requires no protector. +define void @test5b(i8* %a) nounwind uwtable ssp { +entry: +; LINUX-I386: test5b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test5b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test5b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test5b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + store i8* %a, i8** %a.addr, align 8 + %0 = load i8** %a.addr, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0) + ret void +} + +; test5c: no arrays / no nested arrays +; sspstrong attribute +; Requires no protector. +define void @test5c(i8* %a) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test5c: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test5c: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test5c: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test5c: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a.addr = alloca i8*, align 8 + store i8* %a, i8** %a.addr, align 8 + %0 = load i8** %a.addr, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0) + ret void +} + +; test5d: no arrays / no nested arrays +; sspreq attribute +; Requires protector. +define void @test5d(i8* %a) nounwind uwtable sspreq { +entry: +; LINUX-I386: test5d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test5d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test5d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test5d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a.addr = alloca i8*, align 8 + store i8* %a, i8** %a.addr, align 8 + %0 = load i8** %a.addr, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0) + ret void +} + +; test6a: Address-of local taken (j = &a) +; no ssp attribute +; Requires no protector. +define void @test6a() nounwind uwtable { +entry: +; LINUX-I386: test6a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test6a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test6a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test6a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %retval = alloca i32, align 4 + %a = alloca i32, align 4 + %j = alloca i32*, align 8 + store i32 0, i32* %retval + %0 = load i32* %a, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %a, align 4 + store i32* %a, i32** %j, align 8 + ret void +} + +; test6b: Address-of local taken (j = &a) +; ssp attribute +; Requires no protector. +define void @test6b() nounwind uwtable ssp { +entry: +; LINUX-I386: test6b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test6b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test6b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test6b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %retval = alloca i32, align 4 + %a = alloca i32, align 4 + %j = alloca i32*, align 8 + store i32 0, i32* %retval + %0 = load i32* %a, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %a, align 4 + store i32* %a, i32** %j, align 8 + ret void +} + +; test6c: Address-of local taken (j = &a) +; sspstrong attribute +; Requires protector. +define void @test6c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test6c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test6c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test6c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test6c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %retval = alloca i32, align 4 + %a = alloca i32, align 4 + %j = alloca i32*, align 8 + store i32 0, i32* %retval + %0 = load i32* %a, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %a, align 4 + store i32* %a, i32** %j, align 8 + ret void +} + +; test6d: Address-of local taken (j = &a) +; sspreq attribute +; Requires protector. +define void @test6d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test6d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test6d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test6d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test6d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %retval = alloca i32, align 4 + %a = alloca i32, align 4 + %j = alloca i32*, align 8 + store i32 0, i32* %retval + %0 = load i32* %a, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %a, align 4 + store i32* %a, i32** %j, align 8 + ret void +} + +; test7a: PtrToInt Cast +; no ssp attribute +; Requires no protector. +define void @test7a() nounwind uwtable readnone { +entry: +; LINUX-I386: test7a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test7a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test7a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test7a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %0 = ptrtoint i32* %a to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test7b: PtrToInt Cast +; ssp attribute +; Requires no protector. +define void @test7b() nounwind uwtable readnone ssp { +entry: +; LINUX-I386: test7b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test7b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test7b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test7b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %0 = ptrtoint i32* %a to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test7c: PtrToInt Cast +; sspstrong attribute +; Requires protector. +define void @test7c() nounwind uwtable readnone sspstrong { +entry: +; LINUX-I386: test7c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test7c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test7c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test7c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %0 = ptrtoint i32* %a to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test7d: PtrToInt Cast +; sspreq attribute +; Requires protector. +define void @test7d() nounwind uwtable readnone sspreq { +entry: +; LINUX-I386: test7d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test7d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test7d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test7d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %0 = ptrtoint i32* %a to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test8a: Passing addr-of to function call +; no ssp attribute +; Requires no protector. +define void @test8a() nounwind uwtable { +entry: +; LINUX-I386: test8a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test8a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test8a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test8a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %b = alloca i32, align 4 + call void @funcall(i32* %b) nounwind + ret void +} + +; test8b: Passing addr-of to function call +; ssp attribute +; Requires no protector. +define void @test8b() nounwind uwtable ssp { +entry: +; LINUX-I386: test8b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test8b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test8b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test8b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %b = alloca i32, align 4 + call void @funcall(i32* %b) nounwind + ret void +} + +; test8c: Passing addr-of to function call +; sspstrong attribute +; Requires protector. +define void @test8c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test8c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test8c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test8c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test8c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %b = alloca i32, align 4 + call void @funcall(i32* %b) nounwind + ret void +} + +; test8d: Passing addr-of to function call +; sspreq attribute +; Requires protector. +define void @test8d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test8d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test8d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test8d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test8d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %b = alloca i32, align 4 + call void @funcall(i32* %b) nounwind + ret void +} + +; test9a: Addr-of in select instruction +; no ssp attribute +; Requires no protector. +define void @test9a() nounwind uwtable { +entry: +; LINUX-I386: test9a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test9a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test9a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test9a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp2 = fcmp ogt double %call, 0.000000e+00 + %y.1 = select i1 %cmp2, double* %x, double* null + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1) + ret void +} + +; test9b: Addr-of in select instruction +; ssp attribute +; Requires no protector. +define void @test9b() nounwind uwtable ssp { +entry: +; LINUX-I386: test9b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test9b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test9b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test9b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp2 = fcmp ogt double %call, 0.000000e+00 + %y.1 = select i1 %cmp2, double* %x, double* null + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1) + ret void +} + +; test9c: Addr-of in select instruction +; sspstrong attribute +; Requires protector. +define void @test9c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test9c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test9c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test9c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test9c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp2 = fcmp ogt double %call, 0.000000e+00 + %y.1 = select i1 %cmp2, double* %x, double* null + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1) + ret void +} + +; test9d: Addr-of in select instruction +; sspreq attribute +; Requires protector. +define void @test9d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test9d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test9d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test9d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test9d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp2 = fcmp ogt double %call, 0.000000e+00 + %y.1 = select i1 %cmp2, double* %x, double* null + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1) + ret void +} + +; test10a: Addr-of in phi instruction +; no ssp attribute +; Requires no protector. +define void @test10a() nounwind uwtable { +entry: +; LINUX-I386: test10a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test10a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test10a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test10a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp = fcmp ogt double %call, 3.140000e+00 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %call1 = call double @testi_aux() nounwind + store double %call1, double* %x, align 8 + br label %if.end4 + +if.else: ; preds = %entry + %cmp2 = fcmp ogt double %call, 1.000000e+00 + br i1 %cmp2, label %if.then3, label %if.end4 + +if.then3: ; preds = %if.else + br label %if.end4 + +if.end4: ; preds = %if.else, %if.then3, %if.then + %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ] + %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind + ret void +} + +; test10b: Addr-of in phi instruction +; ssp attribute +; Requires no protector. +define void @test10b() nounwind uwtable ssp { +entry: +; LINUX-I386: test10b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test10b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test10b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test10b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp = fcmp ogt double %call, 3.140000e+00 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %call1 = call double @testi_aux() nounwind + store double %call1, double* %x, align 8 + br label %if.end4 + +if.else: ; preds = %entry + %cmp2 = fcmp ogt double %call, 1.000000e+00 + br i1 %cmp2, label %if.then3, label %if.end4 + +if.then3: ; preds = %if.else + br label %if.end4 + +if.end4: ; preds = %if.else, %if.then3, %if.then + %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ] + %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind + ret void +} + +; test10c: Addr-of in phi instruction +; sspstrong attribute +; Requires protector. +define void @test10c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test10c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test10c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test10c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test10c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp = fcmp ogt double %call, 3.140000e+00 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %call1 = call double @testi_aux() nounwind + store double %call1, double* %x, align 8 + br label %if.end4 + +if.else: ; preds = %entry + %cmp2 = fcmp ogt double %call, 1.000000e+00 + br i1 %cmp2, label %if.then3, label %if.end4 + +if.then3: ; preds = %if.else + br label %if.end4 + +if.end4: ; preds = %if.else, %if.then3, %if.then + %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ] + %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind + ret void +} + +; test10d: Addr-of in phi instruction +; sspreq attribute +; Requires protector. +define void @test10d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test10d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test10d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test10d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test10d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca double, align 8 + %call = call double @testi_aux() nounwind + store double %call, double* %x, align 8 + %cmp = fcmp ogt double %call, 3.140000e+00 + br i1 %cmp, label %if.then, label %if.else + +if.then: ; preds = %entry + %call1 = call double @testi_aux() nounwind + store double %call1, double* %x, align 8 + br label %if.end4 + +if.else: ; preds = %entry + %cmp2 = fcmp ogt double %call, 1.000000e+00 + br i1 %cmp2, label %if.then3, label %if.end4 + +if.then3: ; preds = %if.else + br label %if.end4 + +if.end4: ; preds = %if.else, %if.then3, %if.then + %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ] + %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind + ret void +} + +; test11a: Addr-of struct element. (GEP followed by store). +; no ssp attribute +; Requires no protector. +define void @test11a() nounwind uwtable { +entry: +; LINUX-I386: test11a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test11a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test11a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test11a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + store i32* %y, i32** %b, align 8 + %0 = load i32** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0) + ret void +} + +; test11b: Addr-of struct element. (GEP followed by store). +; ssp attribute +; Requires no protector. +define void @test11b() nounwind uwtable ssp { +entry: +; LINUX-I386: test11b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test11b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test11b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test11b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + store i32* %y, i32** %b, align 8 + %0 = load i32** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0) + ret void +} + +; test11c: Addr-of struct element. (GEP followed by store). +; sspstrong attribute +; Requires protector. +define void @test11c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test11c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test11c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test11c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test11c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + store i32* %y, i32** %b, align 8 + %0 = load i32** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0) + ret void +} + +; test11d: Addr-of struct element. (GEP followed by store). +; sspreq attribute +; Requires protector. +define void @test11d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test11d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test11d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test11d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test11d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + store i32* %y, i32** %b, align 8 + %0 = load i32** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0) + ret void +} + +; test12a: Addr-of struct element, GEP followed by ptrtoint. +; no ssp attribute +; Requires no protector. +define void @test12a() nounwind uwtable { +entry: +; LINUX-I386: test12a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test12a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test12a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test12a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + %0 = ptrtoint i32* %y to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test12b: Addr-of struct element, GEP followed by ptrtoint. +; ssp attribute +; Requires no protector. +define void @test12b() nounwind uwtable ssp { +entry: +; LINUX-I386: test12b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test12b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test12b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test12b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + %0 = ptrtoint i32* %y to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test12c: Addr-of struct element, GEP followed by ptrtoint. +; sspstrong attribute +; Requires protector. +define void @test12c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test12c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test12c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test12c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test12c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + %0 = ptrtoint i32* %y to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test12d: Addr-of struct element, GEP followed by ptrtoint. +; sspreq attribute +; Requires protector. +define void @test12d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test12d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test12d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test12d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test12d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %b = alloca i32*, align 8 + %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1 + %0 = ptrtoint i32* %y to i64 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0) + ret void +} + +; test13a: Addr-of struct element, GEP followed by callinst. +; no ssp attribute +; Requires no protector. +define void @test13a() nounwind uwtable { +entry: +; LINUX-I386: test13a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test13a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test13a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test13a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind + ret void +} + +; test13b: Addr-of struct element, GEP followed by callinst. +; ssp attribute +; Requires no protector. +define void @test13b() nounwind uwtable ssp { +entry: +; LINUX-I386: test13b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test13b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test13b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test13b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind + ret void +} + +; test13c: Addr-of struct element, GEP followed by callinst. +; sspstrong attribute +; Requires protector. +define void @test13c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test13c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test13c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test13c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test13c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind + ret void +} + +; test13d: Addr-of struct element, GEP followed by callinst. +; sspreq attribute +; Requires protector. +define void @test13d() nounwind uwtable sspreq { entry: - %a_addr = alloca i8* ; <i8**> [#uses=2] - %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] - store i8* %a, i8** %a_addr - %buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1] - %0 = load i8** %a_addr, align 4 ; <i8*> [#uses=1] - %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0] - %buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1] - %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0] - br label %return +; LINUX-I386: test13d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test13d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail -return: ; preds = %entry - ret void +; LINUX-KERNEL-X64: test13d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test13d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind + ret void } -declare i8* @strcpy(i8*, i8*) nounwind +; test14a: Addr-of a local, optimized into a GEP (e.g., &a - 12) +; no ssp attribute +; Requires no protector. +define void @test14a() nounwind uwtable { +entry: +; LINUX-I386: test14a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test14a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test14a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test14a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %add.ptr5 = getelementptr inbounds i32* %a, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind + ret void +} + +; test14b: Addr-of a local, optimized into a GEP (e.g., &a - 12) +; ssp attribute +; Requires no protector. +define void @test14b() nounwind uwtable ssp { +entry: +; LINUX-I386: test14b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test14b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test14b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test14b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %add.ptr5 = getelementptr inbounds i32* %a, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind + ret void +} + +; test14c: Addr-of a local, optimized into a GEP (e.g., &a - 12) +; sspstrong attribute +; Requires protector. +define void @test14c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test14c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test14c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test14c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test14c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %add.ptr5 = getelementptr inbounds i32* %a, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind + ret void +} + +; test14d: Addr-of a local, optimized into a GEP (e.g., &a - 12) +; sspreq attribute +; Requires protector. +define void @test14d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test14d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test14d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test14d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test14d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %add.ptr5 = getelementptr inbounds i32* %a, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind + ret void +} + +; test15a: Addr-of a local cast to a ptr of a different type +; (e.g., int a; ... ; float *b = &a;) +; no ssp attribute +; Requires no protector. +define void @test15a() nounwind uwtable { +entry: +; LINUX-I386: test15a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test15a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test15a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test15a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %b = alloca float*, align 8 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + store float* %0, float** %b, align 8 + %1 = load float** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1) + ret void +} + +; test15b: Addr-of a local cast to a ptr of a different type +; (e.g., int a; ... ; float *b = &a;) +; ssp attribute +; Requires no protector. +define void @test15b() nounwind uwtable ssp { +entry: +; LINUX-I386: test15b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test15b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test15b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test15b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %b = alloca float*, align 8 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + store float* %0, float** %b, align 8 + %1 = load float** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1) + ret void +} + +; test15c: Addr-of a local cast to a ptr of a different type +; (e.g., int a; ... ; float *b = &a;) +; sspstrong attribute +; Requires protector. +define void @test15c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test15c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test15c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test15c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test15c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %b = alloca float*, align 8 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + store float* %0, float** %b, align 8 + %1 = load float** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1) + ret void +} + +; test15d: Addr-of a local cast to a ptr of a different type +; (e.g., int a; ... ; float *b = &a;) +; sspreq attribute +; Requires protector. +define void @test15d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test15d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test15d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test15d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test15d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %b = alloca float*, align 8 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + store float* %0, float** %b, align 8 + %1 = load float** %b, align 8 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1) + ret void +} + +; test16a: Addr-of a local cast to a ptr of a different type (optimized) +; (e.g., int a; ... ; float *b = &a;) +; no ssp attribute +; Requires no protector. +define void @test16a() nounwind uwtable { +entry: +; LINUX-I386: test16a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test16a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test16a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test16a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + call void @funfloat(float* %0) nounwind + ret void +} + +; test16b: Addr-of a local cast to a ptr of a different type (optimized) +; (e.g., int a; ... ; float *b = &a;) +; ssp attribute +; Requires no protector. +define void @test16b() nounwind uwtable ssp { +entry: +; LINUX-I386: test16b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test16b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test16b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test16b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + call void @funfloat(float* %0) nounwind + ret void +} + +; test16c: Addr-of a local cast to a ptr of a different type (optimized) +; (e.g., int a; ... ; float *b = &a;) +; sspstrong attribute +; Requires protector. +define void @test16c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test16c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test16c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test16c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test16c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + call void @funfloat(float* %0) nounwind + ret void +} + +; test16d: Addr-of a local cast to a ptr of a different type (optimized) +; (e.g., int a; ... ; float *b = &a;) +; sspreq attribute +; Requires protector. +define void @test16d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test16d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test16d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test16d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test16d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + store i32 0, i32* %a, align 4 + %0 = bitcast i32* %a to float* + call void @funfloat(float* %0) nounwind + ret void +} + +; test17a: Addr-of a vector nested in a struct +; no ssp attribute +; Requires no protector. +define void @test17a() nounwind uwtable { +entry: +; LINUX-I386: test17a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test17a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test17a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test17a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.vec, align 16 + %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0 + %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind + ret void +} + +; test17b: Addr-of a vector nested in a struct +; ssp attribute +; Requires no protector. +define void @test17b() nounwind uwtable ssp { +entry: +; LINUX-I386: test17b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test17b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test17b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test17b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.vec, align 16 + %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0 + %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind + ret void +} + +; test17c: Addr-of a vector nested in a struct +; sspstrong attribute +; Requires protector. +define void @test17c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test17c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test17c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test17c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test17c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.vec, align 16 + %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0 + %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind + ret void +} + +; test17d: Addr-of a vector nested in a struct +; sspreq attribute +; Requires protector. +define void @test17d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test17d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test17d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test17d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test17d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.vec, align 16 + %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0 + %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind + ret void +} + +; test18a: Addr-of a variable passed into an invoke instruction. +; no ssp attribute +; Requires no protector. +define i32 @test18a() uwtable { +entry: +; LINUX-I386: test18a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test18a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test18a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test18a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + store i32 0, i32* %a, align 4 + invoke void @_Z3exceptPi(i32* %a) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test18b: Addr-of a variable passed into an invoke instruction. +; ssp attribute +; Requires no protector. +define i32 @test18b() uwtable ssp { +entry: +; LINUX-I386: test18b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test18b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test18b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test18b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + store i32 0, i32* %a, align 4 + invoke void @_Z3exceptPi(i32* %a) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test18c: Addr-of a variable passed into an invoke instruction. +; sspstrong attribute +; Requires protector. +define i32 @test18c() uwtable sspstrong { +entry: +; LINUX-I386: test18c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test18c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test18c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test18c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + store i32 0, i32* %a, align 4 + invoke void @_Z3exceptPi(i32* %a) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test18d: Addr-of a variable passed into an invoke instruction. +; sspreq attribute +; Requires protector. +define i32 @test18d() uwtable sspreq { +entry: +; LINUX-I386: test18d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test18d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test18d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test18d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + store i32 0, i32* %a, align 4 + invoke void @_Z3exceptPi(i32* %a) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test19a: Addr-of a struct element passed into an invoke instruction. +; (GEP followed by an invoke) +; no ssp attribute +; Requires no protector. +define i32 @test19a() uwtable { +entry: +; LINUX-I386: test19a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test19a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test19a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test19a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + store i32 0, i32* %a, align 4 + %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + invoke void @_Z3exceptPi(i32* %a1) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test19b: Addr-of a struct element passed into an invoke instruction. +; (GEP followed by an invoke) +; ssp attribute +; Requires no protector. +define i32 @test19b() uwtable ssp { +entry: +; LINUX-I386: test19b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test19b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test19b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test19b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.pair, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + store i32 0, i32* %a, align 4 + %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + invoke void @_Z3exceptPi(i32* %a1) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test19c: Addr-of a struct element passed into an invoke instruction. +; (GEP followed by an invoke) +; sspstrong attribute +; Requires protector. +define i32 @test19c() uwtable sspstrong { +entry: +; LINUX-I386: test19c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test19c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test19c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test19c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + store i32 0, i32* %a, align 4 + %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + invoke void @_Z3exceptPi(i32* %a1) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test19d: Addr-of a struct element passed into an invoke instruction. +; (GEP followed by an invoke) +; sspreq attribute +; Requires protector. +define i32 @test19d() uwtable sspreq { +entry: +; LINUX-I386: test19d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test19d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test19d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test19d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %c = alloca %struct.pair, align 4 + %exn.slot = alloca i8* + %ehselector.slot = alloca i32 + %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + store i32 0, i32* %a, align 4 + %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0 + invoke void @_Z3exceptPi(i32* %a1) + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + ret i32 0 +} + +; test20a: Addr-of a pointer +; no ssp attribute +; Requires no protector. +define void @test20a() nounwind uwtable { +entry: +; LINUX-I386: test20a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test20a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test20a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test20a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32*, align 8 + %b = alloca i32**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + store i32** %a, i32*** %b, align 8 + %0 = load i32*** %b, align 8 + call void @funcall2(i32** %0) + ret void +} + +; test20b: Addr-of a pointer +; ssp attribute +; Requires no protector. +define void @test20b() nounwind uwtable ssp { +entry: +; LINUX-I386: test20b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test20b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test20b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test20b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32*, align 8 + %b = alloca i32**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + store i32** %a, i32*** %b, align 8 + %0 = load i32*** %b, align 8 + call void @funcall2(i32** %0) + ret void +} + +; test20c: Addr-of a pointer +; sspstrong attribute +; Requires protector. +define void @test20c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test20c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test20c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test20c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test20c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32*, align 8 + %b = alloca i32**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + store i32** %a, i32*** %b, align 8 + %0 = load i32*** %b, align 8 + call void @funcall2(i32** %0) + ret void +} + +; test20d: Addr-of a pointer +; sspreq attribute +; Requires protector. +define void @test20d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test20d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test20d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test20d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test20d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32*, align 8 + %b = alloca i32**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + store i32** %a, i32*** %b, align 8 + %0 = load i32*** %b, align 8 + call void @funcall2(i32** %0) + ret void +} + +; test21a: Addr-of a casted pointer +; no ssp attribute +; Requires no protector. +define void @test21a() nounwind uwtable { +entry: +; LINUX-I386: test21a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test21a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test21a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test21a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32*, align 8 + %b = alloca float**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + %0 = bitcast i32** %a to float** + store float** %0, float*** %b, align 8 + %1 = load float*** %b, align 8 + call void @funfloat2(float** %1) + ret void +} + +; test21b: Addr-of a casted pointer +; ssp attribute +; Requires no protector. +define void @test21b() nounwind uwtable ssp { +entry: +; LINUX-I386: test21b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test21b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test21b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test21b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca i32*, align 8 + %b = alloca float**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + %0 = bitcast i32** %a to float** + store float** %0, float*** %b, align 8 + %1 = load float*** %b, align 8 + call void @funfloat2(float** %1) + ret void +} + +; test21c: Addr-of a casted pointer +; sspstrong attribute +; Requires protector. +define void @test21c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test21c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test21c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test21c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test21c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32*, align 8 + %b = alloca float**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + %0 = bitcast i32** %a to float** + store float** %0, float*** %b, align 8 + %1 = load float*** %b, align 8 + call void @funfloat2(float** %1) + ret void +} + +; test21d: Addr-of a casted pointer +; sspreq attribute +; Requires protector. +define void @test21d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test21d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test21d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test21d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test21d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca i32*, align 8 + %b = alloca float**, align 8 + %call = call i32* @getp() + store i32* %call, i32** %a, align 8 + %0 = bitcast i32** %a to float** + store float** %0, float*** %b, align 8 + %1 = load float*** %b, align 8 + call void @funfloat2(float** %1) + ret void +} + +; test22a: [2 x i8] in a class +; no ssp attribute +; Requires no protector. +define signext i8 @test22a() nounwind uwtable { +entry: +; LINUX-I386: test22a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test22a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test22a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test22a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca %class.A, align 1 + %array = getelementptr inbounds %class.A* %a, i32 0, i32 0 + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test22b: [2 x i8] in a class +; ssp attribute +; Requires no protector. +define signext i8 @test22b() nounwind uwtable ssp { +entry: +; LINUX-I386: test22b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test22b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test22b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test22b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca %class.A, align 1 + %array = getelementptr inbounds %class.A* %a, i32 0, i32 0 + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test22c: [2 x i8] in a class +; sspstrong attribute +; Requires protector. +define signext i8 @test22c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test22c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test22c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test22c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test22c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca %class.A, align 1 + %array = getelementptr inbounds %class.A* %a, i32 0, i32 0 + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test22d: [2 x i8] in a class +; sspreq attribute +; Requires protector. +define signext i8 @test22d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test22d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test22d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test22d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test22d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca %class.A, align 1 + %array = getelementptr inbounds %class.A* %a, i32 0, i32 0 + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test23a: [2 x i8] nested in several layers of structs and unions +; no ssp attribute +; Requires no protector. +define signext i8 @test23a() nounwind uwtable { +entry: +; LINUX-I386: test23a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test23a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test23a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test23a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca %struct.deep, align 1 + %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0 + %c = bitcast %union.anon* %b to %struct.anon* + %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0 + %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0 + %array = bitcast %union.anon.1* %e to [2 x i8]* + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test23b: [2 x i8] nested in several layers of structs and unions +; ssp attribute +; Requires no protector. +define signext i8 @test23b() nounwind uwtable ssp { +entry: +; LINUX-I386: test23b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test23b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test23b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test23b: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %x = alloca %struct.deep, align 1 + %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0 + %c = bitcast %union.anon* %b to %struct.anon* + %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0 + %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0 + %array = bitcast %union.anon.1* %e to [2 x i8]* + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test23c: [2 x i8] nested in several layers of structs and unions +; sspstrong attribute +; Requires protector. +define signext i8 @test23c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test23c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test23c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test23c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test23c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca %struct.deep, align 1 + %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0 + %c = bitcast %union.anon* %b to %struct.anon* + %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0 + %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0 + %array = bitcast %union.anon.1* %e to [2 x i8]* + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test23d: [2 x i8] nested in several layers of structs and unions +; sspreq attribute +; Requires protector. +define signext i8 @test23d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test23d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test23d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test23d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test23d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %x = alloca %struct.deep, align 1 + %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0 + %c = bitcast %union.anon* %b to %struct.anon* + %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0 + %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0 + %array = bitcast %union.anon.1* %e to [2 x i8]* + %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0 + %0 = load i8* %arrayidx, align 1 + ret i8 %0 +} + +; test24a: Variable sized alloca +; no ssp attribute +; Requires no protector. +define void @test24a(i32 %n) nounwind uwtable { +entry: +; LINUX-I386: test24a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test24a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test24a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test24a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %n.addr = alloca i32, align 4 + %a = alloca i32*, align 8 + store i32 %n, i32* %n.addr, align 4 + %0 = load i32* %n.addr, align 4 + %conv = sext i32 %0 to i64 + %1 = alloca i8, i64 %conv + %2 = bitcast i8* %1 to i32* + store i32* %2, i32** %a, align 8 + ret void +} + +; test24b: Variable sized alloca +; ssp attribute +; Requires protector. +define void @test24b(i32 %n) nounwind uwtable ssp { +entry: +; LINUX-I386: test24b: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test24b: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test24b: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test24b: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %n.addr = alloca i32, align 4 + %a = alloca i32*, align 8 + store i32 %n, i32* %n.addr, align 4 + %0 = load i32* %n.addr, align 4 + %conv = sext i32 %0 to i64 + %1 = alloca i8, i64 %conv + %2 = bitcast i8* %1 to i32* + store i32* %2, i32** %a, align 8 + ret void +} + +; test24c: Variable sized alloca +; sspstrong attribute +; Requires protector. +define void @test24c(i32 %n) nounwind uwtable sspstrong { +entry: +; LINUX-I386: test24c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test24c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test24c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test24c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %n.addr = alloca i32, align 4 + %a = alloca i32*, align 8 + store i32 %n, i32* %n.addr, align 4 + %0 = load i32* %n.addr, align 4 + %conv = sext i32 %0 to i64 + %1 = alloca i8, i64 %conv + %2 = bitcast i8* %1 to i32* + store i32* %2, i32** %a, align 8 + ret void +} + +; test24d: Variable sized alloca +; sspreq attribute +; Requires protector. +define void @test24d(i32 %n) nounwind uwtable sspreq { +entry: +; LINUX-I386: test24d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test24d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test24d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test24d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %n.addr = alloca i32, align 4 + %a = alloca i32*, align 8 + store i32 %n, i32* %n.addr, align 4 + %0 = load i32* %n.addr, align 4 + %conv = sext i32 %0 to i64 + %1 = alloca i8, i64 %conv + %2 = bitcast i8* %1 to i32* + store i32* %2, i32** %a, align 8 + ret void +} + +; test25a: array of [4 x i32] +; no ssp attribute +; Requires no protector. +define i32 @test25a() nounwind uwtable { +entry: +; LINUX-I386: test25a: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test25a: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test25a: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test25a: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %a = alloca [4 x i32], align 16 + %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0 + %0 = load i32* %arrayidx, align 4 + ret i32 %0 +} + +; test25b: array of [4 x i32] +; ssp attribute +; Requires no protector, except for Darwin which _does_ require a protector. +define i32 @test25b() nounwind uwtable ssp { +entry: +; LINUX-I386: test25b: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test25b: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test25b: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test25b: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca [4 x i32], align 16 + %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0 + %0 = load i32* %arrayidx, align 4 + ret i32 %0 +} + +; test25c: array of [4 x i32] +; sspstrong attribute +; Requires protector. +define i32 @test25c() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test25c: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test25c: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test25c: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test25c: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca [4 x i32], align 16 + %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0 + %0 = load i32* %arrayidx, align 4 + ret i32 %0 +} + +; test25d: array of [4 x i32] +; sspreq attribute +; Requires protector. +define i32 @test25d() nounwind uwtable sspreq { +entry: +; LINUX-I386: test25d: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test25d: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test25d: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test25d: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %a = alloca [4 x i32], align 16 + %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0 + %0 = load i32* %arrayidx, align 4 + ret i32 %0 +} + +; test26: Nested structure, no arrays, no address-of expressions. +; Verify that the resulting gep-of-gep does not incorrectly trigger +; a stack protector. +; ssptrong attribute +; Requires no protector. +define void @test26() nounwind uwtable sspstrong { +entry: +; LINUX-I386: test26: +; LINUX-I386-NOT: calll __stack_chk_fail +; LINUX-I386: .cfi_endproc + +; LINUX-X64: test26: +; LINUX-X64-NOT: callq __stack_chk_fail +; LINUX-X64: .cfi_endproc + +; LINUX-KERNEL-X64: test26: +; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail +; LINUX-KERNEL-X64: .cfi_endproc + +; DARWIN-X64: test26: +; DARWIN-X64-NOT: callq ___stack_chk_fail +; DARWIN-X64: .cfi_endproc + %c = alloca %struct.nest, align 4 + %b = getelementptr inbounds %struct.nest* %c, i32 0, i32 1 + %_a = getelementptr inbounds %struct.pair* %b, i32 0, i32 0 + %0 = load i32* %_a, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %0) + ret void +} + +; test27: Address-of a structure taken in a function with a loop where +; the alloca is an incoming value to a PHI node and a use of that PHI +; node is also an incoming value. +; Verify that the address-of analysis does not get stuck in infinite +; recursion when chasing the alloca through the PHI nodes. +; Requires protector. +define i32 @test27(i32 %arg) nounwind uwtable sspstrong { +bb: +; LINUX-I386: test27: +; LINUX-I386: mov{{l|q}} %gs: +; LINUX-I386: calll __stack_chk_fail + +; LINUX-X64: test27: +; LINUX-X64: mov{{l|q}} %fs: +; LINUX-X64: callq __stack_chk_fail + +; LINUX-KERNEL-X64: test27: +; LINUX-KERNEL-X64: mov{{l|q}} %gs: +; LINUX-KERNEL-X64: callq __stack_chk_fail + +; DARWIN-X64: test27: +; DARWIN-X64: mov{{l|q}} ___stack_chk_guard +; DARWIN-X64: callq ___stack_chk_fail + %tmp = alloca %struct.small*, align 8 + %tmp1 = call i32 (...)* @dummy(%struct.small** %tmp) nounwind + %tmp2 = load %struct.small** %tmp, align 8 + %tmp3 = ptrtoint %struct.small* %tmp2 to i64 + %tmp4 = trunc i64 %tmp3 to i32 + %tmp5 = icmp sgt i32 %tmp4, 0 + br i1 %tmp5, label %bb6, label %bb21 + +bb6: ; preds = %bb17, %bb + %tmp7 = phi %struct.small* [ %tmp19, %bb17 ], [ %tmp2, %bb ] + %tmp8 = phi i64 [ %tmp20, %bb17 ], [ 1, %bb ] + %tmp9 = phi i32 [ %tmp14, %bb17 ], [ %tmp1, %bb ] + %tmp10 = getelementptr inbounds %struct.small* %tmp7, i64 0, i32 0 + %tmp11 = load i8* %tmp10, align 1 + %tmp12 = icmp eq i8 %tmp11, 1 + %tmp13 = add nsw i32 %tmp9, 8 + %tmp14 = select i1 %tmp12, i32 %tmp13, i32 %tmp9 + %tmp15 = trunc i64 %tmp8 to i32 + %tmp16 = icmp eq i32 %tmp15, %tmp4 + br i1 %tmp16, label %bb21, label %bb17 + +bb17: ; preds = %bb6 + %tmp18 = getelementptr inbounds %struct.small** %tmp, i64 %tmp8 + %tmp19 = load %struct.small** %tmp18, align 8 + %tmp20 = add i64 %tmp8, 1 + br label %bb6 + +bb21: ; preds = %bb6, %bb + %tmp22 = phi i32 [ %tmp1, %bb ], [ %tmp14, %bb6 ] + %tmp23 = call i32 (...)* @dummy(i32 %tmp22) nounwind + ret i32 undef +} -declare i32 @printf(i8*, ...) nounwind +declare double @testi_aux() +declare i8* @strcpy(i8*, i8*) +declare i32 @printf(i8*, ...) +declare void @funcall(i32*) +declare void @funcall2(i32**) +declare void @funfloat(float*) +declare void @funfloat2(float**) +declare void @_Z3exceptPi(i32*) +declare i32 @__gxx_personality_v0(...) +declare i32* @getp() +declare i32 @dummy(...) diff --git a/test/CodeGen/X86/stack-update-frame-opcode.ll b/test/CodeGen/X86/stack-update-frame-opcode.ll new file mode 100644 index 0000000000..9a5a242123 --- /dev/null +++ b/test/CodeGen/X86/stack-update-frame-opcode.ll @@ -0,0 +1,31 @@ +; RUN: llc -mtriple=x86_64-pc-linux -mcpu=corei7 < %s | FileCheck -check-prefix=CORE_LP64 %s +; RUN: llc -mtriple=x86_64-pc-linux -mcpu=atom < %s | FileCheck -check-prefix=ATOM_LP64 %s +; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mcpu=corei7 < %s | FileCheck -check-prefix=CORE_ILP32 %s +; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mcpu=atom < %s | FileCheck -check-prefix=ATOM_ILP32 %s + +define i32 @bar(i32 %a) nounwind { +entry: + %arr = alloca [400 x i32], align 16 + +; There is a 2x2 variation matrix here: +; Atoms use LEA to update the SP. Opcode bitness depends on data model. +; Cores use sub/add to update the SP. Opcode bitness depends on data model. + +; CORE_LP64: subq $1608 +; CORE_ILP32: subl $1608 +; ATOM_LP64: leaq -1608 +; ATOM_ILP32: leal -1608 + + %arraydecay = getelementptr inbounds [400 x i32]* %arr, i64 0, i64 0 + %call = call i32 @foo(i32 %a, i32* %arraydecay) nounwind + ret i32 %call + +; CORE_LP64: addq $1608 +; CORE_ILP32: addl $1608 +; ATOM_LP64: leaq 1608 +; ATOM_ILP32: leal 1608 + +} + +declare i32 @foo(i32, i32*) + diff --git a/test/CodeGen/X86/store_op_load_fold.ll b/test/CodeGen/X86/store_op_load_fold.ll index 6e47eb397d..070cccdb87 100644 --- a/test/CodeGen/X86/store_op_load_fold.ll +++ b/test/CodeGen/X86/store_op_load_fold.ll @@ -1,13 +1,30 @@ -; RUN: llc < %s -march=x86 | not grep mov +; RUN: llc < %s -mtriple=i686-darwin | FileCheck %s ; ; Test the add and load are folded into the store instruction. @X = internal global i16 0 ; <i16*> [#uses=2] define void @foo() nounwind { +; CHECK: foo: +; CHECK-NOT: mov +; CHECK: add +; CHECK-NEXT: ret %tmp.0 = load i16* @X ; <i16> [#uses=1] %tmp.3 = add i16 %tmp.0, 329 ; <i16> [#uses=1] store i16 %tmp.3, i16* @X ret void } +; rdar://12838504 +%struct.S2 = type { i64, i16, [2 x i8], i8, [3 x i8], [7 x i8], i8, [8 x i8] } +@s2 = external global %struct.S2, align 16 +define void @test2() nounwind uwtable ssp { +; CHECK: test2: +; CHECK: mov +; CHECK-NEXT: and +; CHECK-NEXT: ret + %bf.load35 = load i56* bitcast ([7 x i8]* getelementptr inbounds (%struct.S2* @s2, i32 0, i32 5) to i56*), align 16 + %bf.clear36 = and i56 %bf.load35, -1125895611875329 + store i56 %bf.clear36, i56* bitcast ([7 x i8]* getelementptr inbounds (%struct.S2* @s2, i32 0, i32 5) to i56*), align 16 + ret void +} diff --git a/test/CodeGen/X86/subtarget-feature-change.ll b/test/CodeGen/X86/subtarget-feature-change.ll new file mode 100644 index 0000000000..cd677294c6 --- /dev/null +++ b/test/CodeGen/X86/subtarget-feature-change.ll @@ -0,0 +1,66 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; This should not generate SSE instructions: +; +; CHECK: without.sse: +; CHECK: flds +; CHECK: fmuls +; CHECK: fstps +define void @without.sse(float* nocapture %a, float* nocapture %b, float* nocapture %c, i32 %n) #0 { +entry: + %cmp9 = icmp sgt i32 %n, 0 + br i1 %cmp9, label %for.body, label %for.end + +for.body: + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds float* %b, i64 %indvars.iv + %0 = load float* %arrayidx, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds float* %c, i64 %indvars.iv + %1 = load float* %arrayidx2, align 4, !tbaa !0 + %mul = fmul float %0, %1 + %arrayidx4 = getelementptr inbounds float* %a, i64 %indvars.iv + store float %mul, float* %arrayidx4, align 4, !tbaa !0 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: + ret void +} + +; This should generate SSE instructions: +; +; CHECK: with.sse +; CHECK: movss +; CHECK: mulss +; CHECK: movss +define void @with.sse(float* nocapture %a, float* nocapture %b, float* nocapture %c, i32 %n) #1 { +entry: + %cmp9 = icmp sgt i32 %n, 0 + br i1 %cmp9, label %for.body, label %for.end + +for.body: + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds float* %b, i64 %indvars.iv + %0 = load float* %arrayidx, align 4, !tbaa !0 + %arrayidx2 = getelementptr inbounds float* %c, i64 %indvars.iv + %1 = load float* %arrayidx2, align 4, !tbaa !0 + %mul = fmul float %0, %1 + %arrayidx4 = getelementptr inbounds float* %a, i64 %indvars.iv + store float %mul, float* %arrayidx4, align 4, !tbaa !0 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: + ret void +} + +attributes #0 = { nounwind optsize ssp uwtable "target-cpu"="core2" "target-features"="-sse4a,-avx2,-xop,-fma4,-bmi2,-3dnow,-3dnowa,-pclmul,-sse,-avx,-sse41,-ssse3,+mmx,-rtm,-sse42,-lzcnt,-f16c,-popcnt,-bmi,-aes,-fma,-rdrand,-sse2,-sse3" } +attributes #1 = { nounwind optsize ssp uwtable "target-cpu"="core2" "target-features"="-sse4a,-avx2,-xop,-fma4,-bmi2,-3dnow,-3dnowa,-pclmul,+sse,-avx,-sse41,+ssse3,+mmx,-rtm,-sse42,-lzcnt,-f16c,-popcnt,-bmi,-aes,-fma,-rdrand,+sse2,+sse3" } + +!0 = metadata !{metadata !"float", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/test/CodeGen/X86/tailcall-structret.ll b/test/CodeGen/X86/tailcall-structret.ll index d8be4b2e2d..dcfefe8670 100644 --- a/test/CodeGen/X86/tailcall-structret.ll +++ b/test/CodeGen/X86/tailcall-structret.ll @@ -1,6 +1,7 @@ -; RUN: llc < %s -march=x86 -tailcallopt | grep TAILCALL +; RUN: llc < %s -mtriple=i686-unknown-linux -tailcallopt | FileCheck %s define fastcc { { i8*, i8* }*, i8*} @init({ { i8*, i8* }*, i8*}, i32) { entry: %2 = tail call fastcc { { i8*, i8* }*, i8* } @init({ { i8*, i8*}*, i8*} %0, i32 %1) ret { { i8*, i8* }*, i8*} %2 +; CHECK: jmp init } diff --git a/test/CodeGen/X86/tailcallbyval.ll b/test/CodeGen/X86/tailcallbyval.ll index 118eee6ba6..9a0b57c138 100644 --- a/test/CodeGen/X86/tailcallbyval.ll +++ b/test/CodeGen/X86/tailcallbyval.ll @@ -1,5 +1,4 @@ -; RUN: llc < %s -march=x86 -tailcallopt | grep TAILCALL -; RUN: llc < %s -march=x86 -tailcallopt | grep "movl[[:space:]]*4(%esp), %eax" | count 1 +; RUN: llc < %s -mtriple=i686-unknown-linux -tailcallopt | FileCheck %s %struct.s = type {i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } @@ -9,10 +8,14 @@ entry: %tmp2 = getelementptr %struct.s* %a, i32 0, i32 0 %tmp3 = load i32* %tmp2 ret i32 %tmp3 +; CHECK: tailcallee +; CHECK: movl 4(%esp), %eax } define fastcc i32 @tailcaller(%struct.s* byval %a) nounwind { entry: %tmp4 = tail call fastcc i32 @tailcallee(%struct.s* byval %a ) ret i32 %tmp4 +; CHECK: tailcaller +; CHECK: jmp tailcallee } diff --git a/test/CodeGen/X86/tailcallfp.ll b/test/CodeGen/X86/tailcallfp.ll index c0b609ac95..22a7930ba8 100644 --- a/test/CodeGen/X86/tailcallfp.ll +++ b/test/CodeGen/X86/tailcallfp.ll @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86 -x86-asm-syntax=intel -tailcallopt | not grep call +; RUN: llc < %s -march=x86 -tailcallopt | FileCheck %s define fastcc i32 @bar(i32 %X, i32(double, i32) *%FP) { %Y = tail call fastcc i32 %FP(double 0.0, i32 %X) ret i32 %Y +; CHECK: jmpl } diff --git a/test/CodeGen/X86/tailcallpic1.ll b/test/CodeGen/X86/tailcallpic1.ll index 60e3be5c50..ff590a1fd3 100644 --- a/test/CodeGen/X86/tailcallpic1.ll +++ b/test/CodeGen/X86/tailcallpic1.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep TAILCALL +; RUN: llc < %s -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s define protected fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { entry: @@ -9,4 +9,5 @@ define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { entry: %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 ) ; <i32> [#uses=1] ret i32 %tmp11 +; CHECK: jmp tailcallee } diff --git a/test/CodeGen/X86/tailcallpic2.ll b/test/CodeGen/X86/tailcallpic2.ll index eaa7631239..1b6bdb7698 100644 --- a/test/CodeGen/X86/tailcallpic2.ll +++ b/test/CodeGen/X86/tailcallpic2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep -v TAILCALL +; RUN: llc < %s -tailcallopt -mtriple=i686-pc-linux-gnu -relocation-model=pic | FileCheck %s define fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) { entry: @@ -9,4 +9,7 @@ define fastcc i32 @tailcaller(i32 %in1, i32 %in2) { entry: %tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32 %in1, i32 %in2 ) ; <i32> [#uses=1] ret i32 %tmp11 +; CHECK: movl tailcallee@GOT +; CHECK: jmpl } + diff --git a/test/CodeGen/X86/unknown-location.ll b/test/CodeGen/X86/unknown-location.ll index b89c4738af..d3b4d31f6a 100644 --- a/test/CodeGen/X86/unknown-location.ll +++ b/test/CodeGen/X86/unknown-location.ll @@ -18,12 +18,15 @@ entry: ret i32 %c, !dbg !8 } -!0 = metadata !{i32 524545, metadata !1, metadata !"x", metadata !2, i32 1, metadata !6} ; [ DW_TAG_arg_variable ] -!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 1, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 524329, metadata !"test.c", metadata !"/dir", metadata !3} ; [ DW_TAG_file_type ] -!3 = metadata !{i32 524305, i32 0, i32 12, metadata !"test.c", metadata !".", metadata !"producer", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!llvm.dbg.cu = !{!3} +!9 = metadata !{metadata !1} + +!0 = metadata !{i32 786689, metadata !1, metadata !"x", metadata !2, i32 1, metadata !6} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 1, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false, i32 (i32, i32, i32, i32)* @foo, null, null, null, i32 1} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 786473, metadata !"test.c", metadata !"/dir", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 786449, i32 0, i32 12, metadata !"test.c", metadata !".", metadata !"producer", i1 true, i1 false, metadata !"", i32 0, null, null, metadata !9, null} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] !5 = metadata !{metadata !6} -!6 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 524299, metadata !1, i32 1, i32 30} ; [ DW_TAG_lexical_block ] +!6 = metadata !{i32 786468, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 786443, metadata !1, i32 1, i32 30} ; [ DW_TAG_lexical_block ] !8 = metadata !{i32 4, i32 3, metadata !7, null} diff --git a/test/CodeGen/X86/v8i1-masks.ll b/test/CodeGen/X86/v8i1-masks.ll new file mode 100644 index 0000000000..8cbfb5d724 --- /dev/null +++ b/test/CodeGen/X86/v8i1-masks.ll @@ -0,0 +1,39 @@ +; RUN: llc -march=x86-64 -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -o - < %s | FileCheck %s + +;CHECK: and_masks +;CHECK: vmovaps +;CHECK: vcmpltp +;CHECK: vcmpltp +;CHECK: vandps +;CHECK: vandps +;CHECK: vmovaps +;CHECK: ret + +define void @and_masks(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwind uwtable noinline ssp { + %v0 = load <8 x float>* %a, align 16 + %v1 = load <8 x float>* %b, align 16 + %m0 = fcmp olt <8 x float> %v1, %v0 + %v2 = load <8 x float>* %c, align 16 + %m1 = fcmp olt <8 x float> %v2, %v0 + %mand = and <8 x i1> %m1, %m0 + %r = zext <8 x i1> %mand to <8 x i32> + store <8 x i32> %r, <8 x i32>* undef, align 32 + ret void +} + +;CHECK: neg_mask +;CHECK: vcmpltps +;CHECK: vxorps +;CHECK: vandps +;CHECK: vmovaps +;CHECK: ret +define void @neg_masks(<8 x float>* %a, <8 x float>* %b, <8 x float>* %c) nounwind uwtable noinline ssp { + %v0 = load <8 x float>* %a, align 16 + %v1 = load <8 x float>* %b, align 16 + %m0 = fcmp olt <8 x float> %v1, %v0 + %mand = xor <8 x i1> %m0, <i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1> + %r = zext <8 x i1> %mand to <8 x i32> + store <8 x i32> %r, <8 x i32>* undef, align 32 + ret void +} + diff --git a/test/CodeGen/X86/vec_compare.ll b/test/CodeGen/X86/vec_compare.ll index 367dd27f30..b6d91a3f77 100644 --- a/test/CodeGen/X86/vec_compare.ll +++ b/test/CodeGen/X86/vec_compare.ll @@ -41,3 +41,27 @@ define <4 x i32> @test4(<4 x i32> %A, <4 x i32> %B) nounwind { %D = sext <4 x i1> %C to <4 x i32> ret <4 x i32> %D } + +define <2 x i64> @test5(<2 x i64> %A, <2 x i64> %B) nounwind { +; CHECK: test5: +; CHECK: pcmpeqd +; CHECK: pshufd $-79 +; CHECK: pand +; CHECK: ret + %C = icmp eq <2 x i64> %A, %B + %D = sext <2 x i1> %C to <2 x i64> + ret <2 x i64> %D +} + +define <2 x i64> @test6(<2 x i64> %A, <2 x i64> %B) nounwind { +; CHECK: test6: +; CHECK: pcmpeqd +; CHECK: pshufd $-79 +; CHECK: pand +; CHECK: pcmpeqd +; CHECK: pxor +; CHECK: ret + %C = icmp ne <2 x i64> %A, %B + %D = sext <2 x i1> %C to <2 x i64> + ret <2 x i64> %D +} diff --git a/test/CodeGen/X86/vec_fpext.ll b/test/CodeGen/X86/vec_fpext.ll index dc0464ff9e..e4a8f46cbc 100644 --- a/test/CodeGen/X86/vec_fpext.ll +++ b/test/CodeGen/X86/vec_fpext.ll @@ -29,8 +29,8 @@ entry: ; CHECK: cvtps2pd 8(%{{.+}}), %xmm{{[0-9]+}} ; CHECK: cvtps2pd 16(%{{.+}}), %xmm{{[0-9]+}} ; CHECK: cvtps2pd 24(%{{.+}}), %xmm{{[0-9]+}} -; AVX: vcvtps2pd (%{{.+}}), %ymm{{[0-9]+}} ; AVX: vcvtps2pd 16(%{{.+}}), %ymm{{[0-9]+}} +; AVX: vcvtps2pd (%{{.+}}), %ymm{{[0-9]+}} %0 = load <8 x float>* %in %1 = fpext <8 x float> %0 to <8 x double> store <8 x double> %1, <8 x double>* %out, align 1 diff --git a/test/CodeGen/X86/vec_sdiv_to_shift.ll b/test/CodeGen/X86/vec_sdiv_to_shift.ll new file mode 100644 index 0000000000..349868a87f --- /dev/null +++ b/test/CodeGen/X86/vec_sdiv_to_shift.ll @@ -0,0 +1,72 @@ +; RUN: llc < %s -march=x86-64 -mcpu=penryn -mattr=+avx2 | FileCheck %s + + +define <8 x i16> @sdiv_vec8x16(<8 x i16> %var) { +entry: +; CHECK: sdiv_vec8x16 +; CHECK: psraw $15 +; CHECK: vpsrlw $11 +; CHECK: vpaddw +; CHECK: vpsraw $5 +; CHECK: ret + %0 = sdiv <8 x i16> %var, <i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32> + ret <8 x i16> %0 +} + +define <4 x i32> @sdiv_zero(<4 x i32> %var) { +entry: +; CHECK: sdiv_zero +; CHECK-NOT: sra +; CHECK: ret + %0 = sdiv <4 x i32> %var, <i32 0, i32 0, i32 0, i32 0> + ret <4 x i32> %0 +} + +define <4 x i32> @sdiv_vec4x32(<4 x i32> %var) { +entry: +; CHECK: sdiv_vec4x32 +; CHECK: vpsrad $31 +; CHECK: vpsrld $28 +; CHECK: vpaddd +; CHECK: vpsrad $4 +; CHECK: ret +%0 = sdiv <4 x i32> %var, <i32 16, i32 16, i32 16, i32 16> +ret <4 x i32> %0 +} + +define <4 x i32> @sdiv_negative(<4 x i32> %var) { +entry: +; CHECK: sdiv_negative +; CHECK: vpsrad $31 +; CHECK: vpsrld $28 +; CHECK: vpaddd +; CHECK: vpsrad $4 +; CHECK: vpsubd +; CHECK: ret +%0 = sdiv <4 x i32> %var, <i32 -16, i32 -16, i32 -16, i32 -16> +ret <4 x i32> %0 +} + +define <8 x i32> @sdiv8x32(<8 x i32> %var) { +entry: +; CHECK: sdiv8x32 +; CHECK: vpsrad $31 +; CHECK: vpsrld $26 +; CHECK: vpaddd +; CHECK: vpsrad $6 +; CHECK: ret +%0 = sdiv <8 x i32> %var, <i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64> +ret <8 x i32> %0 +} + +define <16 x i16> @sdiv16x16(<16 x i16> %var) { +entry: +; CHECK: sdiv16x16 +; CHECK: vpsraw $15 +; CHECK: vpsrlw $14 +; CHECK: vpaddw +; CHECK: vpsraw $2 +; CHECK: ret + %a0 = sdiv <16 x i16> %var, <i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4> + ret <16 x i16> %a0 +} diff --git a/test/CodeGen/X86/vec_splat-2.ll b/test/CodeGen/X86/vec_splat-2.ll index f105de4d97..5c668b7e5a 100644 --- a/test/CodeGen/X86/vec_splat-2.ll +++ b/test/CodeGen/X86/vec_splat-2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mcpu=penryn -mattr=+sse2 | grep pshufd | count 1 +; RUN: llc < %s -march=x86 -mcpu=pentium4 -mattr=+sse2 | FileCheck %s define void @test(<2 x i64>* %P, i8 %x) nounwind { %tmp = insertelement <16 x i8> zeroinitializer, i8 %x, i32 0 ; <<16 x i8>> [#uses=1] @@ -23,4 +23,11 @@ define void @test(<2 x i64>* %P, i8 %x) nounwind { %tmp73.upgrd.1 = bitcast <16 x i8> %tmp73 to <2 x i64> ; <<2 x i64>> [#uses=1] store <2 x i64> %tmp73.upgrd.1, <2 x i64>* %P ret void + +; CHECK: test: +; CHECK-NOT: pshufd +; CHECK: punpcklbw +; CHECK: punpcklbw +; CHECK: pshufd $0 +; CHECK-NOT: pshufd } diff --git a/test/CodeGen/X86/vec_splat-3.ll b/test/CodeGen/X86/vec_splat-3.ll index feacc42406..cf0ecf4055 100644 --- a/test/CodeGen/X86/vec_splat-3.ll +++ b/test/CodeGen/X86/vec_splat-3.ll @@ -1,55 +1,230 @@ -; RUN: llc < %s -march=x86 -mcpu=penryn -mattr=sse41 -o %t -; RUN: grep punpcklwd %t | count 4 -; RUN: grep punpckhwd %t | count 4 -; RUN: grep "pshufd" %t | count 8 +; RUN: llc <%s -march=x86 -mcpu=penryn -mattr=sse41 | FileCheck %s ; Splat test for v8i16 -; Should generate with pshufd with masks $0, $85, $170, $255 (each mask is used twice) define <8 x i16> @shuf_8i16_0(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 0, i32 undef, i32 undef, i32 0, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 0, i32 undef, i32 undef, i32 0, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_0: +; CHECK: pshuflw $0 } define <8 x i16> @shuf_8i16_1(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_1: +; CHECK: pshuflw $5 } define <8 x i16> @shuf_8i16_2(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 2, i32 undef, i32 undef, i32 2, i32 undef, i32 2, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 2, i32 undef, i32 undef, i32 2, i32 undef, i32 2, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_2: +; CHECK: punpcklwd +; CHECK-NEXT: pshufd $-86 } define <8 x i16> @shuf_8i16_3(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 3, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 3, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_3: +; CHECK: pshuflw $15 } define <8 x i16> @shuf_8i16_4(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 4, i32 undef, i32 undef, i32 undef, i32 4, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 4, i32 undef, i32 undef, i32 undef, i32 4, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_4: +; CHECK: movhlps } define <8 x i16> @shuf_8i16_5(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 5, i32 undef, i32 undef, i32 5, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 5, i32 undef, i32 undef, i32 5, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_5: +; CHECK: punpckhwd +; CHECK-NEXT: pshufd $85 } define <8 x i16> @shuf_8i16_6(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 6, i32 6, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 6, i32 6, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 -} +; CHECK: shuf_8i16_6: +; CHECK: punpckhwd +; CHECK-NEXT: pshufd $-86 +} define <8 x i16> @shuf_8i16_7(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 7, i32 undef, i32 undef, i32 7, i32 undef, i32 undef, i32 undef , i32 undef > + %tmp6 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> <i32 7, i32 undef, i32 undef, i32 7, i32 undef, i32 undef, i32 undef, i32 undef> ret <8 x i16> %tmp6 + +; CHECK: shuf_8i16_7: +; CHECK: punpckhwd +; CHECK-NEXT: pshufd $-1 +} + +; Splat test for v16i8 +define <16 x i8> @shuf_16i8_8(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 0, i32 undef, i32 undef, i32 0, i32 undef, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_8: +; CHECK: punpcklbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $0 +} + +define <16 x i8> @shuf_16i8_9(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef > + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_9: +; CHECK: punpcklbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $85 +} + +define <16 x i8> @shuf_16i8_10(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 2, i32 undef, i32 undef, i32 2, i32 undef, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_10: +; CHECK: punpcklbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $-86 +} + +define <16 x i8> @shuf_16i8_11(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 3, i32 undef, i32 undef, i32 3, i32 undef, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_11: +; CHECK: punpcklbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $-1 +} + + +define <16 x i8> @shuf_16i8_12(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 4, i32 undef, i32 undef, i32 undef, i32 4, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef > + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_12: +; CHECK: pshufd $5 +} + +define <16 x i8> @shuf_16i8_13(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 5, i32 undef, i32 undef, i32 5, i32 undef, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_13: +; CHECK: punpcklbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $85 +} + +define <16 x i8> @shuf_16i8_14(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 6, i32 undef, i32 undef, i32 6, i32 undef, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_14: +; CHECK: punpcklbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $-86 +} + +define <16 x i8> @shuf_16i8_15(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 7, i32 undef, i32 undef, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef > + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_15: +; CHECK: punpcklbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $-1 +} + +define <16 x i8> @shuf_16i8_16(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 8, i32 undef, i32 undef, i32 8, i32 undef, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_16: +; CHECK: punpckhbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $0 +} + +define <16 x i8> @shuf_16i8_17(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 9, i32 undef, i32 undef, i32 9, i32 undef, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_17: +; CHECK: punpckhbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $85 +} + +define <16 x i8> @shuf_16i8_18(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 10, i32 undef, i32 undef, i32 10, i32 undef, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_18: +; CHECK: punpckhbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $-86 +} + +define <16 x i8> @shuf_16i8_19(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 11, i32 undef, i32 undef, i32 11, i32 undef, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_19: +; CHECK: punpckhbw +; CHECK-NEXT: punpcklbw +; CHECK-NEXT: pshufd $-1 +} + +define <16 x i8> @shuf_16i8_20(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 12, i32 undef, i32 undef, i32 12, i32 undef, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_20: +; CHECK: punpckhbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $0 +} + +define <16 x i8> @shuf_16i8_21(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 13, i32 undef, i32 undef, i32 13, i32 undef, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_21: +; CHECK: punpckhbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $85 +} + +define <16 x i8> @shuf_16i8_22(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 14, i32 undef, i32 undef, i32 14, i32 undef, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_22: +; CHECK: punpckhbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $-86 +} + +define <16 x i8> @shuf_16i8_23(<16 x i8> %T0, <16 x i8> %T1) nounwind readnone { + %tmp6 = shufflevector <16 x i8> %T0, <16 x i8> %T1, <16 x i32> <i32 15, i32 undef, i32 undef, i32 15, i32 undef, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15> + ret <16 x i8> %tmp6 + +; CHECK: shuf_16i8_23: +; CHECK: punpckhbw +; CHECK-NEXT: punpckhbw +; CHECK-NEXT: pshufd $-1 } diff --git a/test/CodeGen/X86/vec_splat-4.ll b/test/CodeGen/X86/vec_splat-4.ll deleted file mode 100644 index 374acfa4e0..0000000000 --- a/test/CodeGen/X86/vec_splat-4.ll +++ /dev/null @@ -1,104 +0,0 @@ -; RUN: llc < %s -march=x86 -mcpu=penryn -mattr=sse41 -o %t -; RUN: grep punpcklbw %t | count 16 -; RUN: grep punpckhbw %t | count 16 -; RUN: grep "pshufd" %t | count 16 - -; Should generate with pshufd with masks $0, $85, $170, $255 (each mask is used 4 times) - -; Splat test for v16i8 -define <16 x i8 > @shuf_16i8_0(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 0, i32 undef, i32 undef, i32 0, i32 undef, i32 0, i32 0 , i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_1(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef, i32 undef, i32 undef, i32 undef > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_2(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 2, i32 undef, i32 undef, i32 2, i32 undef, i32 2, i32 2 , i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_3(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 3, i32 undef, i32 undef, i32 3, i32 undef, i32 3, i32 3 , i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3 > - ret <16 x i8 > %tmp6 -} - - -define <16 x i8 > @shuf_16i8_4(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 4, i32 undef, i32 undef, i32 undef, i32 4, i32 undef, i32 undef , i32 undef, i32 undef, i32 undef, i32 undef , i32 undef, i32 undef, i32 undef, i32 undef , i32 undef > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_5(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 5, i32 undef, i32 undef, i32 5, i32 undef, i32 5, i32 5 , i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_6(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 6, i32 undef, i32 undef, i32 6, i32 undef, i32 6, i32 6 , i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_7(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 7, i32 undef, i32 undef, i32 7, i32 undef, i32 undef, i32 undef , i32 undef, i32 undef, i32 undef, i32 undef , i32 undef , i32 undef, i32 undef, i32 undef , i32 undef > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_8(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 8, i32 undef, i32 undef, i32 8, i32 undef, i32 8, i32 8 , i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_9(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 9, i32 undef, i32 undef, i32 9, i32 undef, i32 9, i32 9 , i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9, i32 9 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_10(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 10, i32 undef, i32 undef, i32 10, i32 undef, i32 10, i32 10 , i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_11(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 11, i32 undef, i32 undef, i32 11, i32 undef, i32 11, i32 11 , i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11, i32 11 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_12(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 12, i32 undef, i32 undef, i32 12, i32 undef, i32 12, i32 12 , i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12, i32 12 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_13(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 13, i32 undef, i32 undef, i32 13, i32 undef, i32 13, i32 13 , i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_14(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 14, i32 undef, i32 undef, i32 14, i32 undef, i32 14, i32 14 , i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14, i32 14 > - ret <16 x i8 > %tmp6 -} - -define <16 x i8 > @shuf_16i8_15(<16 x i8 > %T0, <16 x i8 > %T1) nounwind readnone { -entry: - %tmp6 = shufflevector <16 x i8 > %T0, <16 x i8 > %T1, <16 x i32> < i32 15, i32 undef, i32 undef, i32 15, i32 undef, i32 15, i32 15 , i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15 > - ret <16 x i8 > %tmp6 -} diff --git a/test/CodeGen/X86/vec_splat.ll b/test/CodeGen/X86/vec_splat.ll index 24d8487f17..deedee8019 100644 --- a/test/CodeGen/X86/vec_splat.ll +++ b/test/CodeGen/X86/vec_splat.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86 -mcpu=penryn -mattr=+sse2 | grep pshufd -; RUN: llc < %s -march=x86 -mcpu=penryn -mattr=+sse3 | grep movddup +; RUN: llc < %s -march=x86 -mcpu=pentium4 -mattr=+sse2 | FileCheck %s -check-prefix=SSE2 +; RUN: llc < %s -march=x86 -mcpu=pentium4 -mattr=+sse3 | FileCheck %s -check-prefix=SSE3 define void @test_v4sf(<4 x float>* %P, <4 x float>* %Q, float %X) nounwind { %tmp = insertelement <4 x float> zeroinitializer, float %X, i32 0 ; <<4 x float>> [#uses=1] @@ -10,6 +10,12 @@ define void @test_v4sf(<4 x float>* %P, <4 x float>* %Q, float %X) nounwind { %tmp10 = fmul <4 x float> %tmp8, %tmp6 ; <<4 x float>> [#uses=1] store <4 x float> %tmp10, <4 x float>* %P ret void + +; SSE2: test_v4sf: +; SSE2: pshufd $0 + +; SSE3: test_v4sf: +; SSE3: pshufd $0 } define void @test_v2sd(<2 x double>* %P, <2 x double>* %Q, double %X) nounwind { @@ -19,4 +25,10 @@ define void @test_v2sd(<2 x double>* %P, <2 x double>* %Q, double %X) nounwind { %tmp6 = fmul <2 x double> %tmp4, %tmp2 ; <<2 x double>> [#uses=1] store <2 x double> %tmp6, <2 x double>* %P ret void + +; SSE2: test_v2sd: +; SSE2: shufpd $0 + +; SSE3: test_v2sd: +; SSE3: movddup } diff --git a/test/CodeGen/X86/vector-gep.ll b/test/CodeGen/X86/vector-gep.ll index 3476e36c64..ec93ce0761 100644 --- a/test/CodeGen/X86/vector-gep.ll +++ b/test/CodeGen/X86/vector-gep.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86 -mcpu=corei7-avx | FileCheck %s -; RUN: opt -instsimplify %s -disable-output +; RUN: opt -instsimplify -disable-output < %s ;CHECK: AGEP0: define <4 x i32*> @AGEP0(i32* %ptr) nounwind { @@ -8,10 +8,8 @@ entry: %vecinit2.i = insertelement <4 x i32*> %vecinit.i, i32* %ptr, i32 1 %vecinit4.i = insertelement <4 x i32*> %vecinit2.i, i32* %ptr, i32 2 %vecinit6.i = insertelement <4 x i32*> %vecinit4.i, i32* %ptr, i32 3 -;CHECK: pslld $2 ;CHECK: padd %A2 = getelementptr <4 x i32*> %vecinit6.i, <4 x i32> <i32 1, i32 2, i32 3, i32 4> -;CHECK: pslld $2 ;CHECK: padd %A3 = getelementptr <4 x i32*> %A2, <4 x i32> <i32 10, i32 14, i32 19, i32 233> ret <4 x i32*> %A3 @@ -21,7 +19,6 @@ entry: ;CHECK: AGEP1: define i32 @AGEP1(<4 x i32*> %param) nounwind { entry: -;CHECK: pslld $2 ;CHECK: padd %A2 = getelementptr <4 x i32*> %param, <4 x i32> <i32 1, i32 2, i32 3, i32 4> %k = extractelement <4 x i32*> %A2, i32 3 diff --git a/test/CodeGen/X86/vselect-minmax.ll b/test/CodeGen/X86/vselect-minmax.ll new file mode 100644 index 0000000000..cf654b6f20 --- /dev/null +++ b/test/CodeGen/X86/vselect-minmax.ll @@ -0,0 +1,2788 @@ +; RUN: llc -march=x86-64 -mcpu=core2 < %s | FileCheck %s -check-prefix=SSE2 +; RUN: llc -march=x86-64 -mcpu=corei7 < %s | FileCheck %s -check-prefix=SSE4 +; RUN: llc -march=x86-64 -mcpu=corei7-avx < %s | FileCheck %s -check-prefix=AVX1 +; RUN: llc -march=x86-64 -mcpu=core-avx2 -mattr=+avx2 < %s | FileCheck %s -check-prefix=AVX2 + +define void @test1(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp slt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test1: +; SSE4: pminsb + +; AVX1: test1: +; AVX1: vpminsb + +; AVX2: test1: +; AVX2: vpminsb +} + +define void @test2(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sle <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test2: +; SSE4: pminsb + +; AVX1: test2: +; AVX1: vpminsb + +; AVX2: test2: +; AVX2: vpminsb +} + +define void @test3(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sgt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test3: +; SSE4: pmaxsb + +; AVX1: test3: +; AVX1: vpmaxsb + +; AVX2: test3: +; AVX2: vpmaxsb +} + +define void @test4(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sge <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test4: +; SSE4: pmaxsb + +; AVX1: test4: +; AVX1: vpmaxsb + +; AVX2: test4: +; AVX2: vpmaxsb +} + +define void @test5(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ult <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test5: +; SSE2: pminub + +; AVX1: test5: +; AVX1: vpminub + +; AVX2: test5: +; AVX2: vpminub +} + +define void @test6(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ule <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test6: +; SSE2: pminub + +; AVX1: test6: +; AVX1: vpminub + +; AVX2: test6: +; AVX2: vpminub +} + +define void @test7(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ugt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test7: +; SSE2: pmaxub + +; AVX1: test7: +; AVX1: vpmaxub + +; AVX2: test7: +; AVX2: vpmaxub +} + +define void @test8(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp uge <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.a, <16 x i8> %load.b + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test8: +; SSE2: pmaxub + +; AVX1: test8: +; AVX1: vpmaxub + +; AVX2: test8: +; AVX2: vpmaxub +} + +define void @test9(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp slt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test9: +; SSE2: pminsw + +; AVX1: test9: +; AVX1: vpminsw + +; AVX2: test9: +; AVX2: vpminsw +} + +define void @test10(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sle <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test10: +; SSE2: pminsw + +; AVX1: test10: +; AVX1: vpminsw + +; AVX2: test10: +; AVX2: vpminsw +} + +define void @test11(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sgt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test11: +; SSE2: pmaxsw + +; AVX1: test11: +; AVX1: vpmaxsw + +; AVX2: test11: +; AVX2: vpmaxsw +} + +define void @test12(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sge <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test12: +; SSE2: pmaxsw + +; AVX1: test12: +; AVX1: vpmaxsw + +; AVX2: test12: +; AVX2: vpmaxsw +} + +define void @test13(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ult <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test13: +; SSE4: pminuw + +; AVX1: test13: +; AVX1: vpminuw + +; AVX2: test13: +; AVX2: vpminuw +} + +define void @test14(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ule <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test14: +; SSE4: pminuw + +; AVX1: test14: +; AVX1: vpminuw + +; AVX2: test14: +; AVX2: vpminuw +} + +define void @test15(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ugt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test15: +; SSE4: pmaxuw + +; AVX1: test15: +; AVX1: vpmaxuw + +; AVX2: test15: +; AVX2: vpmaxuw +} + +define void @test16(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp uge <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.a, <8 x i16> %load.b + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test16: +; SSE4: pmaxuw + +; AVX1: test16: +; AVX1: vpmaxuw + +; AVX2: test16: +; AVX2: vpmaxuw +} + +define void @test17(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp slt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test17: +; SSE4: pminsd + +; AVX1: test17: +; AVX1: vpminsd + +; AVX2: test17: +; AVX2: vpminsd +} + +define void @test18(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sle <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test18: +; SSE4: pminsd + +; AVX1: test18: +; AVX1: vpminsd + +; AVX2: test18: +; AVX2: vpminsd +} + +define void @test19(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sgt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test19: +; SSE4: pmaxsd + +; AVX1: test19: +; AVX1: vpmaxsd + +; AVX2: test19: +; AVX2: vpmaxsd +} + +define void @test20(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sge <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test20: +; SSE4: pmaxsd + +; AVX1: test20: +; AVX1: vpmaxsd + +; AVX2: test20: +; AVX2: vpmaxsd +} + +define void @test21(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ult <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test21: +; SSE4: pminud + +; AVX1: test21: +; AVX1: vpminud + +; AVX2: test21: +; AVX2: vpminud +} + +define void @test22(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ule <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test22: +; SSE4: pminud + +; AVX1: test22: +; AVX1: vpminud + +; AVX2: test22: +; AVX2: vpminud +} + +define void @test23(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ugt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test23: +; SSE4: pmaxud + +; AVX1: test23: +; AVX1: vpmaxud + +; AVX2: test23: +; AVX2: vpmaxud +} + +define void @test24(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp uge <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.a, <4 x i32> %load.b + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test24: +; SSE4: pmaxud + +; AVX1: test24: +; AVX1: vpmaxud + +; AVX2: test24: +; AVX2: vpmaxud +} + +define void @test25(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp slt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test25: +; AVX2: vpminsb +} + +define void @test26(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sle <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test26: +; AVX2: vpminsb +} + +define void @test27(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sgt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test27: +; AVX2: vpmaxsb +} + +define void @test28(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sge <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test28: +; AVX2: vpmaxsb +} + +define void @test29(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ult <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test29: +; AVX2: vpminub +} + +define void @test30(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ule <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test30: +; AVX2: vpminub +} + +define void @test31(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ugt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test31: +; AVX2: vpmaxub +} + +define void @test32(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp uge <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.a, <32 x i8> %load.b + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test32: +; AVX2: vpmaxub +} + +define void @test33(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp slt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test33: +; AVX2: vpminsw +} + +define void @test34(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sle <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test34: +; AVX2: vpminsw +} + +define void @test35(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sgt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test35: +; AVX2: vpmaxsw +} + +define void @test36(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sge <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test36: +; AVX2: vpmaxsw +} + +define void @test37(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ult <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test37: +; AVX2: vpminuw +} + +define void @test38(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ule <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test38: +; AVX2: vpminuw +} + +define void @test39(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ugt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test39: +; AVX2: vpmaxuw +} + +define void @test40(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp uge <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.a, <16 x i16> %load.b + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test40: +; AVX2: vpmaxuw +} + +define void @test41(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp slt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test41: +; AVX2: vpminsd +} + +define void @test42(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sle <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test42: +; AVX2: vpminsd +} + +define void @test43(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sgt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test43: +; AVX2: vpmaxsd +} + +define void @test44(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sge <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test44: +; AVX2: vpmaxsd +} + +define void @test45(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ult <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test45: +; AVX2: vpminud +} + +define void @test46(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ule <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test46: +; AVX2: vpminud +} + +define void @test47(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ugt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test47: +; AVX2: vpmaxud +} + +define void @test48(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp uge <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.a, <8 x i32> %load.b + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test48: +; AVX2: vpmaxud +} + +define void @test49(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp slt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test49: +; SSE4: pmaxsb + +; AVX1: test49: +; AVX1: vpmaxsb + +; AVX2: test49: +; AVX2: vpmaxsb +} + +define void @test50(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sle <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test50: +; SSE4: pmaxsb + +; AVX1: test50: +; AVX1: vpmaxsb + +; AVX2: test50: +; AVX2: vpmaxsb +} + +define void @test51(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sgt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test51: +; SSE4: pminsb + +; AVX1: test51: +; AVX1: vpminsb + +; AVX2: test51: +; AVX2: vpminsb +} + +define void @test52(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp sge <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test52: +; SSE4: pminsb + +; AVX1: test52: +; AVX1: vpminsb + +; AVX2: test52: +; AVX2: vpminsb +} + +define void @test53(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ult <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test53: +; SSE2: pmaxub + +; AVX1: test53: +; AVX1: vpmaxub + +; AVX2: test53: +; AVX2: vpmaxub +} + +define void @test54(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ule <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test54: +; SSE2: pmaxub + +; AVX1: test54: +; AVX1: vpmaxub + +; AVX2: test54: +; AVX2: vpmaxub +} + +define void @test55(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp ugt <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test55: +; SSE2: pminub + +; AVX1: test55: +; AVX1: vpminub + +; AVX2: test55: +; AVX2: vpminub +} + +define void @test56(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <16 x i8>* + %ptr.b = bitcast i8* %gep.b to <16 x i8>* + %load.a = load <16 x i8>* %ptr.a, align 2 + %load.b = load <16 x i8>* %ptr.b, align 2 + %cmp = icmp uge <16 x i8> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i8> %load.b, <16 x i8> %load.a + store <16 x i8> %sel, <16 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test56: +; SSE2: pminub + +; AVX1: test56: +; AVX1: vpminub + +; AVX2: test56: +; AVX2: vpminub +} + +define void @test57(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp slt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test57: +; SSE2: pmaxsw + +; AVX1: test57: +; AVX1: vpmaxsw + +; AVX2: test57: +; AVX2: vpmaxsw +} + +define void @test58(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sle <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test58: +; SSE2: pmaxsw + +; AVX1: test58: +; AVX1: vpmaxsw + +; AVX2: test58: +; AVX2: vpmaxsw +} + +define void @test59(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sgt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test59: +; SSE2: pminsw + +; AVX1: test59: +; AVX1: vpminsw + +; AVX2: test59: +; AVX2: vpminsw +} + +define void @test60(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp sge <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE2: test60: +; SSE2: pminsw + +; AVX1: test60: +; AVX1: vpminsw + +; AVX2: test60: +; AVX2: vpminsw +} + +define void @test61(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ult <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test61: +; SSE4: pmaxuw + +; AVX1: test61: +; AVX1: vpmaxuw + +; AVX2: test61: +; AVX2: vpmaxuw +} + +define void @test62(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ule <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test62: +; SSE4: pmaxuw + +; AVX1: test62: +; AVX1: vpmaxuw + +; AVX2: test62: +; AVX2: vpmaxuw +} + +define void @test63(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp ugt <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test63: +; SSE4: pminuw + +; AVX1: test63: +; AVX1: vpminuw + +; AVX2: test63: +; AVX2: vpminuw +} + +define void @test64(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <8 x i16>* + %ptr.b = bitcast i16* %gep.b to <8 x i16>* + %load.a = load <8 x i16>* %ptr.a, align 2 + %load.b = load <8 x i16>* %ptr.b, align 2 + %cmp = icmp uge <8 x i16> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i16> %load.b, <8 x i16> %load.a + store <8 x i16> %sel, <8 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test64: +; SSE4: pminuw + +; AVX1: test64: +; AVX1: vpminuw + +; AVX2: test64: +; AVX2: vpminuw +} + +define void @test65(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp slt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test65: +; SSE4: pmaxsd + +; AVX1: test65: +; AVX1: vpmaxsd + +; AVX2: test65: +; AVX2: vpmaxsd +} + +define void @test66(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sle <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test66: +; SSE4: pmaxsd + +; AVX1: test66: +; AVX1: vpmaxsd + +; AVX2: test66: +; AVX2: vpmaxsd +} + +define void @test67(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sgt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test67: +; SSE4: pminsd + +; AVX1: test67: +; AVX1: vpminsd + +; AVX2: test67: +; AVX2: vpminsd +} + +define void @test68(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp sge <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test68: +; SSE4: pminsd + +; AVX1: test68: +; AVX1: vpminsd + +; AVX2: test68: +; AVX2: vpminsd +} + +define void @test69(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ult <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test69: +; SSE4: pmaxud + +; AVX1: test69: +; AVX1: vpmaxud + +; AVX2: test69: +; AVX2: vpmaxud +} + +define void @test70(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ule <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test70: +; SSE4: pmaxud + +; AVX1: test70: +; AVX1: vpmaxud + +; AVX2: test70: +; AVX2: vpmaxud +} + +define void @test71(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp ugt <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test71: +; SSE4: pminud + +; AVX1: test71: +; AVX1: vpminud + +; AVX2: test71: +; AVX2: vpminud +} + +define void @test72(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <4 x i32>* + %ptr.b = bitcast i32* %gep.b to <4 x i32>* + %load.a = load <4 x i32>* %ptr.a, align 2 + %load.b = load <4 x i32>* %ptr.b, align 2 + %cmp = icmp uge <4 x i32> %load.a, %load.b + %sel = select <4 x i1> %cmp, <4 x i32> %load.b, <4 x i32> %load.a + store <4 x i32> %sel, <4 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 4 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; SSE4: test72: +; SSE4: pminud + +; AVX1: test72: +; AVX1: vpminud + +; AVX2: test72: +; AVX2: vpminud +} + +define void @test73(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp slt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test73: +; AVX2: vpmaxsb +} + +define void @test74(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sle <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test74: +; AVX2: vpmaxsb +} + +define void @test75(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sgt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test75: +; AVX2: vpminsb +} + +define void @test76(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp sge <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test76: +; AVX2: vpminsb +} + +define void @test77(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ult <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test77: +; AVX2: vpmaxub +} + +define void @test78(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ule <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test78: +; AVX2: vpmaxub +} + +define void @test79(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp ugt <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test79: +; AVX2: vpminub +} + +define void @test80(i8* nocapture %a, i8* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i8* %a, i64 %index + %gep.b = getelementptr inbounds i8* %b, i64 %index + %ptr.a = bitcast i8* %gep.a to <32 x i8>* + %ptr.b = bitcast i8* %gep.b to <32 x i8>* + %load.a = load <32 x i8>* %ptr.a, align 2 + %load.b = load <32 x i8>* %ptr.b, align 2 + %cmp = icmp uge <32 x i8> %load.a, %load.b + %sel = select <32 x i1> %cmp, <32 x i8> %load.b, <32 x i8> %load.a + store <32 x i8> %sel, <32 x i8>* %ptr.a, align 2 + %index.next = add i64 %index, 32 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test80: +; AVX2: vpminub +} + +define void @test81(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp slt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test81: +; AVX2: vpmaxsw +} + +define void @test82(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sle <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test82: +; AVX2: vpmaxsw +} + +define void @test83(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sgt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test83: +; AVX2: vpminsw +} + +define void @test84(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp sge <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test84: +; AVX2: vpminsw +} + +define void @test85(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ult <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test85: +; AVX2: vpmaxuw +} + +define void @test86(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ule <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test86: +; AVX2: vpmaxuw +} + +define void @test87(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp ugt <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test87: +; AVX2: vpminuw +} + +define void @test88(i16* nocapture %a, i16* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i16* %a, i64 %index + %gep.b = getelementptr inbounds i16* %b, i64 %index + %ptr.a = bitcast i16* %gep.a to <16 x i16>* + %ptr.b = bitcast i16* %gep.b to <16 x i16>* + %load.a = load <16 x i16>* %ptr.a, align 2 + %load.b = load <16 x i16>* %ptr.b, align 2 + %cmp = icmp uge <16 x i16> %load.a, %load.b + %sel = select <16 x i1> %cmp, <16 x i16> %load.b, <16 x i16> %load.a + store <16 x i16> %sel, <16 x i16>* %ptr.a, align 2 + %index.next = add i64 %index, 16 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test88: +; AVX2: vpminuw +} + +define void @test89(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp slt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test89: +; AVX2: vpmaxsd +} + +define void @test90(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sle <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test90: +; AVX2: vpmaxsd +} + +define void @test91(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sgt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test91: +; AVX2: vpminsd +} + +define void @test92(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp sge <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test92: +; AVX2: vpminsd +} + +define void @test93(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ult <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test93: +; AVX2: vpmaxud +} + +define void @test94(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ule <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test94: +; AVX2: vpmaxud +} + +define void @test95(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp ugt <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test95: +; AVX2: vpminud +} + +define void @test96(i32* nocapture %a, i32* nocapture %b) nounwind { +vector.ph: + br label %vector.body + +vector.body: ; preds = %vector.body, %vector.ph + %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] + %gep.a = getelementptr inbounds i32* %a, i64 %index + %gep.b = getelementptr inbounds i32* %b, i64 %index + %ptr.a = bitcast i32* %gep.a to <8 x i32>* + %ptr.b = bitcast i32* %gep.b to <8 x i32>* + %load.a = load <8 x i32>* %ptr.a, align 2 + %load.b = load <8 x i32>* %ptr.b, align 2 + %cmp = icmp uge <8 x i32> %load.a, %load.b + %sel = select <8 x i1> %cmp, <8 x i32> %load.b, <8 x i32> %load.a + store <8 x i32> %sel, <8 x i32>* %ptr.a, align 2 + %index.next = add i64 %index, 8 + %loop = icmp eq i64 %index.next, 16384 + br i1 %loop, label %for.end, label %vector.body + +for.end: ; preds = %vector.body + ret void + +; AVX2: test96: +; AVX2: vpminud +} diff --git a/test/CodeGen/X86/vsplit-and.ll b/test/CodeGen/X86/vsplit-and.ll index ee98806c0f..3b7fdff84e 100644 --- a/test/CodeGen/X86/vsplit-and.ll +++ b/test/CodeGen/X86/vsplit-and.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux -mcpu=penryn | FileCheck %s define void @t0(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind readonly { ; CHECK: t0 diff --git a/test/CodeGen/X86/win_ftol2.ll b/test/CodeGen/X86/win_ftol2.ll index 596b4262e6..7f8ae07463 100644 --- a/test/CodeGen/X86/win_ftol2.ll +++ b/test/CodeGen/X86/win_ftol2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL +; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=generic | FileCheck %s -check-prefix=FTOL ; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=COMPILERRT ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=COMPILERRT diff --git a/test/CodeGen/X86/x86-64-dead-stack-adjust.ll b/test/CodeGen/X86/x86-64-dead-stack-adjust.ll index 902c9d5ae0..9c01f16f24 100644 --- a/test/CodeGen/X86/x86-64-dead-stack-adjust.ll +++ b/test/CodeGen/X86/x86-64-dead-stack-adjust.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -mcpu=nehalem | not grep rsp -; RUN: llc < %s -mcpu=nehalem | grep cvttsd2siq +; RUN: llc < %s -mcpu=nehalem | grep cvttsd2si target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-apple-darwin8" diff --git a/test/CodeGen/X86/x86-64-ptr-arg-simple.ll b/test/CodeGen/X86/x86-64-ptr-arg-simple.ll new file mode 100644 index 0000000000..6d46663989 --- /dev/null +++ b/test/CodeGen/X86/x86-64-ptr-arg-simple.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnux32 < %s | FileCheck -check-prefix=X32ABI %s + +; %in is kept in %esi for both ABIs. But the pointer will be passed in %edi +; for x32, not %rdi + +; CHECK: movl %esi, (%rdi) +; X32ABI: movl %esi, (%edi) + +define void @foo(i32* nocapture %out, i32 %in) nounwind { +entry: + store i32 %in, i32* %out, align 4 + ret void +} + +; CHECK: bar +; CHECK: movl (%rsi), %eax + +; Similarly here, but for loading +; X32ABI: bar +; X32ABI: movl (%esi), %eax + +define void @bar(i32* nocapture %pOut, i32* nocapture %pIn) nounwind { +entry: + %0 = load i32* %pIn, align 4 + store i32 %0, i32* %pOut, align 4 + ret void +} + diff --git a/test/CodeGen/X86/x86-64-sret-return.ll b/test/CodeGen/X86/x86-64-sret-return.ll index 7b5f189faa..bc8a543465 100644 --- a/test/CodeGen/X86/x86-64-sret-return.ll +++ b/test/CodeGen/X86/x86-64-sret-return.ll @@ -1,11 +1,16 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux-gnux32 < %s | FileCheck -check-prefix=X32ABI %s -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" -target triple = "x86_64-apple-darwin8" - %struct.foo = type { [4 x i64] } +%struct.foo = type { [4 x i64] } ; CHECK: bar: ; CHECK: movq %rdi, %rax + +; For the x32 ABI, pointers are 32-bit so 32-bit instructions will be used +; X32ABI: bar: +; X32ABI: movl %edi, %eax + define void @bar(%struct.foo* noalias sret %agg.result, %struct.foo* %d) nounwind { entry: %d_addr = alloca %struct.foo* ; <%struct.foo**> [#uses=2] @@ -57,6 +62,11 @@ return: ; preds = %entry ; CHECK: foo: ; CHECK: movq %rdi, %rax + +; For the x32 ABI, pointers are 32-bit so 32-bit instructions will be used +; X32ABI: foo: +; X32ABI: movl %edi, %eax + define void @foo({ i64 }* noalias nocapture sret %agg.result) nounwind { store { i64 } { i64 0 }, { i64 }* %agg.result ret void diff --git a/test/CodeGen/XCore/2010-04-07-DbgValueOtherTargets.ll b/test/CodeGen/XCore/2010-04-07-DbgValueOtherTargets.ll deleted file mode 100644 index 80cf3a6d67..0000000000 --- a/test/CodeGen/XCore/2010-04-07-DbgValueOtherTargets.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llc -O0 -march=xcore -asm-verbose < %s | FileCheck %s -; Check that DEBUG_VALUE comments come through on a variety of targets. - -define i32 @main() nounwind ssp { -entry: -; CHECK: DEBUG_VALUE - call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9 - ret i32 0, !dbg !10 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{metadata !5} -!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 0} -!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] -!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!9 = metadata !{i32 3, i32 11, metadata !8, null} -!10 = metadata !{i32 4, i32 2, metadata !8, null} - diff --git a/test/CodeGen/XCore/DbgValueOtherTargets.test b/test/CodeGen/XCore/DbgValueOtherTargets.test new file mode 100644 index 0000000000..93ab7e0f15 --- /dev/null +++ b/test/CodeGen/XCore/DbgValueOtherTargets.test @@ -0,0 +1 @@ +; RUN: llc -O0 -march=xcore -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll |